搭建自己的Pod库

前言

使用三方库时基本的语法是:

1
pod 'pod-Name'

之后通过以下命令导入此库:

1
pod install

pod会从官方索引库中查找并导入此三方库。有时我们不希望自己的库对外公开,如只在公司范围内使用,这时就可以在代码托管平台发布一个私有库,导入库时通过:source =>指定私有库的远程索引库地址即可。

本篇文章将记录下从私有库到公开库的完整发布流程~

1、远程索引仓库

GitHub->>New repository,创建新的索引仓库~

2、本地索引仓库

2.1.查看本地仓库

1
pod repo

/Users/Macmafia/.cocoapods的目录结构如下:

1
2
3
4
5
6
.
└── repos
└── master
├── CocoaPods-version.yml
├── README.md
└── Specs

2.2.本地索引仓库

创建本地索引仓库,并与远程仓库关联:

1
pod repo add davidlii https://github.com/davidli-/davidlii.git

2.3.确认

确认本地索引仓库是否创建成功:

1
pod repo

现在,/Users/Macmafia/.cocoapods目录中结构如下:

1
2
3
4
5
6
7
8
.
└── repos
├── davidlii
│   └── README.md
└── master
├── CocoaPods-version.yml
├── README.md
└── Specs

其中davidlii目录即为刚创建的本地仓库。

3、远程代码库

上面创建的是”索引”仓库,存放的是”.podspec”索引文件。这一步将要创建的是”代码”仓库,存放的是自制库的相关代码。步骤同#1章节,另取新名DaKit~

4、本地代码库

创建本地代码库:

1
2
cd 代码库的目录 (我的是/Documents/)
pod lib create DaKit

这一步会让你做一些选择,根据自己的情况在终端中输入即可,我的选择按顺序分别为:

1
2
3
4
5
6
1.iOS
2.ObjC
3.Yes
4.None
5.No
6.Da

选择完成后,开始生成本地代码库,之后会自动打开自制库的示例工程,其物理目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/Users/Macmafia/Documents/DaKit/
.
├── DaKit
│   ├── Assets
│   └── Classes
├── DaKit.podspec
├── Example
│   ├── DaKit
│   │   ├── Base.lproj
│   │   │   ├── LaunchScreen.storyboard
│   │   │   └── Main.storyboard
│   │   ├── DaAppDelegate.h
│   │   ├── DaAppDelegate.m
│   │   ├── DaKit-Info.plist
│   │   ├── DaKit-Prefix.pch
│   │   ├── DaViewController.h
│   │   ├── DaViewController.m
│   │   ├── Images.xcassets
│   │   │   └── AppIcon.appiconset
│   │   │   └── Contents.json
│   │   ├── en.lproj
│   │   │   └── InfoPlist.strings
│   │   └── main.m
│   ├── DaKit.xcodeproj
│   │   ├── project.pbxproj
│   │   ├── project.xcworkspace
│   │   │   └── contents.xcworkspacedata
│   │   └── xcshareddata
│   │   └── xcschemes
│   │   └── DaKit-Example.xcscheme
│   ├── DaKit.xcworkspace
│   │   ├── contents.xcworkspacedata
│   │   ├── xcshareddata
│   │   │   └── IDEWorkspaceChecks.plist
│   │   └── xcuserdata
│   │   └── Macmafia.xcuserdatad
│   │   └── UserInterfaceState.xcuserstate
│   ├── Podfile
│   ├── Podfile.lock
│   ├── Pods
│   │   ├── Headers
│   │   ├── Local\ Podspecs
│   │   │   └── DaKit.podspec.json
│   │   ├── Manifest.lock
│   │   ├── Pods.xcodeproj
│   │   │   ├── project.pbxproj
│   │   │   └── xcuserdata
│   │   │   └── Macmafia.xcuserdatad
│   │   │   └── xcschemes
│   │   │   ├── DaKit.xcscheme
│   │   │   ├── Pods-DaKit_Example.xcscheme
│   │   │   ├── Pods-DaKit_Tests.xcscheme
│   │   │   └── xcschememanagement.plist
│   │   └── Target\ Support\ Files
│   │   ├── DaKit
│   │   │   ├── DaKit-Info.plist
│   │   │   ├── DaKit-dummy.m
│   │   │   ├── DaKit-prefix.pch
│   │   │   ├── DaKit-umbrella.h
│   │   │   ├── DaKit.modulemap
│   │   │   └── DaKit.xcconfig
│   │   ├── Pods-DaKit_Example
│   │   │   ├── Pods-DaKit_Example-Info.plist
│   │   │   ├── Pods-DaKit_Example-acknowledgements.markdown
│   │   │   ├── Pods-DaKit_Example-acknowledgements.plist
│   │   │   ├── Pods-DaKit_Example-dummy.m
│   │   │   ├── Pods-DaKit_Example-frameworks.sh
│   │   │   ├── Pods-DaKit_Example-umbrella.h
│   │   │   ├── Pods-DaKit_Example.debug.xcconfig
│   │   │   ├── Pods-DaKit_Example.modulemap
│   │   │   └── Pods-DaKit_Example.release.xcconfig
│   │   └── Pods-DaKit_Tests
│   │   ├── Pods-DaKit_Tests-Info.plist
│   │   ├── Pods-DaKit_Tests-acknowledgements.markdown
│   │   ├── Pods-DaKit_Tests-acknowledgements.plist
│   │   ├── Pods-DaKit_Tests-dummy.m
│   │   ├── Pods-DaKit_Tests-umbrella.h
│   │   ├── Pods-DaKit_Tests.debug.xcconfig
│   │   ├── Pods-DaKit_Tests.modulemap
│   │   └── Pods-DaKit_Tests.release.xcconfig
│   └── Tests
│   ├── Tests-Info.plist
│   ├── Tests-Prefix.pch
│   ├── Tests.m
│   └── en.lproj
│   └── InfoPlist.strings
├── LICENSE
├── README.md
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj

