Welcome to Innominds Blog
Enjoy our insights and engage with us!

A New Approach to Managing Dependencies in iOS Development with Swift Package Manager

By Krishna Prakash Narasannagari,

Swift Package Manager (SPM) is a tool for managing the distribution of Swift code. It is integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. SPM provides a convention-based system for building libraries & executables, and sharing code across different packages.

 

Versions Supported: Swift 3.0 and above

There are many ways to add 3rd party libraries into the application. The following are the best ways to integrate 3rd party libraries:

  1. CocoaPods
  2. Carthage
  3. Swift Package Manager
 

1. CocoaPods

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 30,000 libraries and is used in over 1.9 million apps. CocoaPods can help you scale your projects elegantly. More details can be found at http://cocoapods.org

CocoaPods focuses on source-based distribution of third-party code and automatic integration into Xcode projects.

 
Platforms Supported

All Apple platforms, iOS, tvOS, watchOS, and macOS support CocoaPods dependencies. CocoaPods command line tool only works on a Mac.

CocoaPods also provides a central place where third party libraries can be found. This improves discoverability of open source libraries that can be used in projects. With CocoaPods, updating your dependencies is easily done with the ‘pod update command.’

 

Advantages

  1. CocoaPods make managing dependencies in your code easier
  2. Adding and removing dependencies is just a matter of defining them in a file and running a command to install them
  3. CocoaPods reads the file, determines the dependencies that the listed libraries have, and whether there are any shared dependencies or not
  4. We can search any kind of dependency in CocoaPods official website
  5. CocoaPods supports both dynamic and static libraries
  6. We can easily tell anyone what dependencies we are using in the app
  7. It's easy to check if a new version of a dependency is available by using the ‘pod outdated’ command
  8. Lots of contributors with well-grown community
 

Disadvantages

  1. Installation process will take more time to install CocoaPods
  2. With CocoaPods built on RUBY, it is paramount to have its knowledge, if one wants to understand CocoaPods internal implementation.
  3. Every time you build your project, all your dependencies will also be built, which leads to slower build times
  4. CocoaPods creates new workspace directory, which has xcworkspace extension. We have to use Xcode workspace in order to make CocoaPods work
  5. CocoaPods added some scripts in the build phases of our target
  6. Linked the Pods Frameworks to “Link Binaries with Libraries
  7. CocoaPods takes controls of entire Xcode project and if something fails, entire project stops building
  8. Breakpoints doesn’t work properly on the added libraries source code
  9. As CocoaPods has a centralised repository for all packages and in case of its service being down, a project cannot be built without committing the codes along the pods. 
  10. CI/CD integration with server is hard as we have to install and manage Ruby libraries
 

How to Install CocoaPods?

  1. Open terminal and execute below command
       $ sudo gem install cocoapods
  2. Create a Xcode project. Open the project path in the terminal
       $ cd Projectpath
  3. Enter init command
       $ pod init
  4. Open the pod file in the project folder in any text editor. Add any pod name in the Pod file.
            Example: pod 'Alamofire', '~> 3.3'
    Install CocoaPods
  5. Now, open the terminal in same project path and execute below mentioned command
             $ pod install

    It will create new xcworkspace in the project folder. To continue with the project, instead of projectName.xcodeproj, we will use the projectName.xcworkspace. 

    Now, the pod setup is completed.

    If you want to use added library in view controller, just import it.

    Example: import Alamofire

 

2. Carthage

We can install Carthage by using HomeBrew or we can download the .pkg from Github and install it manually.

Git URL: https://github.com/Carthage/Carthage/releases

 

Platforms Supported

All Apple platforms, iOS, tvOS, watchOS, and macOS support Carthage dependencies. Carthage command line tool only works on a Mac.

 

Integration Steps

  1. Open terminal and execute the below mentioned command
          $ brew install carthage
  2. Subsequently, in order to integrate a dependency using Carthage, you have to create a Cartfile in your project root folder.
           Adding Cartfile:
           Open terminal and execute the following command
           $ touch Cartfile.
           Now, Cartfile is created.
           Convert it into executable file.
           $ chmod +x [YourDirectory/Cartfile]
  3. Open Cartfile with text editor and add the following line
           github "Alamofire/Alamofire"
  4. Open the terminal and run the following command
           $ carthage update
    It creates a Carthage folder in your project root folder. It also creates Build folder in the app with all the platforms. For example, Alamofire, a framework that supports all Apple platforms, is equipped with iOS, Mac, tvOS, and watchOS folders.
    If you want to only build dependencies for a specified platform, run below command, which will build dependencies for iOS platform.
           $ carthage update --platform iOS.
  5. Drag the built.framework binaries from Carthage/Build/<platform> into your application’s Xcode project.
  6. On your application targets’ Build Phases settings tab, click the + icon and choose New Run Script Phase. Create a Run Script in which you specify your shell (ex: /bin/sh), add the following contents to the script area below the shell:
           $ /usr/local/bin/carthage copy-frameworks
  7. Add the paths to the frameworks you want to use under “Input Files". For example:
           $(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
  8. Add the paths to the copied frameworks to the “Output Files”. For example:
           $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Alamofire.framework
 

Advantages

  1. Carthage is purely written in Swift so that iOS developers can understand the technology behind Carthage
  2. Supports both Dynamic Frameworks and Static Libraries
  3. Carthage won’t touch your Xcode settings or project files. It downloads and builds dependencies
  4. Carthage can be easily integrated with Continuous Integration server
 

Disadvantages

  1. Not every framework supports Carthage
  2. Carthage has too many manual steps that need to be performed during setup

3. Swift Package Manager

Apple developed its own package manager, which is fast and robust. So, it’s time to migrate all our team members from CocoaPods and Carthage to SPM.

You can install SPM in two different ways. Xcode < 11 or Xcode > = 11.

In Xcode <11, you need to run the command to add Swift package.

Steps to add package:
      $ mkdir TodoKit
      $ cd TodoKit 
      $ swift package init
But in Xcode 11, we can also perform the above setup using the File > New > Swift Package menu.

Adding Package Dependencies to Your App with Xcode 11

You can add package dependency into the application in two simple ways in Xcode 11.

  1. Adding package dependency from File menu
    • Open Project File -> Swift packages -> Add package dependency
      CocoaPods is a dependency manager for Swift
    • Add Repository URL and click on Next
      Carthage & Swift Package Manager
    • Choose your Version, Brach or Commit ID from the options to download specific repository. Later, click on Next
      Swift Packages in iOS with Example
    • In the final step, it asks for product and targets. Select products or targets if you have multiple product and targets. Then, click on ‘Finish.’
      Building Swift Package
  2. Using Build Phases
    • Open Build Phases - > Link Binary and Libraries -> Click on (+)
      Creating Swift Package
    • Select Add Other and choose Add Package Dependency. Then, add your Repository URL and do the same process as mentioned above.

      After successfully adding the dependency into the project, the structure looks like the below image.

      Developing Swift Package Manager in iOS
    • Use package dependency into your application by importing.
             Ex: import Alamofire
 

How to Remove Swift Package Dependency from App

  • Select Project -> Swift Packages
    Creating and Building Swift Package with Xcode
  • Select your swift package, then click on (-). It will remove swift package from your application.
 

Creating and Building Swift Package with Xcode 11

One of the most exciting new features in Xcode 11 is that the SPM is within Apple’s IDE. Xcode 11 offers complete support for creating and editing package.

  • Open File -> New -> Swift Package
    Swift Package Dependency
  • Name the package and save it in a safe place.
  • Swift package contains below files:
    1. Read.md
    2. Package.swift
    3. Sources
    4. Tests
  • Package.swift: This is the manifest of your library. You can add your dependencies into this file.
    Swift Packages in iOS CocoaPods
  • Sources: Add your classes into the sources folder. The folder name in Sources is always matched with the products -> .library -> targets in package.swift file. You can add multiple folder names in targets.
  • Tests: You can write all the test cases related to your library in this folder.
 

Building App with Swift Package Manager

Here, I am explaining ways to build your own Swift Package Manager with an example. I am creating s SPM for validations.

  • Let’s create a sample app.
    Carthage Swift Package Manager
  • Add swift package into the sample app. File - > New -> Swift Package
    iOS Development with SPM
  • Name your library and select your project name for Add to: and Group to: then click on create.
    Swift Package Manager
  • Created Validations.swift file and added email validation in the swift file.
     Swift Package for iOS developers
  • I want to move validation file into my SPM. So, I removed KPLibrary.swift file in SPM and dragged and dropped the Validations.swift file into KPLibrary folder.
     CocoaPods and Carthage to SPM
  • Add the KPLibrary into ‘Link Binary With Libraries’ in the sample app.
    App validations with
    Swift Package Manager
  • Import your library in the project and use it.
    Swift Packages
 

Unit Test Cases

You can write unit test cases for your package in test folder.

  • Click on the project name and select your library
    Swift Package with Xcode
  • Write the test cases for your library and run the test cases
    Swift package files
  • That’s all. You built your own package manager. If you want to keep this library into the git, just drag and drop your library package manager into the desktop and commit it into the git. By using git URL, you can add it to any projects.
 

Advantages

  1. SPM works on both Mac and Linux platforms
  2. SPM is built by Apple
  3. We can easily say what dependencies we are using in the app
  4. SPM will not compile all the dependencies every time. Hence, compile time will reduce.
  5. If a package is depending on another package, SPM automatically handles it
 

Disadvantages

  1. At this point of time, SPM doesn’t support all third-party libraries
  2. Need to concentrate on maintaining specific target structure in manifest file

Metrics

I created three sample empty applications and added Alamofire with pods, Carthage and SPM. Below are the metrics on my system with Mac OS (10.15) and Xcode 11.0 (beta). These values may vary from system to system.

Metric Type

Pods

Carthage

SPM

Source code size

133Kb

160Kb

30Kb

ipa size

550Kb

550Kb

512Kb

App launch time after clean (might vary based on RAM and memory

14-18 sec

14-18 sec

12-14 sec

 

Conclusion

With Swift Package Manager, your code is not only better but also officially supported by Apple. As far as future projects are concerned, it makes sense to start with it and move the existing dependency managers to SPM as and when opportunities arise.

 

About Innominds

Innominds is a leading Digital Transformation and Product Engineering company headquartered in San Jose, CA. It offers co-creation services to enterprises for building solutions utilising digital technologies focused on Devices, Apps, and Analytics. Innominds builds better outcomes securely for its clients through reliable advanced technologies like IoT, Blockchain, Big Data, Artificial Intelligence, DevOps and Enterprise Mobility among others. From idea to commercialisation, we strive to build convergent solutions that help our clients grow their business and realise their market vision.

To know more about our offerings, please write to marketing@innominds.com

Topics: Mobility

Krishna Prakash Narasannagari

Krishna Prakash Narasannagari

Krishna Prakash Narasannagari - Principal Engineer - Software Engineering

Subscribe to Email Updates

Authors

Show More

Recent Posts