使用 CocoaPods 管理 iOS 依赖库已经不是什么新鲜事了,我最近刚开源了一个网络库,为了方便集成使用,因此决定支持下 CocoaPods,期间也遇到了几个问题,分享给大家。
打个广告,我维护了几个 Pods 库,欢迎使用:
- JSONUtil JSON 转 model 工具
- SCNetworkKit iOS/macOS 网络库
- SCHTTPServer macOS 内嵌 HTTPS 服务器
- SCHTTPClient macOS libcurl 客户端
pod lib
创建 CocoaPods 库主要使用 pod lib 命令, 先看下该命令支持哪些命令参数吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜ ~ pod lib --help
Usage:
$ pod lib COMMAND
Develop pods
Commands:
+ create Creates a new Pod
+ lint Validates a Pod
Options:
--silent Show nothing
--verbose Show more debugging information
--no-ansi Show output without ANSI codes
--help Show help banner of specified command
支持两个命令参数,一个是创建,一个是验证。
创建 pod 库
创建 Pods 库非常简单,只需要使用 lib 命令即可完成,详细过程如下:
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
➜ demoWorkspace pod lib create TestPod
Cloning `https://github.com/CocoaPods/pod-template.git` into `TestPod`.
Configuring TestPod template.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
If this is your first time we recommend running through with the guide:
- https://guides.cocoapods.org/making/using-pod-lib-create.html
( hold cmd and double click links to open in a browser. )
What platform do you want to use?? [ iOS / macOS ]
> iOS
What language do you want to use?? [ Swift / ObjC ]
> Objc
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> No
What is your class prefix?
> MR
Running pod install on your new library.
Analyzing dependencies
Fetching podspec for `TestPod` from `../`
Downloading dependencies
Installing TestPod (0.1.0)
Generating Pods project
Integrating client project
[!] Please close any current Xcode sessions and use `TestPod.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
Ace! you're ready to go!
We will start you off by opening your project in Xcode
open 'TestPod/Example/TestPod.xcworkspace'
To learn more about the template see `https://github.com/CocoaPods/pod-template.git`.
To learn more about creating a new pod, see `https://guides.cocoapods.org/making/making-a-cocoapod`.
➜ demoWorkspace
按照提示填写库支持的平台和使用的语言,以及是否需要测试框架,类前缀等;选择 iOS 和 macOS 是有些区别的,如果选择 macOS 平台,那么下一步就不会提示使用哪种语言生成 demo,而是强制使用 Swift 语言!
按照上面的步骤操作无误时,会自动打开 TestPod 工程,workspace 里还包含了 Pods 工程,用来管理demo对于库的依赖,其目录结构如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
├── Example
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
│ ├── TestPod
│ ├── TestPod.xcodeproj
│ ├── TestPod.xcworkspace
│ └── Tests
├── LICENSE
├── README.md
├── TestPod
│ ├── Assets
│ └── Classes
├── TestPod.podspec
└── _Pods.xcodeproj -> Example/Pods/Pods.xcodeproj
目录含义如下:
- Example : 用来编写 demo,编写测试用例等,当别人使用 pod try 的时候,就会把你这个 demo 下载到一个临时目录里,如果不提供 demo,别人就无法使用 pod try 尝试你的库!
- LICENSE : 自动生成的是 MIT,后续可以修改
- README.md : 可以按照 markdown 格式编写一个概况,放到 github 上就会自动渲染
- TestPod : pod 库默认文件夹,可以在 .podspec 文件里修改
- TestPod.podspec : pod 库的细则文件,该文件非常重要,详细见下面说明
完善 .podspec 文件
TestPod.podspec 里面有好多模板内容,接下来我们来根据实际情况去完善下,这个文件支持的配置项非常多,你必要每个都修改,必要的改下就好了,至于哪些是必要的,无需记忆,后面有命令去验证,验证不过的修改下就好了:
- s.name : 默认是创建库时输入的名字,也是使用这个库时 Podfile 里填写的名字
- s.version : 库的版本,每次发布新版本时修改下,刚创建的是 0.1.0
- s.summary : 对库的一个简单描述,不写的话等会验证的时候会有警告;搜索这个库的时候会显示出来,所以最好写下
- s.description : 对库的一个详细描述,文字个数要比 summary 写得要多,否则也有警告;注意要写在两个 DESC 之间,可随意换行
- s.homepage : 如果这个库有主页的话,可以填上,搜索这个库的时候也会显示出来的;
- s.license : 默认生成了 MIT,可以根据需要进行修改
- s.author : 作者信息,默认根据 git 账户信息填写
- s.platform : 根据实际情况写 iOS 或者 OS X;
- s.source : 源码管理方式,常用的是git方式: { :git => ‘https://github.com/tonymillion/Reachability.git’, :tag => ‘v3.1.0’ }
- :git => :tag, :branch, :commit, :submodules
- :svn => :folder, :tag, :revision
- :hg => :revision
- :http => :flatten, :type, :sha256, :sha1, :headers
- s.source_files : 库文件所在目录,可以递归
- s.framework : 依赖的系统库
- s.library : 依赖的系统库
- s.requires_arc : 是否必须是 arc;
- s.dependency : 你这个库依赖了哪些其他 pods 库;
第一次可能写不好,所以最好是找个已经发布的 pod 库,看下是怎么写的,然后看着改。可以使用 pod spec cat xx
命令,具体参考 : pod spec 命令
注: 提到的 .podspec 文件,均指 TestPod.podspec 文件,TestPod 为库的名称。
验证 .podspec
完善好了 podspec 文件,并且代码也准备好后,就可以验证下了,如果是第一次搞,可能需要多次修改验证才能通过;验证这块有 3 点需要说下:
1、先本地验证而不是从指定的 source 验证;因为从指定的 source 下载验证比较麻烦,需要先提交,然后再拉取,如果出错了,就要再提交,基于 git + tag 管理源码的话,还得重新打 tag
2、验证出错了,不知道错在哪里,无从下手时,加上 --verbose --no-clean 可以查看整个过程,帮助我们快速找到问题
3、远程验证会受到缓存的影响,如果修改了代码,确定没问题了,但还是验证不通过,有可能是缓存搞的鬼,可以通过日志去排查,避免缓存干扰;
这里提到的 source 就是在 .podspec 文件所指定的,下面具体看下验证过程吧。
本地验证
我之所以叫本地验证,是因为验证的是放在本地的 pod 库,没有从指定的 source 下载代码,所以本地验证前也不用把代码传到 source 指定处。
1
2
pod cache clean --all
pod lib lint
我当时遇到的错误:
1
2
3
4
5
6
-> SCNetworkKit (1.0.0)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- NOTE | xcodebuild: Headers/Public/SCNetworkKit/SCNetworkKit.h:11:9: fatal error: 'NSDictionary+SCAddtions.h' file not found
- NOTE | xcodebuild: clang: error: linker command failed with exit code 1 (use -v to see invocation)
- NOTE | [iOS] xcodebuild: fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /var/folders/2z/l7ftfgd54lv0_nvq7pnr_zbw0000gn/T/CocoaPods/Lint/DerivedData/App/Build/Intermediates/App.build/Release-iphonesimulator/App.build/Objects-normal/i386/App (No such file or directory)
- NOTE | [iOS] xcodebuild: error: cannot parse the debug map for "/var/folders/2z/l7ftfgd54lv0_nvq7pnr_zbw0000gn/T/CocoaPods/Lint/DerivedData/App/Build/Products/Release-iphonesimulator/App.app/App": No such file or directory
这个原因是我最初路径我写错了,写成了 s.source_files = "SCNetworkKit/*.{h,m}"
,没有递归查找子文件夹里的类,所以说这个类别文件找不到!我是通过加上 --verbose
之后,查看执行过程发现的,验证的时候会下载文件,然后 copy 到别的目录去编译,我发现没有下载子文件里的文件!
1
2
3
4
5
6
-> Installing SCNetworkKit (1.0.0)
> Copying SCNetworkKit from
`/Users/crown/Library/Caches/CocoaPods/Pods/External/SCNetworkKit/d91c7ff7dcd08eaf54117a932c0d41d7-b0517`
to
`../../../../private/var/folders/2z/l7ftfgd54lv0_nvq7pnr_zbw0000gn/T/CocoaPods/Lint/Pods/SCNetworkKit`
- Running pre install hooks
远程验证
远程验证是相对本地验证而言的,验证时会从指定的 source 下载代码,因此需要把代码先提交到远程。
在本地验证没有问题后,pod 库是能在本地用的,放到自己的版本控制里,当做私有库去使用也是可以的,但是作为一个开源库就需要发布出去了,发布前最好做个远程验证,虽然发布时还会验证,但还是建议单独走下验证。
1
2
pod cache clean --all
pod spec lint --allow-warnings
如果本地验证无误的话,到这一步反而出错了?一般都是 source 的问题,只要耐心看打印的日志,一般都能快速解决的。常见问题比如将代码 push 到远程了,但是却忘记 打 tag,或者打的 tag 跟 .podspec 文件里指定的不一致,都会导致远程验证时不能下载代码而报错!
我的 pod 库都是放到 github 的,版本都是采用 tag 管理,因此 .podspec 文件可以这么写:
1
2
s.version = "1.0.0"
s.source = { :git => "https://github.com/debugly/SCHTTPClient.git", :tag => s.version.to_s }
这样后续只需要修改 version 的值就可以了,然后远程验证时就会拉取 version 对应的 tag 标签。
验证通过打印如下信息:
1
2
3
4
5
6
7
** BUILD SUCCEEDED **
-> SCNetworkKit (1.0.0)
Analyzed 1 podspec.
SCNetworkKit.podspec passed validation.
创建账户
发布之前需要创建一个 CocoaPods 的账户,如果你有多个电脑,那么你可以注册多次,以邮箱地址为唯一标识,一个邮箱地址可以在多台电脑上注册!
pod trunk register youar@email.com 'nickName’
通过这个命令注册后,你的邮箱很快就会收到 CocoaPods 发来的验证链接,点击即可激活,名称无法修改哦!激活之后,我们返回到终端继续往下操作即可,使用 pod trunk me
查看个人信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
~ pod trunk me
- Name: Matt Reach
- Email: qianlongxu@gmail.com
- Since: July 20th, 2017 02:05
- Pods:
- SCNetworkKit
- TestSCFPods
- SCJSONUtil
- SCHTTPServer
- SCHTTPClient
- Sessions:
- July 20th, 2017 02:05 - November 26th, 2017 00:36. IP:
125.35.217.43
- July 20th, 2017 07:21 - November 25th, 2017 08:19. IP:
117.10.28.87
- September 9th, 2017 19:32 - March 7th, 2018 23:46. IP:
125.35.217.43
- April 18th, 2018 07:02 - December 15th, 2018 09:04. IP:
221.198.236.178
- November 26th, 2018 23:00 - December 25th, 05:11. IP:
61.240.25.170
发布/更新 podspec
将刚才已经验证通过的 podspec 文件推送到 cocoapods 的仓库里,这样别人就能通过 pods 搜索到你的库了。
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
pod trunk push SCNetworkKit.podspec
Updating spec repo `master`
CocoaPods 1.3.0.beta.2 is available.
To update use: `sudo gem install cocoapods --pre`
[!] This is a test version we'd love you to try.
For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.3.0.beta.2
Validating podspec
-> SCNetworkKit (1.0.0)
Updating spec repo `master`
CocoaPods 1.3.0.beta.2 is available.
To update use: `sudo gem install cocoapods --pre`
[!] This is a test version we'd love you to try.
For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.3.0.beta.2
--------------------------------------------------------------------------------
🎉 Congrats
🚀 SCNetworkKit (1.0.0) successfully published
📅 July 20th, 02:58
🌎 https://cocoapods.org/pods/SCNetworkKit
👍 Tell your friends!
--------------------------------------------------------------------------------
Congrats 表明已经发布成功了!!
更新的步骤除了创建用户外没啥不一样的,步骤如下:
1、修改好代码,demo正常跑起来 2、本地验证 3、推送代码 4、打tag 5、远程验证 6、推送 podspec 文件
🔍搜索
是不是很高兴呢,Pods 库创建好了,我们试着搜下吧:
pod search SCNetworkKit
结果是:
1
[!] Unable to find a pod with name, author, summary, or description matching `SCNetworkKit`
好郁闷呢,明明已经成功发布了,为何就是搜索不到呢?这是因为再次之前我搜过别的库,CocoaPods 做了缓存了,因此我们找到他的搜索索引缓存,将它删除即可:
rm -rf ~/Library/Caches/CocoaPods
再次搜索,会重新建立索引,这个过程大概需要片刻,耐心等待即可:
1
2
3
4
5
6
7
8
9
10
11
pod search SCNetworkKit
Creating search index for spec repo 'macdownapp'.. Done!
Creating search index for spec repo 'master'.. Done!
-> SCNetworkKit (1.0.0)
SCNetworkKit is a simple but powerful iOS network framework.
pod 'SCNetworkKit', '~> 1.0.0'
- Homepage: http://debugly.cn/SCNetworkKit/
- Source: https://github.com/debugly/SCNetworkKit.git
- Versions: 1.0.0 [master repo]
(END)