SPM: co to je, Swift Package Manager a Package.swift

Autor: IT Sectr Publikováno: 2026-02-13 Doba čtení: 11 min

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) — vestavěný správce balíčků v kompilátoru Swift, který nevyžaduje samostatnou instalaci; funguje na iOS, macOS, Linuxu a serverových platformách.
  • Package.swift — manifestový soubor popisující název balíčku, platformy, závislosti a cílové moduly (targets) v deklarativním formátu.
  • SPM řeší závislosti pomocí sémantického verzování (SemVer), ukládá zdrojový kód do mezipaměti a sestavuje balíčky paralelně pro zrychlení.
  • Příkazy: swift package init (vytvořit balíček), swift package update (aktualizovat závislosti), swift build (sestavit), swift test (spustit testy).
  • Migrace z CocoaPods/Carthage na SPM se provádí přes Xcode: File → Add Package Dependency, poté se podfile a Cartfile odstraní.

Co je SPM?

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.

Jak funguje Swift Package Manager

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:

  1. Klonování — SPM stáhne Git repozitář závislosti z uvedené URL.
  2. Řešení verzí — analyzuje SemVer tagy (např. 2.1.3) a vybere vhodnou verzi v rámci zadaného rozsahu.
  3. Tranzitivní řešení — zkontroluje závislosti závislostí a sestaví graf bez konfliktů verzí.
  4. Ukládání do mezipaměti — uloží stažený zdrojový kód do ~Library/Caches/org.swift.swiftpm/.
  5. Kompilace — sestaví všechny cíle balíčku s příznaky hlavního projektu.

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 — manifest projektu

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
// 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:

swift
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.

Základní příkazy SPM

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).

bash
# 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 balíčku

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.

Krok 1: Inicializace

bash
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library

Krok 2: Struktura adresářů

Příkaz swift package init vytvoří následující strukturu:

text
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).

Krok 3: Úprava Package.swift

Přidáme závislosti a nakonfigurujeme cílové platformy:

swift
// 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"]
        ),
    ]
)

Krok 4: Psaní kódu

swift
// 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
    }
}

Krok 5: Publikování

Pushněte balíček do Git repozitáře a vytvořte SemVer tag:

bash
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").

Příklady použití SPM

Příklad 1: Připojení Alamofire pro síťové požadavky

Alamofire — nejpopulárnější HTTP klient pro Swift. Přidáme ho přes SPM a provedeme GET požadavek.

swift
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)")
            }
        }
}

Příklad 2: Swinject — vkládání závislostí

Knihovna Swinject poskytuje DI kontejner pro Swift. Připojuje se přes .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0").

swift
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()

Příklad 3: Swift-log pro strukturované logování

Balíček swift-log od Apple — jednotné API pro logování podporující mnoho backendů (OSLog, konzole, soubory).

swift
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.

Migrace z CocoaPods a Carthage

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.

CocoaPods → SPM

  1. V Xcode: File → Add Package Dependency, zadejte URL balíčku.
  2. Vyberte verzi a přidejte balíček k požadovaným targetům.
  3. Po přidání všech závislostí přes SPM odstraňte řádky z Podfile.
  4. Odstraňte .xcworkspace, otevřete .xcodeproj a proveďte Clean Build Folder.

Carthage → SPM

  1. Přidejte balíčky přes Xcode File → Add Package Dependency.
  2. Odstraňte závislosti z Cartfile.
  3. Odstraňte skripty sestavení Carthage z Build Phases.
  4. Vyčistěte mezipaměť: 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

Čím se SPM liší od CocoaPods a Carthage?

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.

Lze SPM použít pro Objective-C projekty?

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.

Jak SPM řeší konflikty verzí?

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.

Kde se ukládají stažené SPM balíčky?

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.

Podporuje SPM uzavřené (proprietární) knihovny?

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í

  • SPM (Swift Package Manager) — vestavěný správce balíčků Swift, který nevyžaduje samostatnou instalaci a je integrován s Xcode a kompilátorem.
  • Package.swift — deklarativní manifest v jazyce Swift popisující název balíčku, platformy, závislosti, produkty a cíle sestavení.
  • SPM používá Git repozitáře jako zdroj balíčků a řeší verze podle SemVer, přičemž ukládá zdrojový kód do mezipaměti pro urychlení opakovaných sestavení.
  • Základní příkazy: swift package init (vytvořit balíček), swift build (sestavit), swift test (otestovat), swift package update (aktualizovat závislosti).
  • Vlastní balíček se vytvoří přes swift package init, publikuje se v Gitu a je dostupný dalším projektům přes URL s SemVer tagem.
  • Migrace z CocoaPods/Carthage na SPM je bezpečná: závislosti mohou koexistovat, migrace se provádí přes File → Add Package Dependency v Xcode.
  • SPM — standard správy závislostí v ekosystému Swift, používaný 67 % iOS vývojářů (Swift.org Developer Survey, 2024).

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í.

Prodiskutovat projekt

Přečtěte si také