Swift Package Manager nel 2026: Creare, Pubblicare Pacchetti e Domande da Colloquio
Guida completa a Swift Package Manager per sviluppatori iOS. Come creare pacchetti, gestire dipendenze, pubblicare librerie e rispondere alle domande tecniche sui colloqui SPM.

Swift Package Manager (SPM) gestisce le dipendenze e la distribuzione dei pacchetti per i progetti Swift. A differenza di CocoaPods o Carthage, SPM si integra direttamente in Xcode e nella toolchain Swift, senza richiedere installazioni esterne. Swift 6.2 e 6.3 hanno introdotto impostazioni rigorose di memory safety, isolamento degli actor predefinito e il nuovo sistema Swift Build, rendendo SPM la scelta definitiva per lo sviluppo iOS moderno.
Swift Package Manager risolve le dipendenze, scarica il codice sorgente, compila i moduli e li collega nel binario finale. Un singolo file manifest Package.swift definisce tutto: dipendenze, target, prodotti e impostazioni di build.
Struttura e Sintassi del Manifest Package.swift
Ogni pacchetto Swift inizia con un file Package.swift nella root del repository. Questo manifest utilizza codice Swift per dichiarare la struttura del pacchetto, le dipendenze e la configurazione di build.
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"]
)
]
)L'array platforms specifica i target di deployment minimi. La sezione products definisce cosa altri pacchetti possono importare. La sezione targets elenca le unità di compilazione con le rispettive dipendenze.
Creare un Pacchetto Swift dalla Riga di Comando
Il comando swift package init crea la struttura di un nuovo pacchetto con la directory standard. Il flag --type determina se il pacchetto produce una libreria o un eseguibile.
# 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.swiftL'esecuzione di swift build compila il pacchetto. L'esecuzione di swift test esegue la suite di test. Entrambi i comandi utilizzano la configurazione da Package.swift senza configurazioni aggiuntive.
Requisiti di Versione delle Dipendenze e Risoluzione
SPM supporta tre strategie di specifica della versione: versione esatta, range di versioni e riferimento a branch o commit. La scelta influisce sulla riproducibilità e flessibilità.
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")
]Il file Package.resolved registra le versioni esatte risolte durante la risoluzione delle dipendenze. Questo file dovrebbe essere committato nel version control per garantire build riproducibili tra i membri del team e i sistemi CI.
I riferimenti a branch e commit bypassano il semantic versioning. Usare branch: "main" in un'app di produzione significa che qualsiasi push su main può rompere la build. I riferimenti a branch dovrebbero essere riservati allo sviluppo attivo di feature non ancora rilasciate.
Aggiungere Pacchetti a un Progetto Xcode
Xcode integra SPM tramite il menu File. Il percorso passa da File, poi Aggiungi Dipendenze Pacchetto. Dopo aver inserito l'URL del repository, si seleziona la regola di versione e si sceglie quali target devono linkare la dipendenza.
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 memorizza i riferimenti ai pacchetti nel file .xcodeproj e le versioni risolte in Package.resolved nella root del progetto. La cartella Derived Data fa cache dei pacchetti scaricati.
Sviluppo Locale di Pacchetti con Dipendenze Path
Durante lo sviluppo, puntare a un path locale invece di un URL remoto permette iterazioni rapide senza pubblicare versioni intermedie. Questa tecnica si adatta a setup monorepo e sviluppo di feature.
dependencies: [
// Local path for development
.package(path: "../NetworkKit"),
// Remote URL for release
// .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]Il passaggio tra dipendenze locali e remote avviene commentando la riga inattiva. Xcode e la CLI Swift risolvono le dipendenze path relative al pacchetto consumatore.
Pronto a superare i tuoi colloqui su iOS?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Pubblicare un Pacchetto Swift su GitHub
La pubblicazione richiede un repository Git con tag di versione semantici. SPM tratta i tag Git come versioni di release. Il Swift Package Index indicizza automaticamente i pacchetti pubblici.
# 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")Le convenzioni del semantic versioning vanno seguite: incrementare la versione major per breaking changes, minor per nuove feature e patch per bug fix. SPM assume l'aderenza a queste regole quando risolve i requisiti di versione from:.
Impostazioni Pacchetto Swift 6.2 e 6.3
Swift 6.2 ha introdotto la configurazione del language mode per target e impostazioni rigorose di memory safety. Swift 6.3 aggiunge l'integrazione Swift Build come sistema di build opt-in.
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")
]
)
]
)L'impostazione swiftLanguageMode permette l'adozione graduale delle feature Swift 6 in un codebase. I target possono usare language mode differenti all'interno dello stesso pacchetto.
Generazione SBOM per Conformità di Sicurezza
SE-0509 ha aggiunto la generazione nativa di Software Bill of Materials in Swift 6.3. I documenti SBOM elencano tutte le dipendenze e le loro versioni per audit di sicurezza e conformità normativa.
# 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 URLsGli ambienti enterprise e i contratti governativi richiedono sempre più documentazione SBOM. I formati CycloneDX e SPDX si integrano con gli strumenti standard di vulnerability scanning.
Binary Target e Distribuzione XCFramework
I binary target permettono la distribuzione di framework precompilati invece del codice sorgente. Gli XCFramework raggruppano binari per piattaforme e architetture multiple.
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.zipI binary target riducono i tempi di build per i consumatori e proteggono implementazioni proprietarie. Il checksum garantisce l'integrità del download.
Domande Comuni da Colloquio su Swift Package Manager
I colloqui tecnici per posizioni iOS includono frequentemente domande su SPM. Queste spaziano dall'uso base alle decisioni architetturali.
D: Come si differenzia SPM da CocoaPods e Carthage?
SPM si integra in Xcode e nella toolchain Swift senza strumenti esterni. CocoaPods usa un repository spec centrale e modifica la struttura del workspace Xcode. Carthage compila framework in uno step separato senza integrazione Xcode. SPM risolve le dipendenze e compila in un singolo processo unificato. La documentazione Apple sui pacchetti Swift copre gli strumenti ufficiali.
D: Cosa succede durante la risoluzione delle dipendenze?
SPM legge i manifest Package.swift ricorsivamente, costruendo un grafo delle dipendenze. Poi applica i vincoli di versione per trovare versioni compatibili per tutti i pacchetti. Il resolver scrive le versioni esatte in Package.resolved. I conflitti si verificano quando due pacchetti richiedono versioni incompatibili di una dipendenza condivisa.
D: Come si gestisce un conflitto di dipendenza diamond?
Quando il pacchetto A e B dipendono entrambi dal pacchetto C con requisiti di versione incompatibili, la risoluzione SPM fallisce. Le soluzioni includono: aggiornare un consumatore per supportare un range di versioni più ampio, fare fork del pacchetto restrittivo, o usare module aliasing se il conflitto è tra pacchetti diversi con lo stesso nome di modulo.
// Module aliasing for name conflicts
.target(
name: "MyApp",
dependencies: [
.product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
]
)D: Quando usare un binary target invece della distribuzione sorgente?
I binary target si adattano a SDK proprietari dove l'esposizione del sorgente è inaccettabile, grandi dipendenze dove il tempo di compilazione impatta la produttività degli sviluppatori, e librerie vendor precompilate. La distribuzione sorgente rimane preferibile per progetti open source e librerie interne dove il debug nelle dipendenze aggiunge valore.
Migrazione da CocoaPods a Swift Package Manager
La migrazione richiede la sostituzione delle voci del Podfile con riferimenti a pacchetti SPM. Non tutti i CocoaPods hanno equivalenti SPM, quindi verificare la disponibilità su Swift Package Index prima di iniziare.
# 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.0Dopo la migrazione, rimuovere Podfile, Podfile.lock e la directory Pods. Eseguire pod deintegrate per rimuovere le modifiche al workspace CocoaPods. Le dichiarazioni import nei file Swift rimangono invariate.
Best Practice SPM per App di Produzione
- Pinnare le versioni major con
from:per stabilità ricevendo aggiornamenti minor e patch - Committare
Package.resolvedper garantire build riproducibili in tutto il team - Usare pacchetti locali durante lo sviluppo attivo, passando a URL remoti prima del merge
- Separare le dipendenze solo per test usando
testTargetper evitare di includerle nelle build di release - Documentare la versione minima Swift tools all'inizio del manifest:
// swift-tools-version: 5.10 - Validare le build dei pacchetti su CI prima di taggare le release
Il commento // swift-tools-version: deve apparire nella prima riga di Package.swift. Determina quale versione dell'API PackageDescription usa il manifest. Swift 6.0 ha aggiunto flessibilità per permettere questo commento in righe successive per header di licenza.
Punti Chiave per Sviluppatori iOS che Usano SPM
- SPM si integra nativamente in Xcode, eliminando l'overhead di setup di CocoaPods e Carthage
- Il manifest
Package.swiftusa codice Swift, permettendo dichiarazioni di dipendenze type-checked - I requisiti di versione supportano range di semantic versioning, versioni esatte e riferimenti a branch
Package.resolvedblocca le versioni delle dipendenze per build riproducibili- Swift 6.2 ha aggiunto language mode per target e impostazioni rigorose di memory safety
- Swift 6.3 ha introdotto la generazione SBOM per documentazione di conformità
- I binary target distribuiscono XCFramework precompilati quando la distribuzione sorgente non è praticabile
- Le domande da colloquio si concentrano su conflitti di risoluzione, strategie di migrazione e trade-off architetturali tra SPM e alternative
Per una preparazione completa ai colloqui iOS, consultare i moduli su SwiftUI state management e protocol-oriented programming su SharpSkill.
Inizia a praticare!
Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.
Sapresti trovare il bug in iOS?
Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Scritto da
Anthony Fillion-MailletFondatore di SharpSkill
Sviluppatore fullstack da oltre 10 anni. Guida SharpSkill e risponde di tutto ciò che vi viene pubblicato.
Aggiornato il 20 settembre 2026
Tag
Condividi
Articoli correlati

Lavoro sviluppatore iOS 2026: dove cercare, stipendi e preparazione ai colloqui
Il mercato del lavoro per sviluppatori iOS nel 2026: dove trovare offerte, fasce salariali attuali e come prepararsi efficacemente ai colloqui tecnici.

Combine vs async/await in Swift: Pattern di Migrazione Progressiva
Guida completa alla migrazione da Combine ad async/await in Swift: strategie progressive, pattern di bridging e coesistenza dei paradigmi nelle codebase iOS.

Domande di colloquio sull'accessibilità iOS nel 2026: VoiceOver e Dynamic Type
Preparati ai colloqui iOS con domande chiave sull'accessibilità: VoiceOver, Dynamic Type, trait semantici e audit.