SPM: Was ist das, Swift Package Manager und Package.swift

Autor: IT Sectr Veröffentlicht: 2026-02-13 Lesezeit: 11 Min.

SPM (Swift Package Manager) ist ein integrierter Paketmanager des Swift-Ökosystems, der von Apple entwickelt wurde, um das Hinzufügen, Bauen und Aktualisieren von Drittanbieter-Bibliotheken zu automatisieren. SPM ist seit Version 3.0 (2016) Teil des Swift-Compilers und erfordert keine separate Installation. Im Gegensatz zu CocoaPods und Carthage ist SPM direkt in den Compiler und Xcode integriert, was es zum Standardwerkzeug für die Abhängigkeitsverwaltung in modernen Swift-Projekten macht. In diesem Artikel beleuchten wir die Struktur von Package.swift, SPM-Befehle, das Erstellen eigener Pakete und die Migration von alternativen Managern.

Wichtige Punkte

  • SPM (Swift Package Manager) ist ein in den Swift-Compiler integrierter Paketmanager, der keine separate Installation erfordert; er funktioniert unter iOS, macOS, Linux und Serverplattformen.
  • Package.swift ist eine Manifestdatei, die den Paketnamen, Plattformen, Abhängigkeiten und Zielmodule (Targets) in deklarativem Format beschreibt.
  • SPM löst Abhängigkeiten durch semantische Versionierung (SemVer), cached Quellcode und baut Pakete parallel für mehr Geschwindigkeit.
  • Befehle: swift package init (Paket erstellen), swift package update (Abhängigkeiten aktualisieren), swift build (bauen), swift test (Tests ausführen).
  • Die Migration von CocoaPods/Carthage zu SPM erfolgt über Xcode: File → Add Package Dependency, danach werden podfile und Cartfile entfernt.

Was ist SPM?

SPM (Swift Package Manager) ist der offizielle Paketmanager für die Sprache Swift, integriert in den swiftc-Compiler und die Entwicklungsumgebung Xcode. Er ermöglicht Entwicklern das Hinzufügen von Drittanbieter-Bibliotheken, die Verwaltung ihrer Versionen und das Veröffentlichen eigener Pakete. SPM erschien erstmals in Swift 3.0 (September 2016) als Befehlszeilenwerkzeug und erhielt ab Xcode 11 (2019) vollständige Integration in die grafische Oberfläche — Abhängigkeiten werden nun über das Menü File → Add Packages hinzugefügt.

SPM lädt automatisch den Quellcode von Abhängigkeiten aus Git-Repositories herunter, baut sie parallel zum Hauptprojekt und cached die Ergebnisse, sodass nachfolgende Builds schneller ausgeführt werden. Im Gegensatz zu CocoaPods erzeugt SPM keinen separaten Workspace (xcworkspace) — die Abhängigkeiten werden Teil des Haupt-Xcode-Projekts. Laut der Swift.org Developer Survey (2024) verwenden 67% der iOS-Entwickler SPM, was es zum beliebtesten Abhängigkeitsverwaltungstool im Swift-Ökosystem macht.

SPM unterstützt drei Plattformen: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) und serverseitiges Swift (Vapor, Kitura). Unter Linux funktioniert SPM vollständig über die Befehlszeile ohne Xcode.

Wie Swift Package Manager funktioniert

SPM basiert auf drei Schlüsselkonzepten: Paketen (packages), Produkten (products) und Zielen (targets). Ein Paket ist ein Git-Repository mit einem Package.swift-Manifest. Ein Produkt ist das Buildergebnis (eine Bibliothek oder eine ausführbare Datei). Ein Ziel ist ein Modul innerhalb des Pakets, das zu einer Baueinheit kompiliert wird.

Wenn ein Entwickler eine Abhängigkeit zu Package.swift hinzufügt, führt SPM die folgenden Schritte aus:

  1. Klonen — SPM lädt das Git-Repository der Abhängigkeit von der angegebenen URL herunter.
  2. Versionsauflösung — es analysiert SemVer-Tags (z. B. 2.1.3) und wählt die passende Version innerhalb des angegebenen Bereichs aus.
  3. Transitive Auflösung — es überprüft die Abhängigkeiten der Abhängigkeiten und erstellt einen konfliktfreien Versionsgraphen.
  4. Caching — es speichert den heruntergeladenen Quellcode in ~Library/Caches/org.swift.swiftpm/.
  5. Kompilierung — es baut alle Paketziele mit den Flags des Hauptprojekts.

