Swift Package Manager in 2026: Packages Maken, Publiceren en Sollicitatievragen

Uitgebreide handleiding voor Swift Package Manager voor iOS-ontwikkelaars. Packages maken, dependencies beheren, libraries publiceren en veelgestelde SPM-sollicitatievragen beantwoorden.

Swift Package Manager Tutorial 2026

Swift Package Manager (SPM) verzorgt dependency management en package distributie voor Swift-projecten. In tegenstelling tot CocoaPods of Carthage integreert SPM direct in Xcode en de Swift-toolchain, zonder externe installatie. Swift 6.2 en 6.3 introduceerden strikte memory safety instellingen, standaard actor isolation en het nieuwe Swift Build systeem, waardoor SPM de definitieve keuze wordt voor moderne iOS-ontwikkeling.

Wat SPM doet

Swift Package Manager lost dependencies op, downloadt broncode, compileert modules en linkt ze in de uiteindelijke binary. Een enkel Package.swift manifest bestand definieert alles: dependencies, targets, products en build instellingen.

Package.swift Manifest Structuur en Syntax

Elk Swift package begint met een Package.swift bestand in de repository root. Dit manifest gebruikt Swift code om de package structuur, dependencies en build configuratie te declareren.

Package.swiftswift
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"]
        )
    ]
)

De platforms array specificeert minimum deployment targets. De products sectie definieert wat andere packages kunnen importeren. De targets sectie somt compilatie-eenheden op met hun respectievelijke dependencies.

Een Swift Package Maken via de Command Line

Het swift package init commando maakt een nieuw package aan met de standaard directorystructuur. De --type flag bepaalt of het package een library of een executable produceert.

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

Het uitvoeren van swift build compileert het package. Het uitvoeren van swift test voert de test suite uit. Beide commando's gebruiken de configuratie uit Package.swift zonder aanvullende setup.

Dependency Versie Vereisten en Resolutie

SPM ondersteunt drie versie specificatie strategieen: exacte versie, versie range en branch of commit referentie. De keuze beinvloedt reproduceerbaarheid en flexibiliteit.

Package.swiftswift
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")
]

Het Package.resolved bestand registreert de exacte versies die tijdens dependency resolutie zijn opgelost. Dit bestand moet worden gecommit naar version control voor reproduceerbare builds voor teamleden en CI-systemen.

Branch Dependencies in Productie

Branch en commit referenties omzeilen semantic versioning. Het gebruik van branch: "main" in een productie-app betekent dat elke push naar main de build kan breken. Reserveer branch referenties voor actieve ontwikkeling tegen nog niet vrijgegeven features.

Packages Toevoegen aan een Xcode Project

Xcode integreert SPM via het File menu. De route gaat via File, dan Add Package Dependencies. Na het invoeren van de repository URL wordt de versie regel geselecteerd en bepaald welke targets de dependency moeten linken.

AppDelegate.swiftswift
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 slaat package referenties op in het .xcodeproj bestand en opgeloste versies in Package.resolved in de project root. De Derived Data folder cached gedownloade packages.

Lokale Package Ontwikkeling met Path Dependencies

Tijdens ontwikkeling maakt het verwijzen naar een lokaal pad in plaats van een remote URL snelle iteratie mogelijk zonder tussenversies te publiceren. Deze techniek past bij monorepo setups en feature ontwikkeling.

Package.swift in consuming packageswift
dependencies: [
    // Local path for development
    .package(path: "../NetworkKit"),
    
    // Remote URL for release
    // .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]

Wisselen tussen lokale en remote dependencies gebeurt door de inactieve regel te becommentarieren. Xcode en de Swift CLI lossen path dependencies op relatief aan het consumerende package.

Klaar om je iOS gesprekken te halen?

Oefen met onze interactieve simulatoren, flashcards en technische tests.

Een Swift Package Publiceren op GitHub

Publiceren vereist een Git repository met semantische versie tags. SPM behandelt Git tags als release versies. De Swift Package Index indexeert publieke packages automatisch.

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

Volg de conventies van semantic versioning: verhoog de major versie voor breaking changes, minor voor nieuwe features en patch voor bug fixes. SPM gaat uit van naleving van deze regels bij het oplossen van from: versie vereisten.

Swift 6.2 en 6.3 Package Instellingen

Swift 6.2 introduceerde per-target language mode configuratie en strikte memory safety instellingen. Swift 6.3 voegt Swift Build integratie toe als opt-in build systeem.

Package.swift with Swift 6.2+ featuresswift
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")
            ]
        )
    ]
)

De swiftLanguageMode instelling maakt geleidelijke adoptie van Swift 6 features mogelijk in een codebase. Targets kunnen verschillende language modes gebruiken binnen hetzelfde package.

SBOM Generatie voor Security Compliance

SE-0509 voegde native Software Bill of Materials generatie toe in Swift 6.3. SBOM documenten lijsten alle dependencies en hun versies op voor security audits en regelgevende compliance.

bash
# 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 URLs

Enterprise omgevingen en overheidscontracten vereisen steeds vaker SBOM documentatie. De CycloneDX en SPDX formaten integreren met standaard vulnerability scanning tools.

Binary Targets en XCFramework Distributie

Binary targets maken distributie van voorgecompileerde frameworks mogelijk in plaats van broncode. XCFrameworks bundelen binaries voor meerdere platformen en architecturen.

