Distribute Framework With CocoaPods Locally and Remotely

CocoaPods

In this tutorial our focus is to create a framework and then use in our application locally and remotely.

A framework is a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, nib files, image files, localized strings, header files, and reference documentation in a single package. Multiple applications can use all of these resources simultaneously. The system loads them into memory as needed and shares the one copy of the resource among all applications whenever possible.

Benefits of Framework

  1. Code/Features modularization
  2. Sharing of code between multiple applications
  3. Sharing of resources between multiple applications
  4. Distribute it as a third party library
  5. Best for teams working parallely

Creating a Framework for iOS

From Xcode, choose File > New Project to create your project > On the Framework & Library section Select Cocoa Touch Framework > Click Next > Enter Product Name “MyFramework” as shown in Figure 1 > Click Next > Choose Location > Create

Framework has created as shown in Figure 2 with the name MyFramework

Figure 2

Framework responsibility is to fetch data from server and return to the consumer with the data. Let’s create a swift file From Xcode, choose File > File > Swift File > APIRequestLoader > Create

As shown in Figure 3 we completed our framework code. To consume this framework client needs to provide object that conform to APIRequest protocol where it implement the make and parseResponse method with the expected Request and Response Data Type.

Build the framework project to make sure that you get Build Succeeded with no build warnings or errors.

Figure 3

At this point we created framework. Now create a consumer project.

Choose File > New > Project > In Application section, select Single View Application and then click Next > In the dialog that appears Product Name: Consumer > Next > Create .
As shown in Figure 4 we created a consumer application that will consume our framework service.

Figure 4

Consume Framework Using Drag And Drop

Go to the MyFramework project > Right Click on MyFramework.framework under the Products folder > Click on Show in Finder . This will redirect the location of the framework

Figure 5

Now open Consumer app and drag and drop framework to the project . Make sure to check Copy items if needed so that the files actually copy into the new project instead of just adding a reference as shown in Figure 6

Figure 6

As shown in Figure 7 after drop the framework into project. It added to the Linked Frameworks and Libraries section. Remove it from this section by selecting the framework and tap minus sign

Figure 7

Now tap on plus sign on Embedded Binaries and add framework as shown in Figure 8

Figure 8

As shown in Figure 9 MyFramework.framework now added. Adding framework on the Embedded Binaries section will add it to the Linked Frameworks and Libraries section as well

Figure 9

As shown in Figure 10 we consumed our framework by doing following steps

  1. First we import MyFramework. We can’t access Framework api without importing it as we do to access Foundation API
  2. We used APIRequestLoader class api in the framework with the data needed by the framework. It will perform network call and decode data in the model (MyGitHub) as provided when initializing the class.
Figure 10

Consume Framework Using Local CocoaPods

CocoaPods is a popular dependency manager for iOS projects. It’s a tool for managing and versioning dependencies.

First install the cocoapods by follow the instruction in the link

If you’re just jumping in, you can download the projects. The repo contains both Framework(MyFramework) project and Consumer app project(Consumer_Part1_Starter).

Open to the downloaded project folder as shown in Figure 11

Figure 11

Open terminal and go to the root of the MyFramework folder as shown in Figure 12 and run the following command


pod spec create MyFramework
Figure 12

MyFramework.podspec should created. Open file in any text editor. Replace it with the code as shown in Figure 13 and save it.

A pod specification describes a version of Pod library. It includes details about where the source should be fetched from, what files to use, the build settings to apply, and other general metadata such as its name, version, and description.

name → The name of the Pod

version → The version of the Pod

platform → A specification should indicate the platform and the correspondent deployment targets on which the library is supported.

source → The location from where the library should be retrieved.

Figure 13

At this point our framework now configured. Now open Consumer app project and delete the framework we added in previous section. Right click on the framework > Select Delete > Move to Trash as shown in Figure 14. Build the project you will see the error No such module ‘MyFramework’. In the next step we will fix this by installing our framework locally using pods

Figure 14

Open terminal and do to the root folder of Consumer app and run following code. This will create a Podfile as shown in Figure 15. Follow this tutorial if you never worked with pod

pod init

The Podfile is a specification that describes the dependencies of the targets of one or more Xcode projects

Figure 15

Replace the podfile code with the following as shown in Figure 16. In this file we are saying that Consumer app needs MyFramework as a dependency for this project and we gave local path where to find the dependency.

Figure 16

Open terminal > Go to the root folder of Consumer app (Same level in which podfile was created) > Run the following command as shown in Figure 17

pod install

At this point our dependency which is MyFramework now configured. First close the Consumer app and open Consumer.xcworkspace. Run the project and now our application will work without any error.

With this command, you’re searching the CocoaPods repository and downloading any new or updated pods that match the Podfile criteria. It also resolves any dependencies, updates the Xcode project files so it knows how to build and link the pods, and performs any other required configuration.

Figure 17

As shown in Figure 18, our dependency now added you can see the source code as well and framework extension file

Figure 18

At this point we setup local repository of our framework. Now open MyFramework project and add new method which will return hard coded data as shown in Figure 19. Build MyFramework you will see the Build Succeeded

Figure 19

Open Consumer.xcworkspace. You will see the you can access this method now as shown in Figure 20

Figure 20

Distribute Framework Using Remote Repository

This section walks you through publishing your pod to GitHub and using it like a third party framework.

Created MyFramework repository on github as shown in Figure 21

Figure 21

Clone the project to some empty folder

Figure 22

Move the MyFramework project contents into the clone repository folder

Figure 23

Before commit and push the code. First replace the MyFramework.podspec code with the following. We replace source url from local to remote. Now we are telling podspec the location from where the library should be retrieved as shown in Figure 24

Figure 24

As shown in Figure 25 we pushed the code to the repository we created

Figure 25

We pushed the tag as shown in Figure 26 and 27. As we specified in MyFramework.podspec.

Figure 26
Figure 27

Open the Consumer app podfile and replace the pod (dependency) url from local to remote.

Figure 28

Open terminal and go to the root folder of Consumer app directory and run the following code

pod update

Now as shown in Figure 29 it is fetching from remote git repo with the tag specified in podfile

Figure 29

Useful links

https://www.raywenderlich.com/5109-creating-a-framework-for-ios

https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WhatAreFrameworks.html

https://en.wikipedia.org/wiki/Convention_over_configuration

https://guides.cocoapods.org/syntax/podspec.html

Next

In the next part we will see how to configure cocoapods for the library that requires other library as a dependency

Senior iOS Engineer | HungerStation | Delivery Hero