pod install的深入理解

CocoaPods是什么?

CocoaPods是iOS平台当前最流行的包管理工具,可以将它理解为一个可以自动部署到项目的组件池,而对应的podfile文件就相当于请求组件的Request。当组件下载到工程后,CocoaPods会自动完成组件集成到现有项目的工作,并完成修改.xcodeproj文件和创建.xcworkspace文件。最终将所有组件统一打包成Pods.a或者Pods.framework静态库,供项目使用。(类似于JS依赖包管理工具npm)

在CocoaPods中,会存在以下几种文件:

  • podspec
    Pod的描述文件,一般来说表征你的项目地址,项目使用的平台和版本等信息
  • podfile
    用户编写的对于期望加载的pod以及对应Target信息
  • podfile.lock
    记录了之前pod加载时的一些信息,包括版本、依赖、CocoaPods版本等
  • mainfest.lock
    记录了本地pod的基本信息,实际上是podfile.lock的拷贝
    大部分开发者最熟悉的cocoaPods指令就是pod install,那具体在执行pod install时发生了什么呢?

pod install 运行原理分析

当我们运行pod install时,实际上 发生了下面这些步骤:

  • 分析dependency
    对比本地Pod和podfile.lock文件中的版本,如果不一致会提示存在风险。
  • 对比podfile是否发生了变化,add/remove pod依赖
    如果存在 ,会生成两个列表,一个是需要add的pods,一个是需要remove的pods。
  • 如果存在remove的,删除remove的pods(会删除podfile.lock里的版本依赖)。
  • 添加需要的pods依赖
    此时,如果是常规的CocoaPods库(基于git),会先去:
  • Spec下查找对应的Pods文件夹

  • 找到对应的tag

  • 找到对应tag下面的podspec文件

  • git clone下来代码并copy到Pod目录下


    目录结构.png
  • 运行pre-install hook

  • 生成Pod Project
  • 将该pod文件添加到工程中
  • 添加对应的framework、.a库、bundle等
  • 链接头文件,生成Target
  • 运行post-install hook
  • 生成podfile.lock ,之后生成文件副本mainfest.lock并将其放在Pod文件夹内。(如果出现 The sandbox is not sync with the podfile.lock这种错误,则表示manifest.lock和podfile.lock文件不一致),此时一般需要重新运行pod install命令。
  • 配置原有的project文件(add build phase)
  • 添加了 Embed Pods Frameworks
  • 添加了 Copy Pod Resources
    其中,pre-install hook和post-install hook可以理解成回调函数,是在podfile里对于install之前或者之后(生成工程但是还没写入磁盘)可以执行的逻辑,逻辑为:
pre_install do |installer| 
    # 做一些安装之前的hook
end

post_install do |installer| 
    # 做一些安装之后的hook
end

注意:pod install优先遵循 Podfile 里指定的版本信息,其次遵循 Podfile.lock 里指定的版本信息来安装对应的依赖库。

Xcode工程有什么变化

在cocoaPods和Xcode工程进行集成的过程中,会有有以下流程:

  • 创建workspace
    创建xcworkspace文件。其实xcworkspace文件本质上只是xcodeproject的集合,数据结构如下:


   
   
   
   

  • create group
    在工程中创建group文件夹,逻辑上隔离一些文件
  • create pod project & add pod library
    创建pod.xcodeproject工程,并且将在podfile中定义的第三方库引入到这个工程之中。
  • add embed frameworks script phase
    添加了[CP] Embed Pods Frameworks,相应的,多了pods_xxx的group,下列xxx.framework.sh,来完成将内部第三方库打包成.a静态库文件(在Podfile中如果选择了use_frameworks!,则此步骤会打包成.framework)


    [CP] Embed Pods Frameworks

    [CP] Embed Pods Frameworks

  • remove embed frameworks script phase
    如果本次podfile删除了部分第三方库,则此步骤会删除掉不需要的第三方库,将其的引用关系从Pod.xcodeproject工程中拿走。
  • add copy resource script phase
    如果第三方库存在资源bundle,则此步骤会将资源文件进行复制到集中的目录中,方便统一进行打包和封装。相应的,会添加[CP] Copy Pods Resources脚本。


    [CP] Copy Pods Resources
  • add check manifest.lock script phase
    前文提到过,manifest.lock其实是podfile.lock的副本。此步骤会进行diff,如果存在不一致,则会提示著名的那句The sandbox is not sync with the podfile.lock错误。
  • add user script phase
    此步骤是对原有project工程文件进行改造。在运行过pod install后,再次打开原有工程会发现无法编译通过,因为已经做了改动。
  • 首先,添加了对Pod工程的依赖,具体为引用中多了libPods_xxx.a文件。此步骤的.a文件(或者.framework文件)为上述步骤中xxx.framework.sh打包出来的文件,也就是说,cocoaPods会把所有第三方的组件封装为一个.a文件(或者.framework文件)!


    静态文件引入

    *建立了Pods的group,内含pods-xxx-debug.xconfig和pods-xxx.release.xconfig文件。这两个文件是对应工程的build phase的配置。相应的,主工程的Iinfo->Configurations的debug和release配置会对应上述两个配置文件。


    Configurations
  • 上述两个配置都做了什么?包括:
    Header_search_path,指向了Pod/Headers/public/xxx,添加了Pods文件编译后的头文件地址
    Other_LDFLAGS,添加了-ObjC等等
    一些Pods变了,例如Pods_BUILD_DIR等
    至此,原有xcode工程和新建的Pod工程完成了集成和融合。

你可能感兴趣的:(pod install的深入理解)