Package.swift with binary targetswift
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.zip

Binary targets verminderen build tijden voor consumenten en beschermen proprietary implementaties. De checksum garandeert download integriteit.

Veelgestelde Sollicitatievragen over Swift Package Manager

Technische sollicitatiegesprekken voor iOS-posities bevatten regelmatig SPM-vragen. Deze varieren van basisgebruik tot architectuurbeslissingen.

V: Hoe verschilt SPM van CocoaPods en Carthage?

SPM integreert in Xcode en de Swift-toolchain zonder externe tools. CocoaPods gebruikt een centrale spec repository en wijzigt de Xcode workspace structuur. Carthage bouwt frameworks in een aparte stap zonder Xcode integratie. SPM lost dependencies op en bouwt in een enkel verenigd proces. De Apple documentatie over Swift packages behandelt de officiele tooling.

V: Wat gebeurt er tijdens dependency resolutie?

SPM leest Package.swift manifests recursief en bouwt een dependency graaf. Vervolgens worden versie constraints toegepast om compatibele versies voor alle packages te vinden. De resolver schrijft exacte versies naar Package.resolved. Conflicten ontstaan wanneer twee packages incompatibele versies van een gedeelde dependency vereisen.

V: Hoe wordt een diamond dependency conflict opgelost?

Wanneer package A en B beide afhankelijk zijn van package C met incompatibele versie vereisten, faalt SPM resolutie. Oplossingen omvatten: een consument updaten om een breder versie bereik te ondersteunen, het restrictieve package forken, of module aliasing gebruiken als het conflict tussen verschillende packages met dezelfde modulenaam is.

swift
// Module aliasing for name conflicts
.target(
    name: "MyApp",
    dependencies: [
        .product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
    ]
)

V: Wanneer zou een binary target gebruikt worden in plaats van source distributie?

Binary targets passen bij proprietary SDKs waar source blootstelling onaanvaardbaar is, grote dependencies waar compilatietijd de ontwikkelaarsproductiviteit beinvloedt, en voorgebouwde vendor libraries. Source distributie blijft de voorkeur voor open source projecten en interne libraries waar debuggen in dependencies waarde toevoegt.

Migreren van CocoaPods naar Swift Package Manager

Migratie vereist het vervangen van Podfile entries door SPM package referenties. Niet alle CocoaPods hebben SPM equivalenten, dus verifieer beschikbaarheid op Swift Package Index voor de start.

ruby
# Before: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'
swift
// 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.0

Verwijder na migratie het Podfile, Podfile.lock en de Pods directory. Voer pod deintegrate uit om CocoaPods workspace wijzigingen te verwijderen. Import statements in Swift bestanden blijven ongewijzigd.

SPM Best Practices voor Productie Apps

  • Pin major versies met from: voor stabiliteit terwijl minor updates en patches worden ontvangen
  • Commit Package.resolved om reproduceerbare builds in het hele team te garanderen
  • Gebruik lokale packages tijdens actieve ontwikkeling, schakel over naar remote URLs voor het mergen
  • Scheid test-only dependencies met testTarget om ze niet in release builds te bundelen
  • Documenteer minimum Swift tools versie bovenaan het manifest: // swift-tools-version: 5.10
  • Valideer package builds op CI voor het taggen van releases
Swift Tools Version

Het // swift-tools-version: commentaar moet op de eerste regel van Package.swift verschijnen. Het bepaalt welke PackageDescription API versie het manifest gebruikt. Swift 6.0 voegde flexibiliteit toe om dit commentaar op volgende regels toe te staan voor licentie headers.

Kernpunten voor iOS-Ontwikkelaars die SPM Gebruiken

  • SPM integreert native in Xcode, waardoor CocoaPods en Carthage setup overhead wordt geelimineerd
  • Het Package.swift manifest gebruikt Swift code, waardoor type-checked dependency declaraties mogelijk zijn
  • Versie vereisten ondersteunen semantic versioning ranges, exacte versies en branch referenties
  • Package.resolved vergrendelt dependency versies voor reproduceerbare builds
  • Swift 6.2 voegde per-target language modes en strikte memory safety instellingen toe
  • Swift 6.3 introduceerde SBOM generatie voor compliance documentatie
  • Binary targets distribueren voorgecompileerde XCFrameworks wanneer source distributie onpraktisch is
  • Sollicitatievragen richten zich op resolutie conflicten, migratie strategieen en architecturale trade-offs tussen SPM en alternatieven

Voor uitgebreide iOS sollicitatievoorbereiding, bekijk de modules over SwiftUI state management en protocol-oriented programming op SharpSkill.

Begin met oefenen!

Test je kennis met onze gespreksimulatoren en technische tests.

Dagelijkse challenge

Zie jij de bug in iOS?

Een echt codefragment, een verborgen bug, één poging per dag. Zonder account uit te proberen.

Anthony Fillion-Maillet

Geschreven door

Anthony Fillion-Maillet

Oprichter van SharpSkill

Al meer dan 10 jaar fullstack-ontwikkelaar. Hij leidt SharpSkill en staat in voor alles wat hier verschijnt.

Bijgewerkt op 20 september 2026

Tags

#swift
#ios
#spm
#dependency-management
#xcode

Delen

Gerelateerde artikelen