5、添加库文件

将自己的库文件拖入/DaKit/DaKit/Classes目录中:

1
2
3
4
5
6
7
8
9
10
11
12
.
├── DaKit
│   ├── Assets
│   └── Classes
│   └── Runtime
│   ├── DaClassInfo.h
│   ├── DaClassInfo.m
│   ├── DaKakashi.h
│   └── DaSerialize.h
├── DaKit.podspec
├── Example
│   ├── DaKit

这里的Runtime即为我自己的库文件所在目录,下面是四个Da开头的库文件~

6、安装库文件

cd 到Example目录下,执行:

1
pod install

这一步会将刚才拖入到 Classes 目录中的文件导入到示例工程中;

导入后的库文件可在 DaKit.xcworkspace 的 Pods.xcodeproj 中查看。

7、修改.podspec文件

DaKit工程根目录下.podspec文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Pod::Spec.new do |s|
s.name = 'DaKit'
s.version = '0.1.1'
s.summary = 'davidlii\'s Kit for iOS developing~'

# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!

s.description = <<-DESC
Kit to simplify your developing process, I will continuously update this Kit.
DESC

s.homepage = 'https://github.com/davidli-/DaKit'
s.screenshots = 'https://davidlii.nos-eastchina1.126.net/pic_DaKit.png'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'davidlii' => 'macmafia@sina.cn' }
s.source = { :git => 'https://github.com/davidli-/DaKit.git', :tag => s.version.to_s }
s.social_media_url = 'https://davidlii.cn'

s.ios.deployment_target = '8.0'

s.source_files = 'DaKit/Classes/**/*'

# s.resource_bundles = {
# 'DaKit' => ['DaKit/Assets/*.png']
# }

# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end

根据需要,修改对应的选项,修改之后重新编译项目,测试是否能通过编译~

8、远程代码仓库

回到代码库根目录,提交代码到远程代码仓库,大致过程如下:

1
2
3
4
git add .
git commit -m “x”
git remote add origin https://github.com/davidli-/DaKit.git(远程代码库的地址)
git push origin master

设置标签:

1
2
git tag 版本号
git push —-tags (注意:一定要先将tag推送到远程仓库,否则后面验证仓库时无法通过验证)

CocoaPods 依赖于标签,标签的版本号须与.podspec文件中的版本号保持一致~

9、验证podspec文件

验证可分为两种:验证本地和远程仓库,都稍微费些时间。

9.1.只验证本地仓库

1
pod lib lint 仓库名.podspec

9.2.验证远程仓库

既验证本地仓库又验证远程仓库:

1
pod spec lint 仓库名.podspec --verbose --allow-warnings

如果验证通过,则会显示如下样式:

1
2
3
4
5
6
7
8
9
10
11
** BUILD SUCCEEDED **

Testing with `xcodebuild`.
-> DaKit (0.1.1)
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description

Analyzed 1 podspec.

DaKit.podspec passed validation.

10、推送索引文件

将本地索引文件推送到远程索引库:

1
pod repo push 本地索引库 索引文件名 --verbose --allow-warnings

我的为:pod repo push davidlii DaKit.podspec –verbose –allow-warnings

