Create a Swift package to promote modularity and code reuse across your apps.
- Swift Package Manager
As you develop your app, you may discover parts of your code are reusable in your other apps. Refactoring this code into a Swift package reduces code duplication between projects and fosters reuse, improving maintainability as your apps grow over time. Xcode compiles the source code in Swift packages to match the app’s requirements in terms of SDK, architectures, and so on. It can compile packages for multiple platforms in the same build operation, removing the need to create a separate framework target for each platform.
Once you’ve organized your reusable code into a Swift package, you can decide whether to use it locally in a project, or publish it to a private Git repository. To take the idea of sharing code even further, you can become a part of the open source community and make your Swift package available to a global audience. To learn more about publishing a Swift Package, read Publishing a Swift Package with Xcode.
Create a Swift Package
A common use case for Swift packages involves adopting them for your existing shared component. To turn your existing component into a Swift package, you don’t need to create a new Swift package from scratch. Instead, keep your existing project and add a
README and a
Package file inside the root directory of your library project to turn your library into a Swift package.
Use the sample
Package file below to get started and configure the Swift package to use your existing project structure. The amount of configuration depends on your shared component; you can configure minimum deployment targets, package targets, products, and the paths to your source and test files.
If you aren’t turning your existing shared component into a Swift package, you need to create a standalone Swift package. To create a new Swift package, open Xcode and select File > New > Swift Package. Choose a name and select a file location. Select “Create Git repository on my Mac” to put your package under version control. On completion, the Swift package opens in Xcode and looks very similar to a regular Xcode project.
Xcode generates all necessary files and folders as it creates a Swift package:
READMEfile resides at the root level of the package. It describes the functionality of your package.
Packagefile, or package manifest, describes the configuration for the Swift package. You can double-click it in Finder to open the package in Xcode. The manifest file uses Swift and API from the Swift Package Manager’s
Packagelibrary. It defines the package’s name, products, targets, and dependencies on other packages.
Source files reside in a folder named
Sources. A Swift package can contain several targets and, as a convention, each target’s code resides in its own subfolder.
Unit test targets reside in a folder named
Tests, and, following the same convention as regular targets, each test target’s code resides in its own subfolder.
Configure Your Swift Package
Swift packages don’t use
.xcworkspace but rely on the folder structure and use the
Package file for additional configuration. The following code listing shows a simple package manifest:
Package file needs to begin with the string
// swift-tools-version:, followed by a version number such as
The Swift tools version declares:
The version of the PackageDescription library
The minimum version of the Swift tools and Swift language compatibility version to process the manifest
The required minimum version of the Swift tools to use the package
Each version of Swift can introduce updates to the PackageDescription library, but the previous API version is available to packages which declare a prior tools version. This behavior allows you take advantage of new releases of Swift, the Swift tools, and the PackageDescription framework, without having to update your package manifest, or losing access to existing packages.
To learn more about the PackageDescription API, read the documentation for the
Add Your Code
To add source files to a Swift package, you can use workflows that you already know. For example, you can add a source file to a package by dragging it into the Project navigator, or by using the File > Add Files to [packageName] menu.
Make Your Swift Package Cross-Platform Compatible
While Swift packages are platform-independent by nature and include Linux as a target platform, your Swift packages can be platform-specific. Use conditional compilation blocks to handle platform-specific code and achieve cross-platform compatibility. The following example shows how to use conditional compilation blocks:
In addition, you may need to define a minimum deployment target. Note how the package manifest below declares minimum deployment targets by passing them in as a value to the
platforms parameter of the
package initializer. However, passing minimum deployment targets to the initializer doesn’t restrict the package to the listed platforms.
Build Your Targets and Run Unit Tests
Xcode creates a scheme for each product in the Swift package’s manifest file. If your package contains multiple products, Xcode creates an additional scheme with the name
Select a scheme for the package’s build-and-run destination, and build it as you’d build an app target. Each source target usually has at least one corresponding test target.
Leverage the Package's Functionality Locally
To use your package locally, open your Xcode project or workspace. Drag and drop your Swift package’s folder into the Project navigator to add the package to your project. In your target’s Settings, select the General pane, scroll to the “Frameworks, Libraries, and Embedded Content” section, and click the + button. As your package manifest declares a library product, you can select the Swift package’s library product to link it, just like any other library or framework.
In your app’s code, you can now import the package’s targets as Swift modules and use their functionality in your app. For example, the package manifest above defines a target
Shared that a developer can import as a Swift module by declaring
Organize Your Code with Swift Packages
You can organize a larger code-base into Swift packages, instead of using a project setup that uses subprojects or Git submodules.
Create a Swift package as part of your Xcode workspace by selecting File > New > Swift Package.
Choose a project and a group, but don’t create a new Git repository if you app is already under version control and create the new Swift package.
Move your code into the new package in the Project navigator.
Open your app’s project settings, select your app target, and navigate to its General pane.
Click the + button in the “Frameworks, Libraries, and Embedded Content” section and select the local package’s library to link it into your app target.