• CocoaPods——深入理解 CocoaPods


    本文由 伯乐在线 - programmer.du 翻译自 Michele Titolo。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。

      Cocoapods是 OS X 和 iOS 下的一个第三方库管理工具。你能使用CocoaPods添加被称作“Pods”的依赖库,并轻松管理它们的版本,而不用考虑当前的时间和开发环境。

      Cocoapods意义体现在两个方面。首先,引入第三方库无可避免地要进行各种各样的配置。对于Objective-C的初级开发者来说,项目配置可是一件艰巨的任务。在配置编译阶段和链接器选项的过程中,极有可能引入许多人为的错误。而CocoaPods简化了这一切,它能自动配置编译选项,拯救了开发者。

      其次,使用CocoaPods可以很方便地查找新的第三方库。当然,这可不是说让你七拼八凑别人代码而开发出一个“移栽”应用。而是让你找到真正好用的库,缩短你的开发周期,提升你的代码质量。

      接下来,我们将通过分析pod安装的过程,一步步揭示CocoaPods背后的技术。

    核心组件

      CocoaPods是用ruby写的,并划分成了若干个Gem包。CocoaPods在解析执行过程中最重要的几个包的路径分别是:CocoaPods/CocoaPods、 CocoaPods/Core 和 CocoaPods/Xcodeproj。

      CocoaPods / CocoaPod

      这是面向用户的组件,每当你执行一个pod命令时,这个组件将被激活。它包括了所有实用CocoaPods的功能,并且还能调用其他gem包来执行任务。

       CocoaPods / Core

      Core gem提供了与CocoaPods相关的文件(主要是Podfile和podspecs)的处理。

      Podfile

      Podfile用于配置项目所需要的第三方库。它能被高度定制,所以你可以尽可能地给它添加你想要的特性。如果您还想对Podfile了解更多的话,请查看Podfile指南(地址 http://guides.cocoapods.org/syntax/podfile.html)。

      Podspec

      .podspec文件描述了一个库将怎样被添加进工程中。.podspec文件可以标识该第三方库所需要的源码文件、依赖库、编译选项,以及其他第三方库需要的配置。

      CocoaPods / Xcodeproj

      这个包负责工程文件直接关系的处理。它能创建以及修改.xcodeproj文件和.xcworkspace文件。它也可以作为一个独立的包使用,当你要编写修改项目文件的脚本时,可以考虑使用CocoaPods/Xcodeproj。

    运行 pod install 命令

      pod install的执行引发了很多操作。了解底层运行过程最简单的方式就是给pod install语句添加 –verbose 参数。现在,运行

    pod install --verbose

      将会出现以下执行结果:

    Analyzing dependencies 
    
    Updating spec repositories
    Updating spec repo `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

      整个过程中执行了很多操作,不过把它们分解之后,会发现它们都很简单。让我们逐步来分析。

      阅读Podfile文件

      你是否吐槽过Podfile的语法太过诡异,其实这是ruby的语法而不是OC。相较而言,Podfile要比现有的其他格式更加简单好用一些。

      安装的第一步是要弄清楚哪些第三方库被显式或隐式地声明了。CocoaPods加载podspecs文件时,获取了第三方库的名称及版本列表。Podsspecs文件存储在本地,路径为~/.cocoapods。

      版本控制和冲突

      CocoaPods使用语义版本命名约定来解决对版本的依赖。由于冲突解决系统建立在非重大更改的补丁版本之间,这使得解决依赖关系要容易得多。举个栗子,两个完全不同的第三方库同时依赖CocoaLumberjack。它们其中一个依赖的版本是2.3.1,而另一个则为2.3.3,解析器可以自动使用较新的版本,在这里则是2.3.3,因为这可以与2.3.1向后兼容。

      但这并不总是有效。有许多第三方库还并不支持这个约定,这让解决方案变得非常复杂。

      当然,总是会有一些冲突需要手工解决。如果一个第三方库依赖CocoaLumberjack 1.2.5,而另一个依赖CocoaLumberjack 2.3.1,最后只能靠调用这两个第三方库的用户来手动地决定CocoaLumberjack的版本了。

      加载源码

      CocoaPods执行的下一个步骤是加载源代码。每个.podspec文件都包含了源代码的索引,这些索引一般指向了一个git地址或者git tag。它们以commit SHA码的方式存储在 ~/Library/Caches/CocoaPods中。而在这些路径中创建文件则由 Core 包负责。

      源代码将依照Podfile、.podspec和缓存文件的信息下载到相应的第三方库路径。

      生成Pods.xcodeproj

      每次pod install 执行后并且检测到改动时,Pods.xcodeproj文件将呗Xcodeproj gem更新。如果Pods.xcodeproj文件不存在,则会以默认配置生成,若已存在,则Pods.xcodeproj会使用现有的配置。

      安装第三方库

      当Cocoapods向项目中增加了一个第三方库的时候,不仅仅是将添加代码这么简单。由于每个第三方库有不同的target,所以每次添加第三方库时,都只有几个文件被添加。每个源代码都需要:

    • 一个包含编译选项的.xcconfig文件
    • 一个同时拥有编译设置和CocoaPods默认配置的私有.xcconfig文件
    • 编译所必须的prefix.pch文件
    • 另一个编译必须的文件dummy.m

      一旦每个pod的target都完成了以上步骤,整个Pods的Target就会被创建。这增加了相同的文件,与另外几个。如果有源代码中包含了资源bundle,向app的target中添加bundle的方式将写入Pods-Resources.sh。还有一个叫Pods-environment.h的文件,文件中含有许多检查组件是否来自pod的宏定义。最后,将生成两个确认文件,一个.plist文件,一个用于给用户查阅许可信息的markdown文件。

      写入到磁盘

      直到现在,许多已完成的过程都使用的是内存中的对象。为了让这些过程的结果可重复被使用,我们需要将所有结果都记录在一个文件中。所以Pods.xcodeproj和另外两个非常重要的文件:Podfile.lock和Manifest.lock都将被写入磁盘。

      Podfile.lock

      这是CocoaPods创建的最重要的文件之一。它记录了需要被安装的pod的每个已安装的版本。如果你想知道已安装的pod是哪个版本,可以查看这个文件。推荐将Podfile.lock文件加入到版本控制中,这有助于整个团队的一致性。

      Manifest.lock

      这是每次运行pod install时创建的Podfile.lock文件的副本。如果你见过“沙盒文件和Podfile.lock文件不同步”的错误,这个错误就是因Manifest.lock文件和Podfile.lock文件不一样引起。由于Pods所在的目录并不总在版本控制之下,这样可以保证开发者运行app之前都能更新他们的pods,否则app可能会crash,或者在一些不太明显的地方编译失败

      xcproj

      如果您已经依照我们的建议在系统上安装了xcproj,它会将您的Pods.xcodeproj文件转换成就旧有ASCII格式的plist文件。为什么要这么做呢?因为Xcode所依赖和使用的plist在很久以前就已经不被其他软件支持了。如果没有xcproj,你的Pods.xcodeproj文件将会以XML格式的plist文件存储,当你用Xcode打开它时,它会被改写,造成大量的文件冲突。

    运行结果

      运行pod install的最终结果是许多文件被添加到你的工程和系统中。这个过程通常只需要几秒钟。当然没有Cocoapods这些事也都可以完成。只不过所花的时间就不仅仅是几秒而已了。

    旁注:持续集成

      CocoaPods和持续集成在一起非常融洽。虽然持续集成很大程度上取决于你的项目配置,但Cocoapods依然能很容易地对项目进行编译。

      Pods文件夹已加入版本控制的持续集成

      如果包括Pods文件夹的一切东西都在版本控制之中,那么你不需要特别做什么就能够持续集成。由于编译时必须指定一个scheme,所以只需要保证使用了正确的scheme即可。

      没有Pods文件夹的持续集成

      如果你的Pods文件夹没有被纳入版本控制之中,那么你需要一些额外的步骤来保证持续集成的顺利进行。最起码,Podfile文件要放入版本控制之中。另外强烈建议将生成的.xcworkspace文件和Podfile.lock文件纳入版本控制,这样不仅简单方便,更能保证所使用的Pod是正确的版本。

      一旦配置完毕,让CocoaPods在CI上正确运行的关键是保证每次编译之前都执行了pod install。在大多数系统中,譬如Jenkins或者Travis,你只用把“pod install”定义为一个编译步骤即可(实际上,Travis会自动执行pod install)。随着Xcode Bot的发布,我们还没有找到能像书写的这么流畅的解决方案,不过我们正朝着解决方案努力,一旦成功,我们将会立即分享。

    结束语

      CocoaPods简化了OC的开发流程,我们的目标是让第三方库更容易被发现和添加。了解CocoaPods的原理能让你做出更好的App。我们沿着CocoaPods的整个流程一步步执行,从载入specs文件和源代码、创建.xcodeproj文件和所有组件到将所有文件写入磁盘。所以接下来,我们运行 pod install –verbose,静静观察CocoaPods的魔力如何显现。

  • 相关阅读:
    .netcore3.1添加swagger及JWT Authorize 验证
    Quartz.Net实现简单定时任务调度
    基于.Net Framework进行配置Swagger
    升级anaconda的python版本命令
    使用jmeter自带的html查看测试报告
    软件质量模型的6大特性和27个子特性
    PyQt5基础教程及官方文档
    使用jmeter进行下载并发测试
    selenium官方入门文档
    web driver 驱动配置位置
  • 原文地址:https://www.cnblogs.com/sunnyke/p/4490577.html
Copyright © 2020-2023  润新知