1
2
3
4
5
6
. . . 日志
Pushing the `davidlii' repo

$ /usr/bin/git -C /Users/Macmafia/.cocoapods/repos/davidlii push origin master
To https://github.com/davidli-/davidlii.git
6f4b19f..ebd5059 master -> master

看到这些即表示推送成功,此时查看本地索引库,其目录变成:

1
2
3
4
5
6
7
8
/Users/Macmafia/.cocoapods
.
└── repos
├── davidlii
│   └── DaKit
│   └── 0.1.1
└── master
└── Specs

davidlii 目录下多出了DaKit目录和刚提交的库文件标签0.1.1,即表示索引创建成功~

11、导入库私有库

到目前为止我们发布的还只是私有库,尚无法通过pod search命令从官方master索引库中查找的到~

此私有库可在自己的项目或公司范围内使用,只需在想要使用此库的工程中修改Podfile文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
########

use_frameworks!

# 指定自制库DaKit的远程索引库地址
# 方式1:source 'https://github.com/davidli-/davidlii.git'

target 'ASDF' do
# 方式2
pod 'DaKit', :source => 'https://github.com/davidli-/davidlii.git'
end

########

即使用:source =>指定私有库的远程索引库地址即可~

12、发布公开库

  • 注册pod trunk
1
pod trunk register 邮箱 ‘名称’ --description=‘xxx’ --verbose
  • 验证邮箱

前往注册时的邮箱点击链接即可完成验证~

  • 确认注册信息
1
pod trunk me

13、提交.podspec文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pod trunk push DaKit.podspec --allow-warnings

// 日志
Updating spec repo `master`
Validating podspec
-> DaKit (0.1.1)
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description

Updating spec repo `master`

--------------------------------------------------------------------------------
🎉 Congrats

🚀 DaKit (0.1.1) successfully published
📅 August 31st, 08:23
🌎 https://cocoapods.org/pods/DaKit
👍 Tell your friends!
--------------------------------------------------------------------------------

14、搜索自己的库

  • 查询trunk
1
2
3
4
5
6
7
8
pod trunk me
- Name: davidlii
- Email: macmafia@sina.cn
- Since: August 31st, 04:20
- Pods:
- DaKit
- Sessions:
- August 31st, 04:20 - January 6th, 2020 09:14. IP: 183.156.110.234

可以看到Pods:目录下顺利出现了自制的库 DaKit。

  • 查询pod
1
pod search DaKit

如果显示以下结果,则提交公开库成功:

1
2
3
4
5
6
-> DaKit (0.1.1)
davidlii's Kit for iOS developing~
pod 'DaKit', '~> 0.1.1'
- Homepage: https://github.com/davidli-/DaKit
- Source: https://github.com/davidli-/DaKit.git
- Versions: 0.1.1 [davidlii repo]

如果无法查到,则先更新索引库,再重新查找:

1
2
pod repo update
pod search DaKit

15、导入公开库

修改Podfile文件:

1
2
3
4
5
6
7
8
9
#######

use_frameworks!

target 'ASDF' do
# 使用公开库
pod 'DaKit'
end
#######

导入库文件:

1
pod install

16、使用公开库

1
2
3
4
5
6
7
8
9
10
11
// 实体类 ***********
@interface Card : NSObject
@property (nonatomic) int cardNumber; // 编号
@property (nonatomic) float money; // 余额
@end

#import "Card.h"

// 导入头文件
#import <DaKit/DaSerialize.h>
#import <DaKit/DaKakashi.h>
1
2
3
4
5
6
7
@implementation Card

// 使用宏
DaSerialize()
DaKakashi()

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 测试 ***********

#import "Card.h"
#import <DaKit/DaClassInfo.h>

- (void)example{
Card *card = [[Card alloc] init];
card.cardNumber = 100;
card.money = 50000000;

// 序列化
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:card];
Card *card2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];

// 复制
Card *card3 = [card2 copy];

// 获取类的信息
NSArray *ivars = [DaClassInfo ivarListWithClass:[Card class]];
NSArray *props = [DaClassInfo propertyListWithClass:[Card class]];
NSArray *meths = [DaClassInfo methodListWithClass:[Card class]];
}

后记

至此,私有库和公有库的创建与使用均已完成,过程中还有一些ruby源和网络等问题,折腾了好一会儿,每个人的情况可能都不尽相同,这里就不一一罗列了。库已提交,以后就可以快乐的更新啦~

欢迎使用与指正~


相关参考:

#©DaKit


搭建自己的Pod库
https://davidlii.cn/2019/08/31/podspec.html
作者
Davidli
发布于
2019年8月31日
许可协议