Swift Package Manager 2026: Pakete erstellen, veröffentlichen und Interview-Fragen meistern
Umfassende Anleitung zum Swift Package Manager für iOS-Entwickler. Pakete erstellen, Abhängigkeiten verwalten, Bibliotheken veröffentlichen und häufige SPM-Interview-Fragen beantworten.

Swift Package Manager (SPM) übernimmt das Abhängigkeitsmanagement und die Paketverteilung für Swift-Projekte. Im Gegensatz zu CocoaPods oder Carthage integriert sich SPM direkt in Xcode und die Swift-Toolchain, ohne externe Installation. Swift 6.2 und 6.3 führten strenge Memory-Safety-Einstellungen, Standard-Actor-Isolation und das neue Swift-Build-System ein, wodurch SPM zur definitiven Wahl für moderne iOS-Entwicklung wird.
Swift Package Manager löst Abhängigkeiten auf, lädt Quellcode herunter, kompiliert Module und verlinkt sie in die finale Binary. Eine einzige Package.swift-Manifestdatei definiert alles: Abhängigkeiten, Targets, Produkte und Build-Einstellungen.
Package.swift Manifest-Struktur und Syntax
Jedes Swift-Paket beginnt mit einer Package.swift-Datei im Repository-Stammverzeichnis. Dieses Manifest verwendet Swift-Code, um die Paketstruktur, Abhängigkeiten und Build-Konfiguration zu deklarieren.
import PackageDescription
let package = Package(
name: "NetworkKit",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(
name: "NetworkKit",
targets: ["NetworkKit"]
)
],
dependencies: [
.package(
url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"
)
],
targets: [
.target(
name: "NetworkKit",
dependencies: ["Alamofire"]
),
.testTarget(
name: "NetworkKitTests",
dependencies: ["NetworkKit"]
)
]
)Das platforms-Array spezifiziert minimale Deployment-Ziele. Der products-Bereich definiert, was andere Pakete importieren können. Der targets-Bereich listet Kompilierungseinheiten mit ihren jeweiligen Abhängigkeiten auf.
Ein Swift-Paket über die Kommandozeile erstellen
Der Befehl swift package init erstellt ein neues Paket mit der Standard-Verzeichnisstruktur. Das Flag --type bestimmt, ob das Paket eine Bibliothek oder eine ausführbare Datei produziert.
# Create a library package
mkdir NetworkKit && cd NetworkKit
swift package init --type=library
# Generated structure:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │ └── NetworkKit/
# │ └── NetworkKit.swift
# └── Tests/
# └── NetworkKitTests/
# └── NetworkKitTests.swiftDie Ausführung von swift build kompiliert das Paket. Die Ausführung von swift test führt die Test-Suite aus. Beide Befehle nutzen die Konfiguration aus Package.swift ohne zusätzliche Einrichtung.
Abhängigkeitsversionen und Auflösung
SPM unterstützt drei Strategien zur Versionsspezifikation: exakte Version, Versionsbereich und Branch- oder Commit-Referenz. Die Wahl beeinflusst Reproduzierbarkeit und Flexibilität.
dependencies: [
// Semantic versioning: 5.9.0 up to next major
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
// Exact version: locks to 5.9.1
.package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
// Version range: 5.8.0 to 5.9.9
.package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
// Branch reference: for development
.package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
// Commit reference: pinned to specific commit
.package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]Die Datei Package.resolved zeichnet die exakten Versionen auf, die während der Abhängigkeitsauflösung ermittelt wurden. Diese Datei sollte in die Versionskontrolle eingecheckt werden, um reproduzierbare Builds für Teammitglieder und CI-Systeme zu gewährleisten.
Branch- und Commit-Referenzen umgehen Semantic Versioning. Die Verwendung von branch: "main" in einer Produktions-App bedeutet, dass jeder Push auf main den Build brechen kann. Branch-Referenzen sollten für aktive Entwicklung gegen unveröffentlichte Features reserviert bleiben.
Pakete zu einem Xcode-Projekt hinzufügen
Xcode integriert SPM über das Datei-Menü. Der Weg führt über Datei, dann Paketabhängigkeiten hinzufügen. Nach Eingabe der Repository-URL wird die Versionsregel ausgewählt und bestimmt, welche Targets die Abhängigkeit verlinken sollen.
import UIKit
import Alamofire // Available after adding via Xcode
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
AF.request("https://api.example.com/health").response { response in
print(response.result)
}
return true
}
}Xcode speichert Paketreferenzen in der .xcodeproj-Datei und aufgelöste Versionen in Package.resolved im Projektstammverzeichnis. Der Derived-Data-Ordner cached heruntergeladene Pakete.
Lokale Paketentwicklung mit Pfad-Abhängigkeiten
Während der Entwicklung ermöglicht das Verweisen auf einen lokalen Pfad statt einer Remote-URL schnelle Iteration ohne Veröffentlichung von Zwischenversionen. Diese Technik eignet sich für Monorepo-Setups und Feature-Entwicklung.
dependencies: [
// Local path for development
.package(path: "../NetworkKit"),
// Remote URL for release
// .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]Der Wechsel zwischen lokalen und Remote-Abhängigkeiten erfolgt durch Auskommentieren der inaktiven Zeile. Xcode und die Swift-CLI lösen Pfadabhängigkeiten relativ zum konsumierenden Paket auf.
Bereit für deine iOS-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Ein Swift-Paket auf GitHub veröffentlichen
Die Veröffentlichung erfordert ein Git-Repository mit semantischen Versions-Tags. SPM behandelt Git-Tags als Release-Versionen. Der Swift Package Index indexiert öffentliche Pakete automatisch.
# Initialize repository and push
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/NetworkKit.git
git push -u origin main
# Create version tag
git tag 1.0.0
git push origin 1.0.0
# Other packages can now depend on:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")Die Konventionen der semantischen Versionierung sollten befolgt werden: Major-Version für Breaking Changes erhöhen, Minor für neue Features und Patch für Bugfixes. SPM geht bei der Auflösung von from:-Versionsanforderungen von der Einhaltung dieser Regeln aus.
Swift 6.2 und 6.3 Paket-Einstellungen
Swift 6.2 führte die Konfiguration des Sprachmodus pro Target und strenge Memory-Safety-Einstellungen ein. Swift 6.3 fügt Swift-Build-Integration als Opt-in-Build-System hinzu.
import PackageDescription
let package = Package(
name: "SafeNetworkKit",
platforms: [.iOS(.v17)],
products: [
.library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
],
targets: [
.target(
name: "SafeNetworkKit",
swiftSettings: [
// Enable Swift 6 language mode for this target only
.swiftLanguageMode(.v6),
// Enable strict memory safety checking (SE-0458)
.enableExperimentalFeature("StrictMemorySafety"),
// Set default actor isolation (SE-0466)
.enableExperimentalFeature("GlobalActorIsolation")
]
)
]
)Die swiftLanguageMode-Einstellung ermöglicht die schrittweise Einführung von Swift-6-Features in einer Codebasis. Targets können innerhalb desselben Pakets unterschiedliche Sprachmodi verwenden.
SBOM-Generierung für Security-Compliance
SE-0509 fügte in Swift 6.3 native Software-Bill-of-Materials-Generierung hinzu. SBOM-Dokumente listen alle Abhängigkeiten und ihre Versionen für Sicherheitsaudits und regulatorische Compliance auf.
# Generate SBOM in CycloneDX format
swift build --sbom-spec cyclonedx
# Generate SBOM using dedicated subcommand
swift package generate-sbom --format spdx
# Output includes:
# - Package name and version
# - All transitive dependencies
# - License information
# - Source repository URLsUnternehmensumgebungen und Regierungsaufträge erfordern zunehmend SBOM-Dokumentation. Die CycloneDX- und SPDX-Formate integrieren sich mit Standard-Vulnerability-Scanning-Tools.
Binary Targets und XCFramework-Distribution
Binary Targets ermöglichen die Distribution vorkompilierter Frameworks statt Quellcode. XCFrameworks bündeln Binaries für mehrere Plattformen und Architekturen.
import PackageDescription
let package = Package(
name: "AnalyticsSDK",
platforms: [.iOS(.v14)],
products: [
.library(name: "AnalyticsSDK", targets: ["AnalyticsSDK"])
],
targets: [
.binaryTarget(
name: "AnalyticsSDK",
url: "https://releases.example.com/AnalyticsSDK-2.0.0.xcframework.zip",
checksum: "abc123def456..."
)
]
)
// Generate checksum:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zipBinary Targets reduzieren die Build-Zeiten für Konsumenten und schützen proprietäre Implementierungen. Die Prüfsumme stellt die Download-Integrität sicher.
Häufige Interview-Fragen zum Swift Package Manager
Technische Interviews für iOS-Positionen enthalten häufig SPM-Fragen. Diese reichen von grundlegender Verwendung bis zu Architekturentscheidungen.
F: Wie unterscheidet sich SPM von CocoaPods und Carthage?
SPM integriert sich ohne externe Tools in Xcode und die Swift-Toolchain. CocoaPods verwendet ein zentrales Spec-Repository und modifiziert die Xcode-Workspace-Struktur. Carthage baut Frameworks in einem separaten Schritt ohne Xcode-Integration. SPM löst Abhängigkeiten auf und baut in einem einzigen vereinheitlichten Prozess. Die Apple-Dokumentation zu Swift-Paketen behandelt das offizielle Tooling.
F: Was passiert während der Abhängigkeitsauflösung?
SPM liest Package.swift-Manifeste rekursiv und baut einen Abhängigkeitsgraphen auf. Dann werden Versionseinschränkungen angewendet, um kompatible Versionen für alle Pakete zu finden. Der Resolver schreibt exakte Versionen in Package.resolved. Konflikte entstehen, wenn zwei Pakete inkompatible Versionen einer gemeinsamen Abhängigkeit erfordern.
F: Wie wird ein Diamond-Dependency-Konflikt behandelt?
Wenn Paket A und B beide von Paket C mit inkompatiblen Versionsanforderungen abhängen, schlägt die SPM-Auflösung fehl. Lösungen umfassen: einen Konsumenten aktualisieren, um einen breiteren Versionsbereich zu unterstützen, das restriktive Paket forken, oder Module-Aliasing verwenden, wenn der Konflikt zwischen verschiedenen Paketen mit demselben Modulnamen besteht.
// Module aliasing for name conflicts
.target(
name: "MyApp",
dependencies: [
.product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
]
)F: Wann würde man ein Binary Target statt Source-Distribution verwenden?
Binary Targets eignen sich für proprietäre SDKs, bei denen Quellcode-Offenlegung inakzeptabel ist, für große Abhängigkeiten, deren Kompilierungszeit die Entwicklerproduktivität beeinträchtigt, und für vorkompilierte Vendor-Bibliotheken. Source-Distribution bleibt vorzuziehen für Open-Source-Projekte und interne Bibliotheken, bei denen das Debuggen in Abhängigkeiten einen Mehrwert bietet.
Migration von CocoaPods zu Swift Package Manager
Die Migration erfordert das Ersetzen von Podfile-Einträgen durch SPM-Paketreferenzen. Nicht alle CocoaPods haben SPM-Äquivalente, daher sollte die Verfügbarkeit auf Swift Package Index vor dem Start überprüft werden.
# Before: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'// After: Package dependencies in Xcode
// File > Add Package Dependencies for each:
// https://github.com/Alamofire/Alamofire.git from 5.9.0
// https://github.com/SwiftyJSON/SwiftyJSON.git from 5.0.0
// https://github.com/onevcat/Kingfisher.git from 7.0.0Nach der Migration werden Podfile, Podfile.lock und das Pods-Verzeichnis entfernt. Der Befehl pod deintegrate entfernt CocoaPods-Workspace-Modifikationen. Import-Statements in Swift-Dateien bleiben unverändert.
SPM Best Practices für Produktions-Apps
- Major-Versionen mit
from:pinnen für Stabilität bei gleichzeitigem Erhalt von Minor-Updates und Patches Package.resolvedcommitten, um reproduzierbare Builds im gesamten Team sicherzustellen- Lokale Pakete während aktiver Entwicklung verwenden und vor dem Merge auf Remote-URLs wechseln
- Test-only-Abhängigkeiten mittels
testTargetseparieren, um sie nicht in Release-Builds zu bündeln - Minimale Swift-Tools-Version am Manifest-Anfang dokumentieren:
// swift-tools-version: 5.10 - Paket-Builds auf CI vor dem Tagging von Releases validieren
Der Kommentar // swift-tools-version: muss in der ersten Zeile von Package.swift erscheinen. Er bestimmt, welche PackageDescription-API-Version das Manifest verwendet. Swift 6.0 fügte Flexibilität hinzu, um diesen Kommentar in nachfolgenden Zeilen für Lizenz-Header zu erlauben.
Kernpunkte für iOS-Entwickler bei der SPM-Nutzung
- SPM integriert sich nativ in Xcode und eliminiert den Setup-Overhead von CocoaPods und Carthage
- Das
Package.swift-Manifest verwendet Swift-Code und ermöglicht typgeprüfte Abhängigkeitsdeklarationen - Versionsanforderungen unterstützen semantische Versionierungsbereiche, exakte Versionen und Branch-Referenzen
Package.resolvedsperrt Abhängigkeitsversionen für reproduzierbare Builds- Swift 6.2 fügte Sprachmodi pro Target und strenge Memory-Safety-Einstellungen hinzu
- Swift 6.3 führte SBOM-Generierung für Compliance-Dokumentation ein
- Binary Targets distribuieren vorkompilierte XCFrameworks, wenn Source-Distribution unpraktisch ist
- Interview-Fragen konzentrieren sich auf Auflösungskonflikte, Migrationsstrategien und architektonische Trade-offs zwischen SPM und Alternativen
Für umfassende iOS-Interview-Vorbereitung empfiehlt sich die Durchsicht der Module zu SwiftUI State Management und Protocol-Oriented Programming auf SharpSkill.
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Findest du den Bug in iOS?
Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Geschrieben von
Anthony Fillion-MailletGründer von SharpSkill
Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.
Aktualisiert am 20. September 2026
Tags
Teilen
Verwandte Artikel

Combine vs async/await in Swift: Progressive Migrationsmuster
Vollständiger Leitfaden zur Migration von Combine zu async/await in Swift: progressive Strategien, Bridging-Muster und Paradigmen-Koexistenz in iOS-Codebasen.

iOS-Accessibility-Interviewfragen 2026: VoiceOver und Dynamic Type
Vorbereitung auf iOS-Interviews mit zentralen Accessibility-Fragen: VoiceOver, Dynamic Type, semantische Traits und Audits.

Swift Macros: praktische Beispiele für Metaprogrammierung
Vollständiger Leitfaden zu Swift Macros: Erstellung freistehender und attached Makros inklusive Swift 6 Body Macros, AST-Manipulation mit swift-syntax und praktische Beispiele zur Vermeidung von Boilerplate-Code.