SPM (Swift Package Manager) — vestavěný správce balíčků ekosystému Swift, vyvinutý společností Apple pro automatizaci připojování, sestavování a aktualizace knihoven třetích stran. SPM je součástí kompilátoru Swift od verze 3.0 (2016) a nevyžaduje samostatnou instalaci. Na rozdíl od CocoaPods a Carthage je SPM integrován přímo s kompilátorem a Xcode, což z něj činí standardní nástroj pro správu závislostí v moderních projektech Swift. V článku si rozebereme strukturu Package.swift, příkazy SPM, psaní vlastních balíčků a migraci z alternativních správců.
Hlavní body
SPM (Swift Package Manager) — oficiální správce balíčků pro jazyk Swift, vestavěný do kompilátoru swiftc a vývojového prostředí Xcode. Umožňuje vývojářům připojovat knihovny třetích stran, spravovat jejich verze a publikovat vlastní balíčky. SPM se poprvé objevil ve Swift 3.0 (září 2016) jako nástroj příkazového řádku a od Xcode 11 (2019) získal plnou integraci s grafickým rozhraním — nyní se závislosti přidávají přes menu File → Add Packages.
SPM automaticky stahuje zdrojový kód závislostí z Git repozitářů, sestavuje je paralelně s hlavním projektem a ukládá výsledky do mezipaměti, aby bylo opakované sestavování rychlejší. Na rozdíl od CocoaPods, SPM negeneruje samostatný pracovní prostor (xcworkspace) — závislosti se stávají součástí hlavního projektu Xcode. Podle průzkumu Swift.org Developer Survey (2024) používá SPM 67 % vývojářů iOS, což z něj činí nejoblíbenější nástroj pro správu závislostí v ekosystému Swift.
SPM podporuje tři platformy: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) a serverový Swift (Vapor, Kitura). Na Linuxu SPM funguje zcela přes příkazový řádek bez Xcode.
SPM je postaven kolem tří klíčových konceptů: balíčky (packages), produkty (products) a cíle (targets). Balíček je Git repozitář s manifestem Package.swift. Produkt je výsledek sestavení (knihovna nebo spustitelný soubor). Cíl je modul v rámci balíčku, který se kompiluje do jednotky sestavení.
Když vývojář přidá závislost do Package.swift, SPM provede následující kroky:
~Library/Caches/org.swift.swiftpm/.Soubor Package.resolved fixuje přesné verze všech závislostí, aby vývojářský tým pracoval s identickou sadou knihoven. Tento soubor by měl být přidán do systému správy verzí (git).
Klíčovou výhodou SPM oproti alternativám je absence centralizovaného registru. Balíčky mohou být v libovolném veřejném Git repozitáři: GitHub, GitLab, Bitbucket, a také na vlastních Git serverech společnosti. Od verze Swift 5.2 SPM podporuje binární závislosti (binary targets) — uzavřené knihovny distribuované prostřednictvím XCFramework bez poskytnutí zdrojového kódu.
Package.swift — je Swift soubor, který popisuje strukturu balíčku a jeho závislosti. Soubor je psán v samotném Swiftu (ne JSON, ne YAML), což umožňuje použití podmíněné logiky, vypočítávaných konstant a funkcí uvnitř manifestu.
Základní struktura Package.swift:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [
.iOS(.v16),
.macOS(.v13)
],
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
.package(url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"),
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
"Alamofire",
"Kingfisher"
]
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]
),
]
)
Pojďme si rozebrat klíčové prvky:
// swift-tools-version: 5.9 — direktiva udávající verzi SPM; od ní závisí dostupná syntaxe manifestu.name — název balíčku zobrazený v Xcode a používaný v odkazech závislostí.platforms — minimální verze platforem; SPM nedovolí sestavit balíček na starší verzi OS.products — co balíček „exportuje": knihovnu (.library) nebo spustitelný soubor (.executable).dependencies — seznam externích balíčků s URL a verzí; podporovány jsou from:, exact:, branch:, revision:.targets — cíle sestavení; každý cíl obsahuje seznam závislostí, zdrojů a swift souborů z příslušného adresáře (Sources/TargetName/).Příklad uvedení přesné verze, větve a commitu:
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git",
exact: "1.17.3"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",
branch: "main"),
.package(url: "https://github.com/apple/swift-log.git",
revision: "e5c6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4"),
]
Od verze Swift 5.9 byla do Package.swift přidána podpora pro static/framework a linkerSettings, což umožňuje přesnější konfiguraci linkování pro statické a dynamické knihovny.
Swift Package Manager poskytuje sadu příkazů pro práci přes terminál. Příkazy se spouštějí z kořenového adresáře balíčku (kde leží Package.swift).
# Vytvořit nový balíček s knihovnou
swift package init --type library
# Vytvořit spustitelný balíček (konzolová aplikace)
swift package init --type executable
# Sestavit projekt
swift build
# Sestavit v release konfiguraci
swift build -c release
# Spustit testy
swift test
# Spustit konkrétní test
swift test --filter "MyLibraryTests/testExample"
# Stáhnout a vyřešit závislosti
swift package resolve
# Aktualizovat závislosti na nejnovější dostupné verze
swift package update
# Zobrazit graf závislostí
swift package show-dependencies
# Vyčistit mezipaměť sestavení
swift package clean
# Vygenerovat Xcode projekt (před Xcode 11)
swift package generate-xcodeproj
Při práci v Xcode se většina těchto příkazů provádí automaticky: závislosti se řeší při otevření projektu, sestavení se spouští pomocí ⌘B, testy pomocí ⌘U. Znalost terminálových příkazů je však nezbytná pro CI/CD pipeline (GitHub Actions, GitLab CI, Jenkins), kde Xcode není k dispozici.
Příkaz swift package resolve vytváří nebo aktualizuje soubor Package.resolved. Tento soubor fixuje přesné verze všech závislostí, včetně tranzitivních, a měl by být přidán do gitu. Doporučuje se spouštět swift package update před každou novou feature větví, aby se pracovalo s aktuálními verzemi knihoven.
Vytvoření vlastního SPM balíčku je užitečné pro zapouzdření obchodní logiky ve vícemodulových projektech a pro publikování open-source knihoven. Pojďme si projít proces krok za krokem.
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
Příkaz swift package init vytvoří následující strukturu:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
SPM automaticky skenuje adresáře Sources/ a Tests/: každý podadresář v Sources odpovídá cíli (target).
Přidáme závislosti a nakonfigurujeme cílové platformy:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyNetworkKit",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(
name: "MyNetworkKit",
targets: ["MyNetworkKit"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
],
targets: [
.target(
name: "MyNetworkKit",
dependencies: ["Alamofire"]
),
.testTarget(
name: "MyNetworkKitTests",
dependencies: ["MyNetworkKit"]
),
]
)
// Sources/MyNetworkKit/MyNetworkKit.swift
import Foundation
import Alamofire
public struct NetworkClient {
private let session: Session
public init() {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
self.session = Session(configuration: configuration)
}
public func fetchData(from url: String) async throws -> Data {
let response = try await session.request(url).serializingData().value
return response
}
}
Pushněte balíček do Git repozitáře a vytvořte SemVer tag:
git init
git add .
git commit -m "Initial commit: MyNetworkKit"
git remote add origin https://github.com/username/MyNetworkKit.git
git push -u origin main
git tag 1.0.0
git push --tags
Poté bude moci jakýkoli vývojář připojit váš balíček přes .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0").
Alamofire — nejpopulárnější HTTP klient pro Swift. Přidáme ho přes SPM a provedeme GET požadavek.
import Alamofire
func fetchUsers() {
AF.request("https://jsonplaceholder.typicode.com/users")
.validate()
.responseDecodable(of: [User].self) { response in
switch response.result {
case .success(let users):
print("Obdrženo \(users.count) uživatelů")
case .failure(let error):
print("Chyba: \(error.localizedDescription)")
}
}
}
Knihovna Swinject poskytuje DI kontejner pro Swift. Připojuje se přes .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0").
import Swinject
let container = Container()
container.register(NetworkServiceProtocol.self) { _ in NetworkService() }
container.register(DataRepositoryProtocol.self) { r in
DataRepository(networkService: r.resolve(NetworkServiceProtocol.self)!)
}
let repository = container.resolve(DataRepositoryProtocol.self)
repository?.loadData()
Balíček swift-log od Apple — jednotné API pro logování podporující mnoho backendů (OSLog, konzole, soubory).
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("Síťový požadavek zahájen", metadata: [
"url": "\(requestURL)",
"method": "GET"
])
logger.warning("Doba odezvy přesáhla 2 sekundy")
logger.error("Chyba připojení: žádný internet")
Tyto tři příklady pokrývají typické scénáře použití SPM: HTTP klienty, DI kontejnery a systémovou infrastrukturu. Výběr knihoven není náhodný — Alamofire, Swinject a swift-log patří mezi 20 nejvíce ohvězdičkovaných Swift balíčků na GitHubu.
Pokud projekt používá CocoaPods nebo Carthage, migrace na SPM se provádí v několika krocích. Proces je bezpečný: SPM závislosti mohou koexistovat s CocoaPods a Carthage v jednom projektu, což umožňuje postupnou migraci.
.xcworkspace, otevřete .xcodeproj a proveďte Clean Build Folder.rm -rf Carthage/ v terminálu.K roku 2025 SPM podporuje drtivou většinu populárních Swift knihoven. Výjimkou jsou některé ObjC frameworky bez modulových map (modulemap). Pokud knihovna ještě nepodporuje SPM — zkontrolujte sekci Installation v jejím README; většina autorů již přidala podporu SPM v nejnovějších verzích.
Často kladené otázky
SPM je vestavěný v kompilátoru Swift a Xcode, nevyžaduje instalaci přes gem nebo Homebrew. CocoaPods používá centralizovaný registr Specs a generuje samostatný workspace. Carthage funguje přes frameworky bez integrace s projektem. SPM je jediný správce integrovaný na úrovni kompilátoru: závislosti se řeší, ukládají do mezipaměti a sestavují paralelně s hlavním kódem.
Ano, SPM podporuje smíšené Swift + Objective-C projekty. ObjC soubory v rámci SPM balíčku automaticky spadají do Umbrella Header za předpokladu správného modulemap. SPM však nepodporuje statické ObjC knihovny, které nemají modulovou mapu. Doporučuje se připojovat ObjC knihovny přes SPM pouze pokud poskytují modulemap nebo jsou napsány v čistém C.
SPM používá sémantické verzování (SemVer). Pokud balíček A vyžaduje Alamofire 5.8+ a balíček B vyžaduje Alamofire 5.9+, SPM zvolí verzi 5.9.x, která vyhovuje oběma. Pokud je konflikt neřešitelný (jeden balíček vyžaduje 5.x, druhý 6.x), SPM ohlásí chybu. V takovém případě je třeba aktualizovat jeden z balíčků nebo změnit závislost na verzi kompatibilní s oběma požadavky.
Na macOS: ~Library/Caches/org.swift.swiftpm/ a ~/Library/Developer/Xcode/DerivedData/. Na Linuxu: ~cache/swiftpm/. Při sestavování SPM ukládá do mezipaměti zdrojový kód a zkompilované objektové soubory. Pro úplné vyčištění mezipaměti spusťte swift package reset — tento příkaz odstraní mezipaměť závislostí a DerivedData pro aktuální projekt.
Ano, od Swift 5.2 SPM podporuje binární cíle (binary targets). Uzavřená knihovna je dodávána jako XCFramework a v Package.swift je uvedena cesta k .xcframework. Zdrojový kód není odhalen. Binární cíl se uvádí přes .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework"). To umožňuje připojení komerčních SDK bez porušení licenčních smluv.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také