February 22, 2020

Swift Package Manager Tutorial: How to add external libraries to iOS projects

With Xcode 11, the Swift Package Manager has been enhanced for use in iOS projects. Frameworks for iOS can now be created and integrated into Xcode projects. This makes the tool an alternative to Cocoapods and Carthage for managing the dependencies of an iOS project.

The following tutorial shows how to use the Swift Package Manager by adding the 3rd party library Kingfisher for asynchronous image loading to the project. This library already provides the metadata required for the Swift Package Manager, recognizable by the file Package.swift in the root folder of the project.

  1. Download the starter project for the sample project Countries. This contains the basic structure for an app that displays images in a UITableViewController:

  2. Open the Kingfisher project page and copy the clone URL of the project:

    Clone-URL von Kingfisher kopieren
  3. In Xcode use File » Swift Packages » Add Package Dependency… to add a new dependency:

    Xcode: Add Package Dependency
  4. Specify the clone URL of the Kingfisher library:

    File » Swift Packages » Add Package Dependency…
  5. Leave the default version settings - the library will be updated until the next major release:

    Xcode Package Options
  6. Only add the Kingfisher product to the app target (Kingfisher also includes an optional integration for SwiftUI)

    Xcode Add Package
  7. The library will be set up in the project and appear in the Project Navigator:

    Xcode Swift Package Dependencies
  8. Have a look at Swift Packages in the project settings. Here, the package configuration can be changed later:

    Swift Packages im Xcode-Projekt
  9. Use the library in the CountriesTableViewController: Import the Kingfisher module there and use the kf extension to start an image download asynchronously in the background:

    import UIKit
    import Kingfisher
    
    // …
    
    class CountriesTableViewController: UITableViewController {
    
        // …
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CountryCell", for: indexPath) as! CountryTableViewCell
            let country = self.countries[indexPath.row]
    
            cell.countryNameLabel.text = country.name
            let placeholder = UIImage(named: "placeholder")
    cell.countryImageView.kf.indicatorType = .activity
    cell.countryImageView.kf.setImage(with: country.landmark.imageUrl, placeholder: placeholder)
    
            return cell
        }
    
    }
    

Q & A

Where are the checked out modules stored?

In the Derived Data folder of Xcode:

What happens if the project is opened without the library having been downloaded?

The library will be automatically downloaded by Xcode:

What happens when a new version of the library is released?

The commit hash of the library is stored in the Xcode project under project.xcworkspace/xcshareddata/swiftpm/Package.resolved. This declaration is used to download the library. There is no automatic update but the version of the library is fixed to this state.

The dependency can be updated with File » Swift Packages » Update to Latest Package Versions.