前言
上一篇介绍了基本的一些参数以及简单介绍模拟了下Cocoapods的组合结构,通过workSpace管理了xcodeproject简单了解了多个工程如何调用。这里我们详细介绍下Cocoapods和Xcode里面的环境参数都是些什么意思。
Cocoapods
它本身就是一个第三方依赖管理工具。支持传递依赖,例如A依赖B,B又依赖C,当我们在工程中指定依赖A的时候,它会帮我们自动下载C,并在编译构建时链接C。
这里主要介绍iOS工程中的一种库,static library,framework可以顺便提一下。当我们新建Target是static library的时候,我们一般使用它编译出来的libxxx.a文件以及对应的头文件,在写应用的时候,把文件拖进项目,后面的一些链接路径搜索一般都是自动的,只要你设置了copy选项。设置Library Search Path搜索静态库路径,设置Header Search Path搜索头文件。
Static Library
cocoapods管理前
└── SDKDemo1
├── SDKDemo1
└── SDKDemo1.xcodeproj
cocoapods管理后
.
└── SDKDemo1
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Headers
│ ├── Local\ Podspecs
│ ├── Manifest.lock
│ ├── Masonry
│ ├── Pods.xcodeproj
│ └── Target\ Support\ Files
├── SDKDemo1
├── SDKDemo1.xcodeproj
└── SDKDemo1.xcworkspace
└── contents.xcworkspacedata
- 首先可以看到xcworkspace,一般安装完之后也会提示用户用xcworkspace打开,不能在用之前的xcodeproj打开了,xcworkspace里面有一个contents文件,这里没什么东西,就是写了管理那几个project而已,这里很明显,管理了原工程SDKDemo1和Pods里面的Pods.xcodeproj的两个工程。
- Podfile 依赖描述配置文件
- Podfile.lock 当前安装的依赖库版本
假设我们在 Podfile 中写上:pod 'Masonry'
,那么默认是安装 Masonry 的最新代码。这就导致用户 A 可能装的是 1.0 版本,而用户 B 再安装就变成了 2.0 版本。即使我们在Podfile
中指定了库的具体版本,那也不能保证不出问题。因为一个第三方库还有可能依赖其他的第三方库,而且不保证它的依赖关系是具体到版本号的
。
因此 Podfile.lock 存在的意义是将某一次 pod install 时使用的各个库的版本,以及这个库依赖的其他第三方库的版本记录下来,以供别人使用。这样一来,pod install 的流程其实是:
判断 Podfile.lock 是否存在,如果不存在,按照 Podfile 中指定的版本安装
如果 Podfile.lock 存在,检查 Podfile 中每一个 Pod 在 Podfile.lock 中是否存在
如果存在, 则忽略 Podfile 中的配置,使用 Podfile.lock 中的配置(实际上就是什么都不做)
如果不存在,则使用 Podfile 中的配置,并写入 Podfile.lock 中
而另一个常用命令 pod update
并不是一个日常更新命令。它的原理是忽略 Podfile.lock
文件,完全使用 Podfile 中的配置,并且更新Podfile.lock
。一旦决定使用 pod update
,就必须所有团队成员一起更新。因此在使用 update 前请务必了解其背后发生的事情和对团队造成的影响,并且确保有必要这么做。
- Pods目录
Pods.xcodeproj
Pods工程,所有第三方库由Pods工程构建,每个第三方库对应里面的一个Target,并且这个工程还有一个Pods-xxx的一个Target,这个是用来管理的总Target- 比如Masonry会对应每个Target,都会在Pods目录下有个对应的目录
- Headers 在Headers下有两个目录,Private和Public,第3方库的私有头文件会在Private目录下有对应的头文件,不过是1个软链接,链接到第3方库的头文件 第3方库的Pubic头文件会在Public目录下有对应的头文件,也是软链接
Manifest.lock
manifest文件 描述对第三方的依赖Target Support Files 支撑target的文件
Target\ Support\ Files ├── Masonry │ ├── Masonry-dummy.m │ ├── Masonry-prefix.pch │ └── Masonry.xcconfig └── Pods-SDKDemo1 ├── Pods-SDKDemo1-acknowledgements.markdown ├── Pods-SDKDemo1-acknowledgements.plist ├── Pods-SDKDemo1-dummy.m ├── Pods-SDKDemo1.debug.xcconfig └── Pods-SDKDemo1.release.xcconfig
在Target Support Files目录下每1个第3方库都会有1个对应的文件夹,比如Masonry,该目录下有一个空实现文件dummy
,也有预定义头文件用来优化头文件编译速度pch
,还会有1个xcconfig
文件,该文件会在工程配置中使用,主要存放头文件搜索目录,链接的Flag(比如链接哪些库)
在Target Support Files
目录下还会有1个Pods-XXX
的文件夹,该文件夹存放了第3方库声明文档markdown文档和plist文件,还有1个dummy
的空实现文件,还有debug和release各自对应的xcconfig配置文件,如果是framework另外还有2个脚本文件,Pods-XXX-frameworks.sh脚本用于实现framework库的链接,当依赖的第3方库是framework形式才会用到该脚本,另外1个脚本文件: Pods-XXX-resources.sh用于编译storyboard类的资源文件或者拷贝*.xcassets之类的资源文件
工程结构的变化
当我们用了Cocoapods的时候,会生成xcworkspace用来管理project,这时候我们不能在启动project,因为工程文件配置已经发生了变化。
Pods工程
首先我们来看Cocoapods为我们创建的Project
可以看到Pods Project下面我们只引入了Masonry,但是还有一个Pods-xxx的Target,这个等下再看,这里的每个Target就是静态库文件。根据上面的目录介绍,每个第三方库都是静态库Target,而且第三方库都会有一个配置文件xcconfig文件,例如我们的Masonry,会有一个Masonry.xcconfig
,还有个总的Target提供了Pods-SDKDemo1.debug.xcconfig
和Pods-SDKDemo1.release.xcconfig
,会在Project下面根据不同环境配置不同的config文件。
看一下Masonry下面的config文件,由于每个三方库的config文件没有被引入工程,我们点开show in finder查看,还是在Target Supporting Files里面
这个是最新的Cocoapods做的
CONFIGURATION_BUILD_DIR = ${
PODS_CONFIGURATION_BUILD_DIR}/Masonry
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private"