Reference: 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 Devel opment environments.
The
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 the class 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 your should go and build a frankenapp, where every part was written by somebody else and simply STITC Hed together. It does mean that's can find really good libraries that shorten your development cycle and improve the quality of your s Oftware.
In this article, we'll walk through the pod install process, and take a deeper look at what's CocoaPods is doing Behin d The scenes.
Core components
CocoaPods are written in Ruby and actually are made of several Ruby Gems. The most important gems when explaining the integration process is cocoapods/cocoapods, Cocoapods/core, and Cocoapods/xco Deproj (yes, CocoaPods is a dependency manager this is built using a dependency manager!).
Cocoapods/cocoapod
The user-facing component and is activated whenever a pod command. It includes all the functionality your need to actually use CocoaPods, and makes use of any of the other gems to perform TA Sks.
Cocoapods/core
The Core Gem provides support for working with the files that is involved with CocoaPods, mainly the Podfile and podspecs .
Podfile
The podfile is the file, defines the pods you want to use. It's highly customizable, and you can be as specific as you ' d. For more information, check out the Podfile guide.
Podspec
The. Podspec is a file, determines how a particular pod was added to a project. It supports features such as listing source files, frameworks, compiler flags, and any other dependencies that a library R Equires, 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, thi S gemis for you.
Running pod Install
There is a lot this happens when pod install runs. The easiest insight into this is running the command with--verbose. Run the command, pod install--verbose now, and then come back. It'll 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 in here and 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're Actua Lly writing Ruby. It ' s just a simpler DSL to use than the other formats available right now.
So, the first step during installation was figuring out what pods was both explicitly or implicitly defined. CocoaPods goes through and makes a list of all of the these, and their versions, by loading podspecs. podspecs is stored locally in ~/.cocoapods .
Versioning and Conflicts
CocoaPods uses the conventions established by Semantic Versioning to resolve dependency ver Sions. This makes resolving dependencies much easier, since the conflict resolution system can rely on non-breaking changes Betwe En patch versions. Say, for example, that, and different pods rely on, 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 compa Tible with 2.3.1.
But the doesn ' t always work. There is many libraries that don ' t use this Convention, which makes resolution difficult.
and of course, there'll 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 this by explicitly settin G 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 is resolved to commit SHAs, which is then stored in ~/library/caches/cocoapods. The files created in these directories is the responsibility of the Core gem.
the source files is then downloaded to the Pods directory using the information from the Podfile,. Podspec, and cache S.
Generating the Pods.xcodeproj
Every time pod install is run and changes be 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 is 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 eachLibrary getting its own target, for each library, several files is 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 was 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 the bundle to your app ' s target would be added to Pods-re sources.sh. There ' s also a pods-environment.h, which has some macros for the check whether or not a component comes fro M a pod. and lastly, acknowledgement files is generated, one plist, one markdown, to help end users conform with licensing.
Writing to Disk
Up until now, a lot of the this work had been done using the objects in memory. In order for this work to is reproducible, we need a file record of all of this. So the pods.xcodeproj are written to disk, along with the other very important files, Podfile.lock and Manifest.lock.
Podfile.lock
The one of the most important files, CocoaPods creates. It keeps track of any of the resolved versions of Pods that need to be installed. If you is ever curious as to what version of a pod is installed, check this file. This also helps with consistency across teams if the this file was checked in to source control, and which is recommended.
Manifest.lock
This was a copy of the Podfile.lock that gets created every time for you run pod install. If you ' ve ever seen the "the sandbox is not in sync with the Podfile.lock, it's because this file is no longer the SA Me as the Podfile.lock. Since The Pods directory is isn't always under version control, this is a by-making sure that developers update their PO DS before running, as otherwise the app would crash, or the build would fail in another, less visible, the.
Xcproj
If you had xcproj installed on your system, which we recommend, it would touch the pods.xcodeproj to turn it into the old ASCII plist format. Why? The writing of those files are no longer supported, and hasn ' t been for a while, yet Xcode still relies on it. Without xcproj, your pods.xcodeproj is written as a XML plist, and when your open it in Xcode, it'll be rewritten, Causi ng large file diffs.
The Result
The finished product of running pod Install is this a lot of files has been added to your project and created on the Syst Em. This process usually only takes a few seconds. And, of course, everything that CocoaPods does can is done without it. But it's ll take a lot longer than a few seconds.
Sidenote:continuous Integration
CocoaPods plays really well with continuous integration. And, depending on what you had your project set up, it's still fairly easy to get these projects.
with a version-controlled Pods folder
If your Version control the Pods folder and everything inside it, you don ' t NE Ed to does anything special for continuous integration. Just make sure to build your. Xcworkspace and the correct scheme selected, as you need to specify a scheme when building With a workspace.
Without a Pods folder
when you don't version control your Pods Folder, you need to do a few more things to get cont Inuous integration working properly. At the very least, the podfile needs to being checked in. It's recommended that the generated. Xcworkspace and Podfile.lock is also under version control for ease of use, as well As making sure that the correct pod versions is used.
Once You has this setup, the key with running CocoaPods on CI are making sure pod install is run before every build. O n most systems, such as Jenkins or Travis, you can just define the as a build step (in fact, Travis would do it automatically ). With the release of Xcode Bots, we haven ' t quite figured out a smooth process as of writing, but is working toward a Solu tion, and we'll make sure to share it once we do.
Wrapping up
CocoaPods streamlines development with OBJECTIVE-C, and our goal are 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 their components , to writing everything to disk. So next time, run pod install--verbose and watch the magic happen.
CocoaPods under the Hood