CocoaPods Under The Hood

参考: https://www.objc.io/issues/6-build-tools/cocoapods-under-the-hood/
CocoaPods is a library dependency management tool for OS X and iOS applications. With CocoaPods, you can define your dependencies, called pods, and manage their versions easily over time and across development environments.

The philosophy behind CocoaPods is twofold. Firstly, including third-party code in your projects involves many hoops. For the beginning Objective-C developer, the project file is daunting. Going through the steps of configuring build phases and linker flags leaves a lot of room for human error. CocoaPods simplifies all of that, and automatically configures your compiler settings.
Secondly, CocoaPods makes it easy to discover new third-party libraries. Now, this doesn’t mean you should go and build a FrankenApp, where every part is written by somebody else and simply stitched together. It does mean that you can find really good libraries that shorten your development cycle and improve the quality of your software.
In this article, we will walk through the pod install process, and take a deeper look at what CocoaPods is doing behind the scenes.

Core Components
CocoaPods is written in Ruby and actually is made of several Ruby Gems. The most important gems when explaining the integration process are CocoaPods/CocoaPods, CocoaPods/Core, and CocoaPods/Xcodeproj (yes, CocoaPods is a dependency manager that is built using a dependency manager!).

CocoaPods/CocoaPod
This is the user-facing component and is activated whenever you call a pod command. It includes all the functionality you need to actually use CocoaPods, and makes use of all of the other gems to perform tasks.

CocoaPods/Core
The Core gem provides support for working with the files that are involved with CocoaPods, mainly the Podfile and podspecs.
Podfile
The Podfile is the file that defines the pods you want to use. It is highly customizable, and you can be as specific as you’d like. For more information, check out the Podfile guide.
Podspec
The .podspec is a file that determines how a particular pod is added to a project. It supports features such as listing source files, frameworks, compiler flags, and any other dependencies that a library requires, to name a few.

CocoaPods/Xcodeproj
This gem handles all of the project file interactions. It has the ability to both create and modify .xcodeproj and .xcworkspace files. It is also useable as a standalone gem, so if you ever wanted to write scripts and easily modify the project file, this gem is for you.

Running pod install
There is a lot that happens when pod install runs. The easiest insight into this is running the command with --verbose. Run that command, pod install --verbose now, and then come back. It will look something like this:
$ 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

There’s a lot going on here, but when broken down, it’s all very simple. Let’s walk through it.

Reading the Podfile
If you’ve ever wondered why the Podfile syntax looks kind of weird, that’s because you are actually writing Ruby. It’s just a simpler DSL to use than the other formats available right now.
So, the first step during installation is figuring out what pods are both explicitly or implicitly defined. CocoaPods goes through and makes a list of all of these, and their versions, by loading podspecs. Podspecs are stored locally in ~/.cocoapods.

Versioning and Conflicts
CocoaPods uses the conventions established by Semantic Versioning to resolve dependency versions. This makes resolving dependencies much easier, since the conflict resolution system can rely on non-breaking changes between patch versions. Say, for example, that two different pods rely on two versions of CocoaLumberjack. If one relies on 2.3.1 and another 2.3.3, the resolver can use the newer version, 2.3.3, since it should be backward compatible with 2.3.1.
But this doesn’t always work. There are many libraries that don’t use this convention, which makes resolution difficult.
And of course, there will always be some manual resolution of conflicts. If one library depends on CocoaLumberjack 1.2.5 and another 2.3.1, only the end user can resolve that by explicitly setting a version.

Loading Sources
The next step in the process is actually loading the sources. Each .podspec contains a reference to files, normally including a git remote and tag. These are resolved to commit SHAs, which are then stored in ~/Library/Caches/CocoaPods. The files created in these directories are the responsibility of the Core gem.
The source files are then downloaded to the Pods directory using the information from the Podfile, .podspec, and caches.

Generating the Pods.xcodeproj
Every time pod install is run and changes are detected, the Pods.xcodeproj is updated using the Xcodeproj gem. If the file doesn’t exist, it’s created with some default settings. Otherwise, the existing settings are loaded into memory.