Die Datei Package.resolved fixiert die exakten Versionen aller Abhängigkeiten, sodass das Entwicklungsteam mit einem identischen Satz von Bibliotheken arbeitet. Diese Datei sollte zur Versionskontrolle (git) hinzugefügt werden.

Ein wesentlicher Vorteil von SPM gegenüber Alternativen ist das Fehlen einer zentralen Registry. Pakete können in jedem öffentlichen Git-Repository liegen: GitHub, GitLab, Bitbucket, sowie auf unternehmenseigenen Git-Servern. Seit Swift 5.2 unterstützt SPM binäre Abhängigkeiten (binary targets) — Closed-Source-Bibliotheken, die als XCFramework ohne Quellcode verteilt werden.

Package.swift — Projektmanifest

Package.swift ist eine Swift-Datei, die die Paketstruktur und ihre Abhängigkeiten beschreibt. Die Datei ist in Swift selbst geschrieben (nicht JSON oder YAML), was die Verwendung von Bedingungslogik, berechneten Konstanten und Funktionen innerhalb des Manifests ermöglicht.

Grundstruktur von 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"]
        ),
    ]
)

Lassen Sie uns die Schlüsselelemente analysieren:

  • // swift-tools-version: 5.9 — Direktive, die die SPM-Version angibt; davon hängt die verfügbare Manifestsyntax ab.
  • name — der Paketname, der in Xcode angezeigt und in Abhängigkeitslinks verwendet wird.
  • platforms — minimale Plattformversionen; SPM erlaubt das Bauen des Pakets auf einer älteren OS-Version nicht.
  • products — was das Paket exportiert: eine Bibliothek (.library) oder eine ausführbare Datei (.executable).
  • dependencies — Liste externer Pakete mit URL und Version; unterstützt from:, exact:, branch:, revision:.
  • targets — Bauziele; jedes Ziel enthält eine Liste von Abhängigkeiten, Ressourcen und Swift-Dateien aus dem entsprechenden Verzeichnis (Sources/TargetName/).

Beispiel für die Angabe einer genauen Version, Branch und Commit:

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

Seit Swift 5.9 wurde in Package.swift Unterstützung für static framework und linkerSettings hinzugefügt, was eine präzisere Linkerkonfiguration für statische und dynamische Bibliotheken ermöglicht.

Grundlegende SPM-Befehle

Swift Package Manager bietet eine Reihe von Befehlen für die Arbeit über das Terminal. Die Befehle werden aus dem Stammverzeichnis des Pakets (wo Package.swift liegt) ausgeführt.

bash
# Neues Paket mit einer Bibliothek erstellen
swift package init --type library

# Ausführbares Paket erstellen (Konsolenanwendung)
swift package init --type executable

# Projekt bauen
swift build

# In Release-Konfiguration bauen
swift build -c release

# Tests ausführen
swift test

# Bestimmten Test ausführen
swift test --filter "MyLibraryTests/testExample"

# Abhängigkeiten herunterladen und auflösen
swift package resolve

# Abhängigkeiten auf die neuesten verfügbaren Versionen aktualisieren
swift package update

# Abhängigkeitsgraphen anzeigen
swift package show-dependencies

# Build-Cache leeren
swift package clean

# Xcode-Projekt generieren (vor Xcode 11)
swift package generate-xcodeproj

Bei der Arbeit in Xcode werden die meisten dieser Befehle automatisch ausgeführt: Abhängigkeiten werden beim Öffnen des Projekts aufgelöst, der Build startet mit ⌘B, Tests mit ⌘U. Die Kenntnis der Terminalbefehle ist jedoch für CI/CD-Pipelines (GitHub Actions, GitLab CI, Jenkins) erforderlich, wo Xcode nicht verfügbar ist.

