Using CocoaPods with pre-built frameworks instead of source files

One of the best things of Carthage is that it works with pre-built frameworks instead of source files. Hence, your project’s build-time is reduced considerably.

CocoaPods is somehow different. It automatically downloads source code from wherever it is for each library but it just adds the result to your project as a dependency. Every time you clean and build your project you need to build a huge amount of dependencies repeatedly.

Even though it’s not widely known (probably because it’s not mentioned in the start-up guide), CocoaPods allows you to work with pre-built frameworks as well, having the best of CocoaPods and Carthage together.

Introducing cocoapods-binary

cocoapods-binary is a CocoaPods’ plugin designed to link pre-built frameworks to the project. Once you execute pod install command, it will automatically pre-build a framework for each dependency and it will link the result to your project.

This ends in build-time reduction for your project, since you’ll be building your source code only, instead of each dependency everytime. It’s really a step forward in the right direction.

Installing cocoapods-binary

In order to install cocoapods-binary, we need to run either brew install cocoapods-binary or gem install cocoapods-binary command.

Using cocoapods-binary in our Podfile

We need to add the following line to the beginning of our Podfile:

plugin 'cocoapods-binary'

If we want to use pre-built frameworks for all of our dependencies, we can also add all_binary! before any target or definition.

If we run pod install again, it will pre-build a framework for each dependency and it will link it with our project. If we clean and build it, it will no longer waste a huge amount of time building dependencies.

Embedding Bitcode in pre-built frameworks

If we want to Bitcode to be embed in our iOS app we’ll also need to have it embedded in our dependencies. In order to make it work with pre-built frameworks, we’ll need to specify it in the Podfile by adding enable_bitcode_for_prebuilt_frameworks! and keep_source_code_for_prebuilt_frameworks! after all_binary! .

Please note you will need to re-run pod install in order to see the changes.

Adding exceptions

Some dependencies won’t work if we try to add them using pre-built frameworks, such as Google Maps iOS SDK. Since it requires GoogleMaps.bundle file to be added to the main project and copied at build-time, using a pre-built framework is not an option.

In order to keep them working properly, we will need to add an exception by setting :binary => false to each dependency we would like to exclude.

pod 'GoogleMaps', :binary => false

Let’s see an example

Considering we have the following Podfile:

plugin 'cocoapods-binary'

platform :ios, '12.0'
use_frameworks!

target 'ProjectName' do
pod 'Charts'
pod 'RxSwift'
pod 'RxCocoa'
pod 'Kingfisher'
pod 'SwipeCellKit'
pod 'FSCalendar'
pod 'NVActivityIndicatorView'
pod 'Alamofire'
pod 'HandyJSON'
pod 'RealmSwift'
pod 'KeychainSwift'
pod 'TrustKit'
pod 'ReachabilitySwift'
pod 'OAuthSwift'
end

We would need to transform it to:

plugin 'cocoapods-binary'

platform :ios, '12.0'
use_frameworks!
enable_bitcode_for_prebuilt_frameworks!
keep_source_code_for_prebuilt_frameworks!
all_binary!

target 'ProjectName' do
pod 'Charts'
pod 'RxSwift'
pod 'RxCocoa'
pod 'Kingfisher'
pod 'SwipeCellKit'
pod 'FSCalendar'
pod 'NVActivityIndicatorView'
pod 'Alamofire'
pod 'HandyJSON'
pod 'RealmSwift'
pod 'KeychainSwift'
pod 'TrustKit'
pod 'ReachabilitySwift'
pod 'OAuthSwift'
end

After that, running pod install command will pre-build a framework for each dependency and link it to the project. Cleaning and rebuilding our app won’t rebuild each dependency again.

Related notes

Check out official docs of cocoapods-binary for more information.