Installing Libraries
When CocoaPods adds a library to the project, it adds a lot more than just the source. Since the change to each library getting its own target, for each library, several files are added. Each source needs:
An .xcconfig that contains the build settings
A private .xcconfig that merges these build settings with the default CocoaPods configuration
A prefix.pch which is required for building
A dummy.m which is also required for building
Once this is done for each pod target, the overall Pods target is created. This adds the same files, with the addition of a few more. If any source contains a resource bundle, instructions on adding that bundle to your app’s target will be added to Pods-Resources.sh. There’s also a Pods-environment.h, which has some macros for you to check whether or not a component comes from a pod. And lastly, two acknowledgement files are generated, one plist, one markdown, to help end users conform with licensing.

Writing to Disk
Up until now, a lot of this work has been done using objects in memory. In order for this work to be reproducible, we need a file record of all of this. So the Pods.xcodeproj is written to disk, along with two other very important files, Podfile.lock and Manifest.lock.

Podfile.lock
This is one of the most important files that CocoaPods creates. It keeps track of all of the resolved versions of pods that need to be installed. If you are ever curious as to what version of a pod was installed, check this file. This also helps with consistency across teams if this file is checked in to source control, which is recommended.

Manifest.lock
This is a copy of the Podfile.lock that gets created every time you run pod install. If you’ve ever seen the error The sandbox is not in sync with the Podfile.lock, it’s because this file is no longer the same as the Podfile.lock. Since the Pods directory is not always under version control, this is a way of making sure that developers update their pods before running, as otherwise the app would crash, or the build would fail in another, less visible, way.

xcproj
If you have xcproj installed on your system, which we recommend, it will touch the Pods.xcodeproj to turn it into the old ASCII plist format. Why? The writing of those files is no longer supported, and hasn’t been for a while, yet Xcode still relies on it. Without xcproj, your Pods.xcodeproj is written as an XML plist, and when you open it in Xcode, it will be rewritten, causing large file diffs.

The Result
The finished product of running pod install is that a lot of files have been added to your project and created on the system. This process usually only takes a few seconds. And, of course, everything that CocoaPods does can be done without it. But it’ll take a lot longer than a few seconds.

Sidenote: Continuous Integration
CocoaPods plays really well with Continuous Integration. And, depending on how you have your project set up, it’s still fairly easy to get these projects building.
With a Version-Controlled Pods Folder
If you version control the Pods folder and everything inside it, you don’t need to do anything special for continuous integration. Just make sure to build your .xcworkspace with the correct scheme selected, as you need to specify a scheme when building with a workspace.

Without a Pods Folder
When you do not version control your Pods folder, you need to do a few more things to get continuous integration working properly. At the very least, the Podfile needs to be checked in. It’s recommended that the generated .xcworkspace and Podfile.lock are also under version control for ease of use, as well as making sure that the correct pod versions are used.
Once you have that setup, the key with running CocoaPods on CI is making sure pod install is run before every build. On most systems, like Jenkins or Travis, you can just define this as a build step (in fact, Travis will do it automatically). With the release of Xcode Bots, we haven’t quite figured out a smooth process as of writing, but are working toward a solution, and we’ll make sure to share it once we do.

Wrapping Up
CocoaPods streamlines development with Objective-C, and our goal is to improve the discoverability of, and engagement in, third-party open-source libraries. Understanding what’s happening behind the scenes can only help you make better apps. We’ve walked through the entire process, from loading specs and sources and creating the .xcodeproj and all its components, to writing everything to disk. So next time, run pod install --verbose and watch the magic happen.

时间: 2024-10-02 06:29:41

CocoaPods Under The Hood的相关文章

CocoaPods安装及使用

工欲善其事,必先利其器,在此记录一下CocoaPods的安装及使用. 一.安装 1.升级Ruby环境 在终端使用:$sudo gem update —system来进行升级 2.安装CocoaPods时我们要访问cocoapods.org,该网站可能被墙了,这样下载安装可能会是龟速,我们可以用淘宝的Ruby镜像来访问该网站,方法如下: 1).gem sources --remove  https://rubygems.org/ 2).gem sources -a  http://ruby.tao