Der Befehl swift package resolve erstellt oder aktualisiert die Datei Package.resolved. Diese Datei fixiert die exakten Versionen aller Abhängigkeiten, einschließlich transitiver, und sollte zu git hinzugefügt werden. Es wird empfohlen, vor jedem neuen Feature-Branch swift package update auszuführen, um mit aktuellen Bibliotheksversionen zu arbeiten.

Erstellen eigener Pakete

Das Erstellen eigener SPM-Pakete ist nützlich, um Geschäftslogik in Multi-Modul-Projekten zu kapseln und Open-Source-Bibliotheken zu veröffentlichen. Sehen wir uns den schrittweisen Prozess an.

Schritt 1: Initialisierung

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

Schritt 2: Verzeichnisstruktur

Der Befehl swift package init erstellt die folgende Struktur:

text
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│   └── MyNetworkKit/
│       └── MyNetworkKit.swift
└── Tests/
    └── MyNetworkKitTests/
        └── MyNetworkKitTests.swift

SPM durchsucht automatisch die Verzeichnisse Sources/ und Tests/: jedes Unterverzeichnis in Sources entspricht einem Ziel (target).

Schritt 3: Package.swift bearbeiten

Fügen wir Abhängigkeiten hinzu und konfigurieren die Zielplattformen:

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

Schritt 4: Code schreiben

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

Schritt 5: Veröffentlichung

Schieben Sie das Paket in ein Git-Repository und erstellen Sie einen 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

Danach kann jeder Entwickler Ihr Paket mit .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0") hinzufügen.

SPM-Anwendungsbeispiele

Beispiel 1: Alamofire für Netzwerkanfragen hinzufügen

Alamofire ist der beliebteste HTTP-Client für Swift. Fügen wir ihn über SPM hinzu und führen eine GET-Anfrage aus.

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("(users.count) Benutzer empfangen")
            case .failure(let error):
                print("Fehler: (error.localizedDescription)")
            }
        }
}

Beispiel 2: Swinject — Dependency Injection

Die Bibliothek Swinject bietet einen DI-Container für Swift. Sie wird hinzugefügt über .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()

Beispiel 3: Swift-log für strukturiertes Logging

Das swift-log-Paket von Apple bietet eine einheitliche Logging-API, die mehrere Backends unterstützt (OSLog, Konsole, Dateien).

swift
import Logging

var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug

logger.info("Netzwerkanfrage gestartet", metadata: [
    "url": "(requestURL)",
    "method": "GET"
])

logger.warning("Antwortzeit überschritt 2 Sekunden")
logger.error("Verbindungsfehler: Kein Internet")

Diese drei Beispiele decken typische SPM-Anwendungsszenarien ab: HTTP-Clients, DI-Container und Systeminfrastruktur. Die Auswahl der Bibliotheken ist nicht zufällig — Alamofire, Swinject und swift-log gehören zu den 20 meistgestarnten Swift-Paketen auf GitHub.

Migration von CocoaPods und Carthage

Wenn Ihr Projekt CocoaPods oder Carthage verwendet, erfolgt die Migration zu SPM in wenigen Schritten. Der Prozess ist sicher: SPM-Abhängigkeiten können im selben Projekt mit CocoaPods und Carthage koexistieren, was eine schrittweise Migration ermöglicht.

CocoaPods → SPM

  1. In Xcode: File → Add Package Dependency, geben Sie die Paket-URL ein.
  2. Wählen Sie die Version aus und fügen Sie das Paket zu den erforderlichen Targets hinzu.
  3. Entfernen Sie nach dem Hinzufügen aller Abhängigkeiten über SPM die Zeilen aus der Podfile.
  4. Löschen Sie den .xcworkspace, öffnen Sie das .xcodeproj und führen Sie Clean Build Folder aus.

Carthage → SPM

  1. Fügen Sie Pakete über Xcode File → Add Package Dependency hinzu.
  2. Entfernen Sie Abhängigkeiten aus der Cartfile.
  3. Entfernen Sie Carthage-Build-Skripte aus Build Phases.
  4. Leeren Sie den Cache: rm -rf Carthage/ im Terminal.

