3.CocoaPods的原理
2016-01-28 11:17
330 查看
前言
本文为通识性的文章,并且会不断更新,如果有什么地方不懂的或者有需要补充的以及不太正确之处可以留言,我会补上的,谢谢各位!~CocoaPods是将所有的依赖库都放到另一个名为Pods的项目中,然后让主项目依赖Pods项目。这样,源码管理工作都从主项目移到了Pods项目中。
Pods项目最终会编译成一个名为
lisPods.a的文件,主项目只需要依赖这个.a文件即可。
对于资源文件,CocoaPods提供了一个名为
Pods-resources.sh的bash脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。
CocoaPods通过一个名为
Pods.xconfig的文件来编译时设置所有的依赖和参数。
核心组件
CocoaPods是用ruby写的,并由若干个ruby包(gems)构成。在解析整合的过程中,最终要的几个gems分别是:CocoaPods/CocoaPods、CocoaPods/Core、CocoaPods/Xcodeproj。(CocoaPods是一个依赖管理工具 —— 利用依赖管理进行构建的)CocoaPods/CocoaPod
这是一个面向用户的组件,每当执行一个pod命令时,这个组件都将被激活。该组件包括了所有使用CocoaPods涉及到的功能,并且还能通过调用左右其他的gems来执行任务。CocoaPods/Core
Core组件提供支持与CocoaPods相关文件的处理,文件主要是Podfile和podspecs。podfile
这是一个文件,用于定义项目中所需要使用的第三方库。该文件支持高度定制,你可以根据个人喜好对其作出定制。这里不展开叙述,若想了解更多,可以查看Podfile指南。Podspec
.podspec也是一个文件,该文件描述了一个库是怎样被添加到工程中的。它支持的功能有:列出源文件、framework、编译选项和某个库所需要的依赖等。
CocosPods/Xcodeproj
这个gem组件负责所有工程文件的整合。它能够对创建修改xcodeproj和
.xworkspace文件。它也可以作为一个单独的gem包使用。如果你想要写一个脚本来方便的修改工程文件,那么可以使用这个gem。
运行pod install
命令
当在运行pod install命令时,会引发很多操作。如果想要深入了解这个命令执行的详细内容,可以运行
pod install --verbose。当运行该命令后,会看到类似以下的内容。
$ pod install --verbose Analyzing dependencies 分析依赖 Updating spec repositories 更新spce仓库 Updating spec repo `master` 更新‘master’分支 $ /usr/bin/git pull Already up-to-date. Finding Podfile changes - AFNetworking - HockeySDK Resolving dependencies of `Podfile` Resolving dependencies for target `Pods' (iOS 6.0) - AFNetworking (= 1.2.1) - SDWebImage (= 3.2) - SDWebImage/Core Comparing resolved specification to the sandbox manifest - AFNetworking - HockeySDK Downloading dependencies -> Using AFNetworking (1.2.1) -> Using HockeySDK (3.0.0) - Running pre install hooks - HockeySDK Generating Pods project - Creating Pods project - Adding source files to Pods project - Adding frameworks to Pods project - Adding libraries to Pods project - Adding resources to Pods project - Linking headers - Installing libraries - Installing target `Pods-AFNetworking` iOS 6.0 - Adding Build files - Adding resource bundles to Pods project - Generating public xcconfig file at `Pods/Pods-AFNetworking.xcconfig` - Generating private xcconfig file at `Pods/Pods-AFNetworking-Private.xcconfig` - Generating prefix header at `Pods/Pods-AFNetworking-prefix.pch` - Generating dummy source file at `Pods/Pods-AFNetworking-dummy.m` - Installing target `Pods-HockeySDK` iOS 6.0 - Adding Build files - Adding resource bundles to Pods project - Generating public xcconfig file at `Pods/Pods-HockeySDK.xcconfig` - Generating private xcconfig file at `Pods/Pods-HockeySDK-Private.xcconfig` - Generating prefix header at `Pods/Pods-HockeySDK-prefix.pch` - Generating dummy source file at `Pods/Pods-HockeySDK-dummy.m` - Installing target `Pods` iOS 6.0 - Generating xcconfig file at `Pods/Pods.xcconfig` - Generating target environment header at `Pods/Pods-environment.h` - Generating copy resources script at `Pods/Pods-resources.sh` - Generating acknowledgements at `Pods/Pods-acknowledgements.plist` - Generating acknowledgements at `Pods/Pods-acknowledgements.markdown` - Generating dummy source file at `Pods/Pods-dummy.m` - Running post install hooks - Writing Xcode project file to `Pods/Pods.xcodeproj` - Writing Lockfile in `Podfile.lock` - Writing Manifest in `Pods/Manifest.lock` Integrating client project
可以看到,整个过程执行了很多的操作。把这些操作分解开,可以发现,其实这些操作很简单,以下逐步来分析一下。
1. 读取podfile
文件
你是否觉得podfile的语法格式很奇怪,事实上 ,
podfile中的语言是用ruby写的。相较而言,这要比现有的其他格式更加简单一些。
在安装期间,第一步是要弄清楚显式或隐式的声明了哪些第三方库。在加载podspec的过程中,CocoaPods就建立了包括版本信息在内的所有第三方库的列表。
podspec被存储在本地路径
~/.cocospods中。
1.1. 版本控制和冲突
CocosPods使用语义版本控制,命名约定来解决对版本的依赖。由于冲突解决系统建立在非重大变更的补丁版本之间,这样就会让依赖关系变得相对容易一些。比如,两个不同的pods依赖某个pod库的两个版本,假设一个依赖于
2.3.1,一个依赖于
2.3.3,此时冲突解决系统可以使用最新的版本
2.3.3,因为这个可以向后与
2.3.1兼容。
然而,这样的解决方式并不能解决所有问题,总会有一些冲突需要手动解决。如果一个库依赖
1.2.5,另外一个库依赖
2.3.1,那么只用最终用户通过明确指定使用某个版本来解决冲突。
在做项目的过程中,会遇到这样的情况,有些项目的源码由于年代稍微有些久远或者其他原因没有使用pod进行管理依赖库,而是把需要引入第三方库的源码
2. 加载源文件
CocoaPods执行的下一步就是加载源码。每个.podspec文件都包含一个源代码的索引,这些索引一般会包裹一个
git地址或者
git tag。它是以
commit SHAs的方式存储在
~/Library/Caches/CocoaPods中的。这个路径中文件的创建由
Core gem负责。
CocoaPods将依照
podfile、
.podspec和缓存文件的信息将源文件下载到Pods目录中。
3. 生成 Pods.xcodeproj
在每次执行pod install时,如果检测到了改动,CocosPods会利用
xcodeproj的gem组件对
Pods.xcodeproj进行更新。如果该文件不存在,那么就会用默认配置进行生成。否则,将会把以后的配置项加载到内存中。
4. 安装第三方库
当CocosPods往工程中添加一个第三方库时,不仅仅是添加代码这么简单,还会添加很多的内容。由于每个第三方库有不同的target,因此对于每个库都会有几个文件需要添加,每个target都需要一个包含编译选项的
.xcconfig文件
一个同时包含编译设置和CocoaPods默认配置的私有
.xcconfig文件
一个编译必须的
prefix.pch文件
另一个编译必须的文件
dummy.m
一旦没有pod的target完成了上面的内容,整个
pods的 target 会被创建。这时,在增加了另外几个文件的同时,还会增加另外几个文件。如果源码中包含有资源bundle,将这个bundle添加到程序target的指令将被添加早
Pods-Resoutces.sh文件中。还有个名为
Pods-environment.h的文件,文件中包含了一些宏定义,这些宏可以用来检查某个组件是否来自于pod。最后,将生成的两个认可文件,
plist、
markdown这两个文件用于给最终用户差远相关许可信息。
5. 写入至磁盘
知道现在,许多工作都是在内存中进行的。为了让这些成果能够被重复利用,我们需要将所有的结果保存在一个文件中。因此,会有Pods.xcodeproj,另外两个非常重要的文件是
Podfile.lock和
Manifest.lock.
5.1 Podfile.lock
这是CocoaPods创建的最重要的文件之一。它记录了需要被安装的pod的每个已安装的版本。如果你想知道已安装的pod是哪个版本,可以查看这个文件。在很多资料中,都会将podfile.lock放入版本控制中,这样可以有助于整个团队工程依赖的一致性,然后,在我的团队开发中,这个文件更多的是放入
.ignore文件中的,这是由于,lock文件如果放入版本控制中,那么在
pod update时,会有可能不成功。
团队中的做法是,将
Podfile放入版本管理中,而不是
podfile.lock。
5.2 Mainfest.lock
此为每次运行Mainfest.lock时创建的
Podfile.lock文件副本。如果你遇见过这样的错误:
沙盒文件与 Podfile.lock 文件不同步 (The sandbox is not in sync with the Podfile.lock)
这就是由于
Manifest.lock文件和
podfile.lock文件不一致引起的。由于Pods所在的目录并不总是在版本控制之下(事实上最好不要放在版本控制之下),这样可以保证开发整运行app之前都能更新他们的pods,否则app可能会crash,或者在一些不太明显的地方编译失败。
在开发中,有时候不会将Pods文件夹中的内容放入版本控制中,这也是一种增加pull代码速度、保持工程干净的一种方式。
.xcodeproj
它会对 Pods.xcodeproj文件执行一下
touch以将其转换成为旧的
ASCII plist格式的文件。如果没有
xcproj,你的
Pods.xcodeproj文件将会以
XML格式的
plist文件存储,当你用 Xcode 打开它时,它会被改写,并造成大量的文件改动。
结果
运行pod install命令的最终结果是许多文被添加到你的工程和系统中。此过程只需要几秒钟时间。
不受版本控制的Pods文件夹
如果你的Pods文件夹不受版本控制,那么你需要做一些额外的步骤来保证持续集成的顺利进行。最起码,正如前文说的,
podfile文件要放入版本控制之中。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- 举例详解iOS开发过程中的沙盒机制与文件
- Android和IOS的浏览器中检测是否安装某个客户端的方法
- 分享一个iOS下实现基本绘画板功能的简单方法
- javascript实现阻止iOS APP中的链接打开Safari浏览器