工作上的一个项目需要自己本地构建,所以稍微了解了一些。
什么是CocoaPods
- 为 iOS 程序提供依赖管理的工具,开始于 2011年8月12日,经过多年发展,现在已经成为iOS开发事实上的依赖管理标准工具。
- 只需要一个
Podfile
文件,就能通过命令pod install
完成以前复杂的工作:- 第三方开源库的源代码文件复制到项目中,或者设置成 git 的 submodule
- 这些开源库通常需要依赖系统的一些 framework,开发者需要手工地将这些 framework 分别增加到项目依赖中,比如一个网络库就需要增加以下 framework: CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics, zlib。
- 某些开源库,还需要手动设置
-licucore
或者-fno-objc-arc
等编译参数 - 需要关注依赖包的更新
CocoaPods的原理
- 依赖库会被放到一个名为Pods的项目里(看起来就是一个文件夹)然后主项目依赖于它。
- Pods项目最后会编译成一个名为
libPods.a
的文件,主项目里引用的就是它 - 对于资源文件,CocoaPods 提供了一个名为
Pods-resources.sh
的 bash 脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。 - CocoaPods 通过一个名为
Pods.xcconfig
的文件来在编译时设置所有的依赖和参数。
CocoaPods的安装和使用
Ruby环境
- ruby环境参考其他文章
- gem可能需要更新
gem update --system
安装CocoaPods
- 一般来讲,需要换国内镜像,比如淘宝的,或者
https://gems.ruby-china.com/
gem sources -l
可以查看现在的源gem sources --remove https://rubygems.org/
gem sources -a http://ruby.taobao.org/
- 注意:,很多网上的老文章,写的都是
https://gems.ruby-china.org/
,但是这个镜像地址已经改成了.com
!
gem install cocoapods
- 如果需要安装beta版本,就是
gem install cocoapods --pre
截止2018-10,发现pod的一个bug
1.6.0 beta2修复了一个问题,就是在
project.pbxproj
文件里,老pod(比如1.2,1.4版本)会在pod install
的时候生成一些代码,比如下面这样:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1916162FB2E14A1C2A5D2BD828 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SHInvest/Pods-SHInvest-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};然后把这些改动在Git提交了,那么其他人在
pod install
的时候就会遇到报错——新版本的pod会删掉这段代码。- 进一步谈一下文件
project.pbxproj
的Git管理问题,这里有一些改动是需要提交的,但是pod install
带进来的改动,是没有必要提交的。所以一般的处理是使用Git命令去忽略pod install带来的改动,只提交项目里需要跟踪的改动。
CocoaPods初始化
pod setup
- 所有的项目的 Podspec 文件都托管在一个github的项目上。第一次执行setup时,CocoaPods会将这些podspec索引文件更新到本地的
~/.cocoapods/
目录下,这个索引文件比较大,有 300多M 左右,在执行一次pod install
之后这个文件目录还会增加到700多M。所以第一次很慢是正常的,不要慌,建议提前预留时间,比如下班前执行,明天来收获。 - 整个过程比较慢,可以查看目录下(
~/.cocoapods/
)文件的大小du -sh *
,以此检查进度 下载索引可以换一个镜像:
1
2
3pod repo remove master
pod repo add master https://gitcafe.com/akuandev/Specs.git
pod repo update
CocoaPods在项目中
- 在项目根目录下建立Podfile,写入你需要引用的各种库,比如
pod 'WechatOpenSDK'
,还可以添加版本设定,比如pod "AFNetworking", "~> 2.0"
- 一般来说,类库的原作者会告诉你导入该类库应该如何写Podfile
- Podfile里不仅可以罗列,还可以写入各种逻辑,比如私有库的地址配置,比如管理开发/生产模式下的库的引用、版本控制等
- 首次安装依赖:
pod install
; - 默认会增加一个文件夹
Pods
来存放安装的依赖包,当然也可以在Podfile里设置,用别的文件夹存放一些私有库之类的。 - 之后,打开工程文件应该使用CocoaPods生成的
.xcworkspace
而不是项目里原先的.xcodeproj
文件。
CocoaPods安装依赖
- 可以直接通过命令来搜索库,
pod search <关键字>
Podfile.lock
用于锁定当前各种依赖库的版本。首次install之后生成,之后install都会按照这个文件锁定的版本来- 更改了
Podfile
之后,在有lock文件存在的情况下,应该通过pod update
命令来更新依赖包
私有pods
CocoaPods还支持管理私有的pod,比如公司内部的pod,或者把项目中一些模块写成pod的形式来引入。特别在一个app包含多条业务线的时候,就可以这么架构,让不同的业务线成为不同的pod,主体App和业务线的独立开发将会更加容易。
用户的spec资源配置信息和它们的更新
本地的spec资源配置
- 之前提过,在安装CocoaPods后,首次使用需要setup,这其实是去生成了一个本地的spec资源配置信息,本质就是官方管理所有pod库的一个资源库的拷贝。
- 文件夹
.cocoapods
一般在用户的目录下,比如/Users/<user>/.cocoapods/repos/master/Specs/<lib name>
这样子的,里面分版本包含多个文件夹,文件夹里是json文件,包含了那个库的一些信息,比如作者、许可协议、版本、资源地址等等 - 命令
pod install
其实就是根据pod库名在上面的文件夹里找对应的库,如果指定了版本就找到指定版本的.podspec,否则就找最高版本的.podspec,然后根据文件里的配置里的资源地址去下载。 - 如果本地的
.cocoapods
文件夹里找不到相应的配置文件,那么库就无法安装。比如某个库安装的是最新的,不通过update的话就找不到那个版本。
本地的spec的更新
- 现在
pod update
其实就会默认执行一遍pod repo update
——也就是说这个命令先更新了一遍索引才去下载新的。 pod repo update
会更新整个.cocoapods
文件夹下的所有库,有时候可能不太快。- 可以单独更新某个库
pod repo update /Users/<user>/.cocoapods/repos/master/Specs/<lib name>
,这个命令在你需要单独更新某个私有库的时候就很有用了。 - 甚至可以手动增加配置文件,去那个库的git上找到相应的文件然后手动增加,比如
/Users/<user>/.cocoapods/repos/master/Specs/<lib name>/3.2.0/<lib name>.spec
避免长时间的更新
- 如上所述,如果在Podfile里没有指定pods的版本号,那么每当执行
pod update
的时候,都会更新索引,然后尝试拉取类库的最新版本,这就很麻烦了 - 如果没有指定好pods的版本号,但是又不希望每次都更新到最新,那么在修改了部分pods配置后,更新pods的最好方法是
pod update --no-repo-update
,这样就只根据本地索引跟新,不会去拉远程spec
把自己的类库用Cocoapods管理
生成podspec文件:pod spec create <your_pod_spec_name>
,执行后生成名为your_pod_spec_name.podspec
的文件。