The Swift Package Manager (SwiftPM) is Apple’s tool for managing package dependencies for Swift application development. SwiftPM has been an integrated part of Swift since v3.0.
So, what are Packages? Packages contain reusable code or other resources stored in repositories that your application needs to provide a feature or function. Some examples include, but are not limited to, the fonts and color scheme for your app, a library that provides access to a web resource, a file with images required by your application. Other examples are the APIs and Frameworks that add functionality to your app and simplify your coding tasks.
Let’s work together and breakdown a high-level overview of basic SwiftPM usage and its associated features.
What Do Package Managers Bring To The Table?
Package Managers give developers a way to control which packages and which versions of those packages that the project will consume.
Other features include:
- Allows easy use of light-weight, reusable libraries
- Reduces code duplication
- Supports development best practices by simplifying and supporting modular coding (easy module/package creation)
While it is possible to manually manage dependencies in a project, it isn’t practical for anything but the smallest of applications. Best practices fall on the side of using a package manager to handle this function automatically.
SwiftPM supports Swift 3+ and XCode 8+. Since Swift 5 and Xcode 11, SwiftPM has had cross-platform support for iOS, macOS, and tvOS.
Are There SwiftPM Alternatives?
There are two mainstream alternatives, CocoaPods and Carthage. Both are third-party tools requiring installation and much configuration before use.
CocoaPods
CocoaPods (2011) — Supports Swift 5+ and Xcode 3.11+ — Mature and stable. A centralized, easy-to-use command-line tool for package dependency management and integration into the application. CocoaPods is written in Ruby.
However, Cocoapods lacks direct control over project configuration and is basically a blackbox. CocoaPods also experiences random build failures that can’t be explained. Resolving these often involves removing and reinstalling CocoaPod dependencies from the project, clearing caches, and completely rebuilding the entire project. These steps can add a significant amount of time to the development process, especially on large projects.
Each CocoaPod dependency must have a “Podspec” file to define the metadata for that dependency. These files are typically uploaded to a different repository from the dependency itself. A “Podfile” within the app project will include a reference to this repository, and CocoaPods will use the information in this Podfile to fetch and install all of the dependencies for the app project.
Carthage
Carthage (2014) — A decentralized command-line tool for dependency management. Developers have full project control and must manually provide all package and dependency information. Carthage pulls the packages the developer specifies.Configuration requires much more manual work than CocoaPods and is somewhat complicated.
Using SwiftPM
SwiftPM has many advantages over Carthage and CocoaPods. Foremost, SwiftPM is a native Apple tool integrated into Swift. Other advantages include a quick and simple configuration, easier control over packages and their sub-dependencies, and a GUI built into Xcode for managing package configurations. Each package’s metadata is defined in a “Package.swift” file, which resides in the same repository as the package source files.
Package Resolution
With the Package dependencies configured in the SwiftPM GUI, Xcode will download the packages and resolve dependencies at build time with no further developer interaction.
When setting dependencies, you have the following options:
- By Version: Next Version, Up to next minor, Range, or a specific commit
- Branch (Specify)
- Commit(Specify)
Adding A Package To Your Project
- Swift Packages> Add Package Dependency
- On the “Choose Package Repository” dialog, enter the desired Repository.
- Click Next.
- On the “Choose Package Options” dialog, set the dependency rules (Versions, Branches, Commits).
- Click Next. Xcode now fetches the dependency.
- On the “Add Package to YourPrjName dialog,” ensure that the relevant packages are checked and the proper Target is selected in the Add to Target cell.
- Click Finish.
Your package now appears in the Navigator under Swift Package Dependencies. Note that SwiftPM can reference both local and remote packages.
Create A Module And Add A Local Package With SwiftPM
SwiftPM simplifies the process of modularizing your code and adding it as a package to a local or external repository. This section will briefly describe the process of creating a module and adding it to a local repository.
- Identify a self-contained portion of code or another resource that is suitable for use in a module.
- Create a new file: Files > New Package. Name the package accordingly and add it to your application using the same dialog.
- Copy the code or resource to the new file.
- Delete the existing code or resource from the app
- Add the new package to the Application Target. In “Application Project Settings,” add the new package under Frameworks and Libraries.
- In the Package code, define the platforms and versions where this Package works.
- In the Application’s code files, import the new package into every file where its code or where its resources are used.
If desired, you could upload the new Package to an external repository for use by developers outside your organization.
Additionally, SwiftPM will allow you to create and use binary packages. Binary packages permit developers to distribute libraries and frameworks without also distributing their source code.
Package Distribution
You can use SwiftPM to distribute resources, in addition to frameworks and libraries. SwiftPM also has built-in support for Apple’s DocC Documentation format, which makes it easy to build robust interactive documentation files and tutorials.
The Future
SwiftPM is a mature product still under active development to improve and add new features. Usage stats currently show it being about equal in popularity with CocoaPods. However, since SwiftPM is a native tool that requires no additional work to begin using, its future is more sure than that of CocoaPods or Carthage.
Happy coding!
To learn more about Swift Package Manager as well as its influence in mobile development and to experience Andrew Balmer’s full Lightning Talk session, watch here.