Stand 2025 unterstützt SPM die überwiegende Mehrheit der populären Swift-Bibliotheken. Ausnahmen sind einige ObjC-Frameworks ohne Modulmaps. Wenn eine Bibliothek SPM noch nicht unterstützt — überprüfen Sie den Abschnitt Installation in ihrer README; die meisten Autoren haben bereits SPM-Unterstützung in den neuesten Versionen hinzugefügt.

Häufig gestellte Fragen

Wie unterscheidet sich SPM von CocoaPods und Carthage?

SPM ist in den Swift-Compiler und Xcode integriert und erfordert keine Installation über gem oder Homebrew. CocoaPods verwendet eine zentrale Specs-Registry und erzeugt einen separaten Workspace. Carthage arbeitet über Frameworks ohne Projektintegration. SPM ist der einzige Manager, der auf Compiler-Ebene integriert ist: Abhängigkeiten werden parallel zum Hauptcode aufgelöst, gecached und gebaut.

Kann SPM für Objective-C-Projekte verwendet werden?

Ja, SPM unterstützt gemischte Swift + Objective-C-Projekte. ObjC-Dateien innerhalb eines SPM-Pakets werden automatisch in einen Umbrella Header aufgenommen, sofern ein korrektes modulemap existiert. Allerdings unterstützt SPM keine statischen ObjC-Bibliotheken ohne Modulmap. Es wird empfohlen, ObjC-Bibliotheken nur dann über SPM anzubinden, wenn sie eine modulemap bereitstellen oder in reinem C geschrieben sind.

Wie löst SPM Versionskonflikte?

SPM verwendet semantische Versionierung (SemVer). Wenn Paket A Alamofire 5.8+ benötigt und Paket B Alamofire 5.9+ benötigt, wählt SPM die Version 5.9.x, die beide Anforderungen erfüllt. Ist der Konflikt nicht auflösbar (ein Paket benötigt 5.x, ein anderes 6.x), meldet SPM einen Fehler. In diesem Fall müssen Sie eines der Pakete aktualisieren oder die Abhängigkeit auf eine mit beiden Anforderungen kompatible Version umstellen.

Wo werden heruntergeladene SPM-Pakete gespeichert?

Unter macOS: ~Library/Caches/org.swift.swiftpm/ und ~/Library/Developer/Xcode/DerivedData/. Unter Linux: ~cache/swiftpm/. Während des Bauens cached SPM Quellcode und kompilierte Objektdateien. Zum vollständigen Leeren des Caches führen Sie swift package reset aus — dieser Befehl entfernt den Abhängigkeits-Cache und DerivedData für das aktuelle Projekt.

Unterstützt SPM Closed-Source-(proprietäre) Bibliotheken?

Ja, seit Swift 5.2 unterstützt SPM binäre Ziele (binary targets). Eine Closed-Source-Bibliothek wird als XCFramework verteilt, und der Pfad zur .xcframework wird in Package.swift angegeben. Der Quellcode wird nicht offengelegt. Ein binäres Ziel wird angegeben über .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework"). Dies ermöglicht die Anbindung kommerzieller SDKs ohne Verletzung von Lizenzvereinbarungen.

Zusammenfassung

  • SPM (Swift Package Manager) ist ein integrierter Swift-Paketmanager, der keine separate Installation erfordert und in Xcode und den Compiler integriert ist.
  • Package.swift ist ein deklaratives Manifest in Swift, das Paketname, Plattformen, Abhängigkeiten, Produkte und Bauziele beschreibt.
  • SPM verwendet Git-Repositories als Paketquellen und löst Versionen über SemVer, wobei Quellcode für schnellere Folge-Builds gecached wird.
  • Hauptbefehle: swift package init (Paket erstellen), swift build (bauen), swift test (testen), swift package update (Abhängigkeiten aktualisieren).
  • Ein benutzerdefiniertes Paket wird über swift package init erstellt, in Git veröffentlicht und über URL mit SemVer-Tag für andere Projekte verfügbar gemacht.
  • Die Migration von CocoaPods/Carthage zu SPM ist sicher: Abhängigkeiten können koexistieren, die Migration erfolgt über File → Add Package Dependency in Xcode.
  • SPM ist das Standard-Abhängigkeitsverwaltungstool im Swift-Ökosystem, verwendet von 67% der iOS-Entwickler (Swift.org Developer Survey, 2024).

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch