The Swift Package Manager has come a long way and support for Xcode improves with every release of Apple's IDE. Even though there are several third party solutions for managing the dependencies of a project, CocoaPods and Carthage being the most popular, the Swift Package Manager has become a viable option in recent years. In this episode, I show you how to add a Swift package to a project in Xcode.
Ease of Use
Because Xcode has built-in support for the Swift Package Manager, SPM for short, it has become more appealing to use the Swift Package Manager to manage the dependencies of your project. As of Swift 5.5, the Swift Package Manager supports package collections to make it straightforward to discover and use packages.
Creating a Project in Xcode
I want to show you how easy it is to add a Swift package to a project. Let's first create a project in Xcode by choosing the App template from the iOS > Application section. Give the project a name and check the Include Tests checkbox at the bottom. Tell Xcode where you would like to store the project on your machine and hit the Create button.
One of my favorite libraries is RxSwift. Up until recently, I added RxSwift to a project using CocoaPods. Even though CocoaPods is very easy to use, adding dependencies to a project using the Swift Package Manager has become the easier option thanks to Xcode's improved support for the SPM. An added bonus is that you no longer rely on a third party dependency manager. Although I have to say that CocoaPods served me very well in the past and it still does for a number of projects.
Select the project in the Project Navigator on the right. Select the project in the Project section and click the Package Dependencies tab at the top.
Adding a Swift Package in Xcode
The Package Dependencies tab shows you an overview of the Swift packages the project depends on. Click the + button at the bottom of the table to add a Swift package using the Swift Package Manager.
This may seem overwhelming at first, but it really isn't. On the left, you see the package collections the Swift Package Manager knows about as well as Swift packages you recently used. Because you haven't used any Swift packages just yet, the latter section is missing for now. The Apple Swift Packages package collection is available by default. It is a nice example of what package collections are and the benefits they offer. As the name suggests, the Apple Swift Packages package collection is managed and maintained by Apple.
The easiest option to add a Swift package is by entering the package URL in the search field in the top right. The package URL is the location where the Swift Package Manager can find the Package.swift file of the package, that is, the manifest of the package. For RxSwift, that simply means adding the GitHub URL.
A few things happen when you enter the GitHub URL of the RxSwift repository. The Swift Package Manager fetches the Package.swift file of the repository, parses it, and displays the package details. Notice that the Recently Used section on the left is now visible. This is convenient if you use a package often.
Before we click the Add Package button, we need to check the configuration of the dependency. We can define which version we want to use and what happens if we update the Swift package. In this example, we tell the Swift Package Manager that we want to use version 6.0.0 or later, excluding major versions. This is important since a major version usually introduces breaking changes. We can also define which project we want to add the dependency to. In this example, there is only one option to choose from.
Click the Add Package button to add the Swift package to the project. The next step is defining which package products we want to add and to which targets we want to add them. Most Swift packages have a single package product, but RxSwift is a bit more complex.
For this project, we add RxSwift, RxCocoa, and RxRelay to the Cocoacasts target. RxTest and RxBlocking are libraries that facilitate unit testing. We add them to the CocoacastsTests target. This is what that looks like.
Click Add Package to add the Swift package to the project. Xcode automatically fetches the Swift package and adds the package products to the targets. Notice that the Package Dependencies tab is updated, showing RxSwift as a dependency of the project.
The RxSwift package is also listed in the Project Navigator on the left in the Package Dependencies section.
To verify that the RxSwift package was successfully added to the project, we should use it in the project. Open ViewController.swift and add an import statement for RxSwift and RxCocoa at the top.
Let's declare an outlet for a text field and a dispose bag. In the viewDidLoad()
method of the view controller, we subscribe to the text
observable of the text field. Build and run the application. If the compiler doesn't throw an error, then you successfully added RxSwift and RxCocoa as dependencies using the Swift Package Manager.
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
// MARK: - Properties
@IBOutlet private var textField: UITextField!
// MARK: -
private let disposeBag = DisposeBag()
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
textField.rx.text
.subscribe(onNext: { text in
print(text)
}).disposed(by: disposeBag)
}
}
Removing a Swift Package in Xcode
Removing a Swift package couldn't be easier. Select the project in the Project Navigator on the right. Select the project in the Project section and click the Package Dependencies tab at the top. To remove RxSwift, select it from the list of packages and click the - button at the bottom of the table. Removing a Swift package in Xcode is as simple as that.
If you try to build the target without making any changes, the compiler throws an error since RxSwift and RxCocoa are no longer dependencies of the Cocoacasts target.
What's Next?
The Swift Package Manager is nicely integrated into Xcode, making it straightforward for developers to use the SPM to manage the dependencies of a project. You may have noticed that, unlike other projects, there is no Package.swift file at the root of the project. Xcode manages that for you. I'm not sure that is a good thing, but that is how it is for now.