Curious Robin Hood(树状数组+线段树)

1112 - Curious Robin Hood    PDF (English) Statistics Forum Time Limit: 1 second(s) Memory Limit: 64 MB Robin Hood likes to loot rich people since he helps the poor people with this money. Instead of keeping all the money together he does another tri

CocoaPods的安装和使用介绍

如有问题欢迎加iOS群:391609253(杭州.上海为主)1.安装 1)首先,查看电脑是否安装了CocoaPods. 上图说明没有安装CocoaPods. 2)接下来,由于在Mac下自带有ruby,使用ruby的gem命令即可下载: 3)因为使用的是亚马逊的云服务,所以Unable to了,那么接下来就是更改ruby的软件源为淘宝源. 4)更改好之后就可以下载了,命令为sudo gem install cocoapods,看到20 gems installed 说明已安装完毕. 5)接下来可以

使用CocoaPods管理第三方开源类库

iOS开发中经常会用到许多第三方类库,比如AFNetworking.FMDB.JSONKit等等,使用CocoaPods这个工具就能很方便得对工程中用到的类库进行管理,包括自动下载配置以及更新. 首先需要下载安装CocoaPods,系统要求有ruby环境,至少OS X 10.9以后是自带ruby环境的(Python也自带了),使用"ruby -v"命令可以查看当前ruby版本. 配置过程如下: 1.ruby环境 不放心的话可以先确认下ruby环境,据说由于GFW的影响,大都把Ruby镜

Cocoapods的安装和使用

一.Cocoapods的安装 第一步:打开终端 第二步:修改ruby镜像引用 gem source --remove https://rubygems.org/ gem sources -a http://ruby.taobao.org/ 完成后用命令行查看ruby镜像是否是taobao,用命令行: gem sources -l 返回信息为: *** CURRENT SOURCES *** http://ruby.taobao.org/ 即为成功. 第三步:安装cocoapods sudo ge

cocoaPods的安装

先介绍下自己吧,准备从事ios开发,现在还是一名小白哦,写得不好请多多指教. 一.为什么需要cocoaPods ios开发时,项目中会用到许多第三方库,如果一一把第三方库导入项目时,会很麻烦. 就引出了CocoaPods(https://github.com/CocoaPods/CocoaPods),它可以用来方便的统一管理这些第三方库. 二.安装过程 第一步:安装或者更新Ruby.(当前安装环境Xcode 8.2  ,mac  OS Sierra 10.12.3) Mac  OS本身自带Rub

使用cocoapods

使用cocoapods 0.如果发现装cocoapods时出错就更新gem到最新版本,在终端中输入:$ sudo gem update --system,注意不要把"$"复制上.等待一会儿会看到   我已经敲过所以是   1.移除原有的源 gem sources --remove https://rubygems.org/   2.添加淘宝的镜像gem sources -a https://gems.ruby-china.org/(原来的淘宝镜像https://ruby.taobao.

Cocoapods 简单的使用

Cocoapods的安装就不再记录了,网上搜索就可以.在这里只记录一些Cocoapods简单的使用. 1.Cocoapods 安装三方步奏 ①首先在终端cd到你项目的目录 ②进入到vim编辑器,进行对Podfile编辑 ③对Podfile进行编辑, 需要注意的是podfile里面输入的格式变了. platform :ios,'8.0' [支持的最高版本] target '你项目的名称' do pod 'AFNetworking','~>3.1.0' end ④对Podfile编辑完成后,按ESC

【转】CocoaPods一个Objective-C第三方库的管理利器

原文网址:http://blog.csdn.net/totogo2010/article/details/8198694 介绍: 开发应用的时候第三方的库是不可缺少的,能提高开发的效率. 一些经常用到的库,在新的项目里用是,你又得手工的Add到项目里,用的到库多起来了,就不方便管理了.发现CocoaPods这个软件,可以帮你管理Xcode里的第三方的库,很方便. 那怎么用呢?先安装CocoaPods. 1.CocoaPods是跑在Ruby的软件,安装可能需要几分钟,安装命名: sudo gem