Distributing Swift Frameworks

Distributing Swift Frameworks via Cocoapods

Anurag Ajwani
Jan 7 · 9 min read

How does Cocoapods work?

In this section we will be looking at a simple overview of how Cocoapods work from two different perspective.

  1. Publishing frameworks to Cocoapods.

1. Installing frameworks to an iOS app project

Let’s start at looking at the simplified overview of how Cocoapods works when we ask the tool to install a Swift framework named FrameworkA to our iOS app project called MyApp.

target 'MyApp' do
  pod 'FrameworkA'
end
Cocoapods — pod install overview

2. Publishing frameworks to Cocoapods

Now that we understand how Cocoapods installs frameworks, the only thing we have to do in order for other apps to use our framework is to publish the specification of our framework to the specification repository.

Cocoapods publish

Getting started

In this guide we will:

  1. Retrieve an Xcode project containing a framework target
  2. Create a local git repository to host our framework project
  3. Create a local specification repository
  4. Publish our framework specification to our specification repository
  5. Install our framework into an app

1. Installing Cocoapods

To start off with let’s install Cocoapods, the tool that will ease sharing and installing frameworks. In terminal type or, copy & paste the following command.

gem install cocoapods
Installing Cocoapods

2. Retrieve starter project

Next, let’s setup the starter framework project which we will share via Cocoapods. Lets download and place the starter project in our home directory via terminal.

cd ~
curl -o MyFramework.zip -L https://www.dropbox.com/s/5vykpag4xb5vh51/MyFramework.zip -s
unzip -q MyFramework.zip

3. Create locally hosted git repository

For this article we’ll be hosting a git repository for the MyFramework project locally in our Macs. To create a locally hosted git repository execute the following commands:

mkdir ~/MyFramework.git
cd ~/MyFramework.git
git init --bare
Locally hosting a git repository for MyFramework project
cd ~/MyFramework
git init
git remote add origin ~/MyFramework.git
git add .
git commit -m "Initial commit"
git tag -a 0.0.1 -m "Version 0.0.1"
git push origin -u master
git push origin --tags
Storing MyFramework in git repository

4. Create local specification repository

Let’s create a repository to hold specifications. This is the place where we publish our framework specification. To do so execute the following commands:

mkdir ~/MySpecs.git
cd ~/MySpecs.git
git init --bare
git clone ~/MySpecs.git ~/MySpecs 
cd ~/MySpecs
touch README.md
git add README.md
git commit -m "Initial commit"
git push origin -u master
pod repo add my-specs ~/MySpecs.git
Create specification repository
List of specification repositories — pod repo list

5. Publish specification for MyFramework

Before pushing a Cocoapods specification let’s add a git tag to our project so Cocoapods can refer to specific snapshot of the project. A git tag will add an identifier to our current state of the project. As git is not the scope of this guide simply know that addition to our project framework won’t affect the code delivered via Cocoapods as Cocoapods will refer to the current state of the project.

cd ~/MyFramework
git tag -a 0.0.1 -m "Version 0.0.1"
cat > ~/MyFramework.podspec <<-EOFPod::Spec.new do |s|
    s.name         = "MyFramework"
    s.version      = "0.0.1"
    s.summary      = "A brief description of MyFramework project."
    s.description  = <<-DESC
    An extended description of MyFramework project.
    DESC
    s.homepage     = "http://your.homepage/here"
    s.license = { :type => 'Copyright', :text => <<-LICENSE
                   Copyright 2018
                   Permission is granted to...
                  LICENSE
                }
    s.author             = { "$(git config user.name)" => "$(git config user.email)" }
    s.source       = { :git => "$HOME/MyFramework.git", :tag => "#{s.version}" }
    s.source_files  = "MyFramework/**/*.swift"
    s.resources = "MyFramework/**/*.xib"
    s.platform = :ios
    s.swift_version = "4.2"
    s.ios.deployment_target  = '12.0'
endEOF
Cocoapods publish
pod repo push my-specs ~/MyFramework.podspec
pod repo push

6. Install MyFramework in an app

Before we can test the installation of MyFramework via Cocoapods we need an app in which to install it to. Let’s fetch MyApp project from my previous post.

cd ~
curl -o MyApp.zip -L https://www.dropbox.com/s/jfdrj58lgrhjc4t/MyApp.zip? -s
unzip -q MyApp.zip
cd ~/MyApp
cat > Podfile <<-EOFtarget 'MyApp' do
    use_frameworks!
    pod 'MyFramework', '0.0.1', :source => "$HOME/MySpecs.git"
endEOF
pod install

Final notes

Before we end this post, note MyFramework source code is copied into a Pods project and wrapped in a framework target. Every time we build the app MyFramework is also built and then attached to the app.

Installed MyFramework in MyApp workspace
Targets in Pods project
MyFramework building in MyApp build process

Summary

In this guide we have learnt

  • how to distribute a framework through Cocoapods
  • how to install our distributed framework via Cocoapods

Next steps

In this guide we saw that Cocoapods shares source code as well as assets with the integrator and then packages them in a framework on the integrators end. We saw the integrator then compiles that code as part of their app build process. But what if we don’t want to share the code? Or maybe we would like to save time from compiling large chunks of code from our apps that are shared and that rarely changes. Is there a way to shared compiled frameworks via Cocoapods?

Onfido Tech

Stories from Design, Engineering, Product and Research at Onfido

Anurag Ajwani

Written by

iOS Engineer @ Onfido

Onfido Tech

Stories from Design, Engineering, Product and Research at Onfido