iOSDev

Swift Dependency Management for iOS

Dependency/Package Manager

Most modern languages come with an official solution for code distribution. In today’s world of modern mobile development, it is essential to re-use the code already written by developers. Code reuse can be achieved by creating and distributing the packages from central repository. A package manager is a tool that simplifies the process of working with code from multiple sources. Typical Package Manager should have ability to do following things

  • Centralised hosting of packages and source code with public server with access to developers or contributors
  • Download the source code at the run time, so that we don’t need to include it in the repository.
  • Link the source code to our working repository by including source files.
  • Allow packages to be versioned

The examples of popular package managers are RubyGems for Ruby , Composer for PHP , NPM for NodeJS, CocoaPods for iOS

The basic usage of most package managers are mostly common,

  • Define the file with all required dependencies (Gemfile, composer.json, package.json, Podfile).
  • Download the dependencies with specific command ( gem/bundle install, composer install, npm install, pod install). This will create lock file with all the all the installed versions of the dependencies. e.g (Gemfile.lock, Composer.lock, Podfile.lock). This will also create a directory with downloaded source code at the specified location e.g (vendor/)
  • Update the dependencies for new version ( gem/bundle update, composer update, npm update, pod update). This will update lock files with new version.
  • Add required packaged by browsing packages on the hosting server.

The Swift dependency management for iOS does exactly same things but it has additional task of building the Xcode scheme. Apple has released it’s own package manager called Swift Package Manager to share and distribute Swift packages. It’s good to know that Apple is working on replacement of the current package managers in the iOS development world those are CocoaPods and Carthage. In this post we will cover popular Swift dependency managers. Those are CocoaPodsCarthage and Swift Package Manager. We will use SwiftyJSON which is very popular Swift library for parsing JSON as an example.

CocoaPods

CocoaPods comes as a Ruby library and need to be installed using RubyGem. CocoaPods is built with Ruby and is installable with the default Ruby available on OS X.

CocoaPods can be initialised with pod init  command which will create template  Podfile  but we can create our own simple   Podfile  will look like this

Now, we can download dependency using magical command

COCOPODS AND XCODE

The above command (pod install) is very magical which make lots of changes to our Xcode project under the hood. The most of the times, it’s really hard to understand that what has been changed. This might be the reason most developers hates CocoaPods. CocoaPods makes following changes to Xcode.

  • .xcworkspace file ( Another file on top of  .xcodeproj  to open project)
  • Podfile.lock (Locked versions of CocoaPods)
  • Pods directory (Directory Containing source code of the Pod dependencies)
  • Lots of things inside your Xcode Settings!

Now,we have to use  .xcworkspace  to open the project to import your dependencies otherwise CocoaPods won’t work.

COCOAPODS PROS AND CONS

The use of CocoaPods has following Pros and Cons

PROS
  • Easy to setup and use.
  • Automatically does all the Xcode setup for the project.
  • Well grown community and support.It has the largest community and is officially supported by almost every open-source iOS library.
CONS
  • It’s Ruby and we have to manage Ruby dependencies e.g Bundler, Gems etc etc
  • CocoaPods updating Xcode Projects and Files is like magic without understanding what’s changed
  • Centralised
  • Can’t work with framework and project at the same time because of two-step process for working on dependencies.

 

Carthage

Carthage is another simple dependency manager for the Cocoa application. It downloads and build the dependencies but will not change Project file Or Xcode project build setting like CocoaPods. We have to manually drag . framework’ binaries to   Linked Frameworks and Libraries .

We can install Carthage using HomeBrew

We are now ready to use Carthage. As above, we need to get SwiftyJSON using Carthage then we have create file called Cartfile  with following content.

Now that, we have specified our dependency in the Cartfile, Run

This will fetch dependencies into a Carthage/Checkouts folder, then build each one. Now everything CocoaPods does automatically as magic, we have do it manually.

On your application targets General settings tab, in the Linked Frameworks and Libraries section, drag and drop each framework you want to use from the Carthage/Build folder on disk. There are also some workaround for the App Store Submission bug, which you can read on Carthage README file. After doing this all manual work, we should be able to import dependencies.

CARTHAGE AND XCODE

Carthage won’t touch Xcode settings or Project files. Carthage being very simple and just checkout and build the dependencies and leave it to you to add the binaries to Xcode. It gives you full control of what we are adding to Xcode.

CARTHAGE PROS AND CONS

There are some pros and cons of the Carthage

PROS
  • Carthage won’t touch your Xcode settings or project files. It just download and build the dependencies so you have proper control on what you are doing.
  • Decentralised
  • Supports submodules
CONS
  • Unstable and Slow
  • Small Community, not many contributors
  • Lot of manual steps to perform on Xcode to get everything setup

Carthage is very simple Swift dependency manager but it involves lot of manual setup.

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

Swift Package Manager is not only package manager but also Build and Test tool. Swift Package Manager can also run on Linux as well as macOS. Swift Package Manager is

  • Command Line Based tool
  • Being Cross-Platform, Swift Package Manager doesn’t need Xcode to create package
  • It’s decentralised
  • Swift Package Manager is open-source and source code is available on Github

Create Swift Package

It’s very easy to create our basic Swift package.  Your default  Hello World Package is ready to publish if you execute following commands.

At this stage, we should have default Hello World package ready to publish on Github. In order o publish package, we need to push it to GitHub account. Assuming we have git setup. Replace username and package name with yours. Swift packages uses semantic versioning to version packages.

We have published our first Swift Package. The published package can be found on Github here.

Generate Xcode Project

  • Swift Package has command to generate Xcode project from the source code so that we can use Xcode for autocompletion etc etc

    This will create xcproj file to open project in Xcode.
  • Using Swift Packages

We can use existing Swift packages by creating package.swift file and specifying dependencies inside the file.  This file should look like this

We will download the SwiftyJSON dependency using fetch command.

Now that, we should have SwiftyJSON dependencies checked out inside Packages directory. We can use that dependency now in our project using

Swift Package Manager Pros and Cons

Swift package manager is very new tool and it has pros and cons

Pros

  • Swift Package Manager is  official Package Manager for Swift
  • Managed by Apple
  • Server side support

Cons

  • Swift Package Manage is very new tool and undergoing lot of changes
  • Swift Package Manager isn’t officially supported for all platforms.
  • Swift Package Manager only work for other Swift package or project following Swift Package Manager’s directory standards.

Conclusion

It’s very challenging to select a Swift dependency manager for iOS project as all of the package managers has it’s own pros and cons. Swift Package Manager will be definitely replace CocoaPods and Carthage in the future but meanwhile we have to use CocoaPods or Carthage.

  • Laks Gandikota

    Thank you of sharing your views. To be clear, at this time, SPM does not support iOS/MacOS projects. It just can built platform agnostic applications. Is my understanding correct?

    • Hi @laks_gandikota:disqus, Thanks for comment. I think you are right. I haven’t read anywhere that Swift Package Manager officially support iOS. Hopefully WWDC 2017 will have something good for us 🙂