Swift Package Manager
Swift Package Manager, often shortened to SwiftPM, organizes code into reusable packages and downloads packages that other developers share. A package bundles source files, tests, and a description file. Xcode and the command line both understand packages.
Imagine a library where each shelf holds ready-made parts for your project. You list the parts you need, and the library delivers the correct versions. SwiftPM acts as that librarian for your code.
Diagram: Package Layout
Greeter/
+-- Package.swift (the recipe)
+-- Sources/
| +-- GreeterKit/
| +-- Greeter.swift (your code)
+-- Tests/
+-- GreeterKitTests/
+-- GreeterTests.swiftKey Terms
- A package is a folder of code with a
Package.swiftfile. - A target is one buildable unit inside the package, such as a library or a test group.
- A product is what the package offers to others, such as a library or an executable.
- A dependency is another package that your package needs.
Creating a Package
Run these commands in a terminal to start a command-line program.
mkdir Greeter
cd Greeter
swift package init --type executable
swift build
swift runThe init command creates the folder layout. The build command compiles the code, and run starts the program. Use --type library to create a reusable library.
Reading Package.swift
The manifest file is itself Swift code. It describes the package in a clear, structured way.
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "Greeter",
platforms: [.macOS(.v13)],
products: [
.library(name: "GreeterKit", targets: ["GreeterKit"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-algorithms",
from: "1.2.0")
],
targets: [
.target(
name: "GreeterKit",
dependencies: [
.product(name: "Algorithms", package: "swift-algorithms")
]
),
.testTarget(
name: "GreeterKitTests",
dependencies: ["GreeterKit"]
)
]
)The opening comment line states the lowest SwiftPM version the file needs. The dependencies list names outside packages, and each target lists the products it uses.
Version Rules
Packages use semantic versioning with three numbers: major, minor, and patch, as in 1.2.0. A major change may break old code. A minor change adds features safely. A patch change fixes bugs.
.package(url: "...", from: "1.2.0") // 1.2.0 up to below 2.0.0
.package(url: "...", exact: "1.2.0") // only 1.2.0
.package(url: "...", "1.2.0"..<"1.5.0") // inside a rangeThe from rule fits most projects. SwiftPM picks the newest compatible version and records the exact choice in a file named Package.resolved. Teammates build with identical versions.
Adding a Package in Xcode
- Open the project and choose File and Add Package Dependencies.
- Paste the package address into the search field.
- Pick a version rule and press Add Package.
- Choose the target that will use the package.
Use the package in code with an import line.
import Algorithms
let letters = ["a", "b", "c"]
for pair in letters.uniquePermutations(ofCount: 2) {
print(pair)
}Everyday Commands
swift build compile the package
swift run build and run an executable
swift test run every test
swift package update fetch newer allowed versions
swift package resolve download the recorded versionsChoosing Packages Wisely
Every dependency adds code you do not control. Check the package license, the date of the latest update, and the number of open issues. Prefer small packages with a clear purpose and active maintenance.
Common Mistakes
Choosing a version rule that is too loose lets a surprise update change behavior. Commit the Package.resolved file to version control to guarantee that every teammate builds with the same versions.
Mixing up targets and products causes confusion for newcomers. A target is a unit of code inside your package. A product is the item that other projects can import.
Real-World Use
Teams split large apps into local packages such as networking, design components, and data models. Each package builds and tests on its own, and builds finish faster. Open-source libraries for images, charts, and networking arrive through the same mechanism.
Key Takeaways
- SwiftPM organizes code into packages with targets and products.
Package.swiftdescribes the package in Swift code.- Semantic versions control which updates your project accepts.
- Xcode and the terminal both add, build, and test packages.
