August 12, 2015
If you’re already familiar with CocoaPods, then you can probably skip this post. If you’re not, it’s worth taking a few minutes to learn about the lovely dependency manager commonly used for iOS libraries today.
CocoaPods is great for adding libraries to your iOS projects, in Objective-C and Swift. In fact, it’s easy to use Objective-C code in Swift projects. If you’re curious, check out Objective-C in Swift Project.
We’ll just cover the simple basics so that when a tutorial says something like add SwiftyJSON v2.2.0 to your project using CocoaPods you’ll know just what to do.
Adding a CocoaPod to your Project
Let’s say we’re going to add the SwiftyJSON CocoaPod to an Xcode project. Here’s what we need to do:
Close your Xcode project
Open the terminal in the project top directory (the directory with the .xcodeproj file for your project)
If you haven’t previously installed CocoaPods run:
sudo gem install cocoapods
If you need more info on installing CocoaPods, check out their Getting Started guide.
Once it’s done installing CocoaPods, you need to initialize Cocoapods for your project. So run:
pod init
That’ll create a new file called “Podfile” with a nice default structure. (You don’t have to use pod init
, you could also just do touch Podfile
to create that file and it’d work just as well). Using a text editor, open the newly created Podfile:
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
target 'grokSwiftRest' do
# Comment this line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for grokSwiftRest
target 'grokSwiftRestTests' do
inherit! :search_paths
# Pods for testing
end
target 'grokSwiftRestUITests' do
inherit! :search_paths
# Pods for testing
end
end
The target names shown will depend on your project. If you didn’t select unit tests or UI tests when you created your project then those sections won’t be shown:
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
target 'grokSwiftRest' do
use_frameworks!
# Pods for grokSwiftRest
end
If you want to specify the minimum version of iOS, comment out the first line (and change it to 8.0 or whatever you’re supporting):
platform :ios, '8.0'
target 'grokSwiftRest' do
use_frameworks!
# Pods for grokSwiftRest
end
Now we need to add some pods to the Podfile. To do that we add a line that starts with pod
. Here’s how to add SwiftyJSON:
platform :ios, '8.0'
target 'grokSwiftRest' do
use_frameworks!
# Pods for grokSwiftRest
pod 'SwiftyJSON'
end
Save the Podfile then switch back to Terminal and run:
pod install
Open the .xcworkspace file in Xcode. Navigate back to whatever class you want to use SwiftyJSON in and add “import SwiftyJSON” at the top like this:
import Foundation
import SwiftyJSON
class MyClass {
...
}
What does the Podfile mean?
While it’s nice to just get instructions that work, it’s usually a good idea to know why they work. So let’s take a look at that Podfile:
platform :ios, '8.0'
target 'grokSwiftRest' do
use_frameworks!
# Pods for grokSwiftRest
pod 'SwiftyJSON'
end
When you run pod install
CocoaPods looks for a Podfile and tries to install the pods listed in it. Install in this case means:
- Fetch the code for the pods and any dependencies they have
- Compile the pods (including the dependencies)
- Unless one already exists, create an Xcode workspace file to hold the pods and the existing project
- Set up the workspace so that the framework is accessible by code in the project
You might not have come across Xcode workspaces before. They’re kind of super-projects: a workspace can hold multiple projects that depend on each other. Like here, we’ll have a Pods project as well as our app project that needs the framework from the Pods project to run.
Let’s go through the Podfile line by line:
platform :ios, '8.0'
The first line specifies that we’re working on iOS (not OS X) and we’re building an app for the iOS 8.0 SDK. Including this info in a Podfile means that pods can have different version for iOS and OS X as well as for different versions of the iOS SDK.
target 'grokSwiftRest' do
...
end
We can include pods for each target in our project, so we have to list the targets in the Podfile. We can also specify that pods should be included for all targets by putting them before the target statements. If we only have one target then this Podfile is equivalent to the previous one:
platform :ios, '8.0'
use_frameworks!
pod 'SwiftyJSON'
target 'grokSwiftRest' do
end
use_frameworks!
use_frameworks!
tells CocoaPods how we want to integrate the code libraries with our project. In Swift we want it to wrap up the code in a framework then include the framework in a workspace. Since CocoaPods pre-dates Swift, that’s not the default so we have to include this line. Want more details? See the release notes for CocoaPods v0.36.
pod 'SwiftyJSON'
And finally we specify which pod (or pods) we want to install.
Dependencies
We’re using the default public CocoaPods repository which is a great place to check for libraries for your projects. You can search for pods in the public repo at cocoapods.org. To find the correct pod, CocoaPods checks the repository for a pod with the name that you specified.
The huge time saver in CocoaPods is that pods can specify dependencies. So if SwiftyJSON required some other library then CocoaPods would make sure we have it in our Pods before downloading SwiftyJSON and adding it to our project. It’ll also make sure that we have the correct compatible version. So we don’t need to hunt down and install a bunch of prerequisites before installing a pod or worry about updating all of the dependencies before we can update a pod.
How does CocoaPods know? Each pod has a podspec
file in it. That file is responsible lists things like the dependencies, the pod’s version number, and what version of iOS/OS X the pod works with.
CocoaPod Version Numbers
One option that I commonly use in CocoaPods specifying which version of a pod I want. That way I can explicitly choose when to upgrade to the latest version. By including the Podfile in a git repo I can go back later to recreate old versions of my apps and know that they’re using the same pods, even without checking in all of the code in the pods.
In a Podfile we can specify an exact version number or be a bit less fussy. For example, to use version 2.2.0:
pod 'SwiftyJSON', '2.2.0'
We could also say that we want to use SwiftyJSON 2.2.whatever to get small updates:
pod 'SwiftyJSON', '~> 2.2.0'
Which would allow 2.2.0, 2.2.1, 2.2.2, … but not 2.3.
Or even v2.whatever:
pod 'SwiftyJSON', '~> 2.2'
Which would allow 2.2, 2.3, … but not 3.0.
If we leave off the version number then CocoaPods will just install the latest version.
Updating CocoaPods
Unless you tell them to, CocoaPods won’t auto-update to newer versions. To tell CocoaPods that you do want newer versions (after tweaking the version numbers in your Podfile if you’re using them) run:
pod update
You’ll see a message in the terminal showing you which pods were updated and to which versions. You’ll also need to run that command if you change the version numbers in the Podfile or add more pods to it.
And That’s All For CocoaPods (Today)
Hopefully that info make it feel a little less like magic when you use CocoaPods.
If you want to go deeper, you can do some neat stuff with CocoaPods including adding different code in testing and App Store versions of your app or making private CocoaPods for use within a team. If you’re curious, check out Creating and Using CocoaPods by Jeffrey Sambells or the CocoaPods Guides.
If you’d like more Swift tutorials on topics like this one, sign up below to get them sent directly to your inbox. Feel free to come back and visit too, we’re pretty friendly around here, but we’ll understand if it’s just easier for us to come to you :) If you have any questions or would like to read about a certain topic, comment below.