Swift Package Manager w 2026: Tworzenie, Publikowanie i Pytania Rekrutacyjne
Opanuj Swift Package Manager dzięki temu kompleksowemu poradnikowi. Naucz się tworzyć pakiety, zarządzać zależnościami, publikować biblioteki i przygotuj się do pytań rekrutacyjnych iOS dotyczących SPM.

Swift Package Manager (SPM) odpowiada za zarządzanie zależnościami i dystrybucję pakietów w projektach Swift. W przeciwieństwie do CocoaPods czy Carthage, SPM jest zintegrowany bezpośrednio z Xcode i toolchainem Swift, nie wymagając dodatkowej instalacji. Swift 6.2 i 6.3 wprowadzily ustawienia ścisłego bezpieczeństwa pamięci, domyślną izolację aktorów oraz nowy system Swift Build, czyniąc SPM definitywnym wyborem dla nowoczesnego rozwoju iOS.
Swift Package Manager rozwiązuje zależności, pobiera kod źródłowy, kompiluje moduły i linkuje je do finalnego binarnego pliku. Pojedynczy plik manifestu Package.swift definiuje wszystko: zależności, cele, produkty i ustawienia budowania.
Struktura i składnia manifestu Package.swift
Każdy pakiet Swift zaczyna się od pliku Package.swift w katalogu głównym repozytorium. Ten manifest wykorzystuje kod Swift do deklarowania struktury pakietu, zależności i konfiguracji budowania.
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"]
)
]
)Tablica platforms określa minimalne wersje docelowe wdrożenia. Sekcja products definiuje, co inne pakiety mogą importować. Sekcja targets wymienia jednostki kompilacji z ich odpowiednimi zależnościami.
Tworzenie pakietu Swift z wiersza poleceń
Polecenie swift package init tworzy szkielet nowego pakietu ze standardową strukturą katalogów. Flaga --type określa, czy pakiet produkuje bibliotekę czy plik wykonywalny.
# Tworzenie pakietu biblioteki
mkdir NetworkKit && cd NetworkKit
swift package init --type=library
# Wygenerowana struktura:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │ └── NetworkKit/
# │ └── NetworkKit.swift
# └── Tests/
# └── NetworkKitTests/
# └── NetworkKitTests.swiftUruchomienie swift build kompiluje pakiet. Uruchomienie swift test wykonuje zestaw testów. Oba polecenia wykorzystują konfigurację z Package.swift bez dodatkowej konfiguracji.
Wymagania wersji zależności i ich rozwiązywanie
SPM obsługuje trzy strategie specyfikacji wersji: dokładna wersja, zakres wersji oraz odniesienie do gałęzi lub commita. Wybór wpływa na odtwarzalność i elastyczność.
dependencies: [
// Wersjonowanie semantyczne: od 5.9.0 do następnej głównej
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
// Dokładna wersja: blokada na 5.9.1
.package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
// Zakres wersji: od 5.8.0 do 5.9.9
.package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
// Odniesienie do gałęzi: do rozwoju
.package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
// Odniesienie do commita: przypięty do konkretnego commita
.package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]Plik Package.resolved rejestruje dokładne wersje rozwiązane podczas rozwiązywania zależności. Ten plik powinien być dodany do kontroli wersji dla odtwarzalnych budowań wśród członków zespołu i systemów CI.
Odniesienia do gałęzi i commitów omijają wersjonowanie semantyczne. Użycie branch: "main" w aplikacji produkcyjnej oznacza, że każdy push do main może zepsuć budowanie. Odniesienia do gałęzi należy rezerwować dla aktywnego rozwoju przeciwko niewydanym funkcjom.
Dodawanie pakietów do projektu Xcode
Xcode integruje SPM poprzez menu File. Należy przejść do File, następnie Add Package Dependencies. Wprowadza się URL repozytorium, wybiera regułę wersji i określa, które cele powinny linkować zależność.
import UIKit
import Alamofire // Dostępne po dodaniu przez 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 przechowuje odniesienia do pakietów w pliku .xcodeproj, a rozwiązane wersje w Package.resolved w katalogu głównym projektu. Folder Derived Data buforuje pobrane pakiety.
Rozwój lokalnych pakietów z zależnościami ścieżkowymi
Podczas rozwoju wskazanie na lokalną ścieżkę zamiast zdalnego URL umożliwia szybką iterację bez publikowania wersji pośrednich. Ta technika sprawdza się w konfiguracjach monorepo i podczas rozwoju funkcji.
dependencies: [
// Lokalna ścieżka do rozwoju
.package(path: "../NetworkKit"),
// Zdalny URL do wydania
// .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]Przełączanie między lokalnymi a zdalnymi zależnościami odbywa się poprzez zakomentowanie nieaktywnej linii. Xcode i CLI Swift rozwiązują zależności ścieżkowe względem pakietu konsumującego.
Gotowy na rozmowy o iOS?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Publikowanie pakietu Swift na GitHub
Publikowanie wymaga repozytorium Git z tagami wersji semantycznych. SPM traktuje tagi Git jako wersje wydań. Swift Package Index automatycznie indeksuje pakiety publiczne.
# Inicjalizacja repozytorium i 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
# Tworzenie tagu wersji
git tag 1.0.0
git push origin 1.0.0
# Inne pakiety mogą teraz zależeć od:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")Należy przestrzegać konwencji wersjonowania semantycznego: zwiększać wersję główną dla zmian łamiących kompatybilność, mniejszą dla nowych funkcji i łatkę dla poprawek błędów. SPM zakłada przestrzeganie tych reguł przy rozwiązywaniu wymagań wersji from:.
Ustawienia pakietów w Swift 6.2 i 6.3
Swift 6.2 wprowadził konfigurację trybu językowego dla poszczególnych celów oraz ustawienia ścisłego bezpieczeństwa pamięci. Swift 6.3 dodaje integrację Swift Build jako opcjonalny system budowania.
import PackageDescription
let package = Package(
name: "SafeNetworkKit",
platforms: [.iOS(.v17)],
products: [
.library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
],
targets: [
.target(
name: "SafeNetworkKit",
swiftSettings: [
// Włączenie trybu językowego Swift 6 tylko dla tego celu
.swiftLanguageMode(.v6),
// Włączenie ścisłego sprawdzania bezpieczeństwa pamięci (SE-0458)
.enableExperimentalFeature("StrictMemorySafety"),
// Ustawienie domyślnej izolacji aktorów (SE-0466)
.enableExperimentalFeature("GlobalActorIsolation")
]
)
]
)Ustawienie swiftLanguageMode pozwala na stopniowe przyjmowanie funkcji Swift 6 w całej bazie kodu. Cele mogą używać różnych trybów językowych w ramach tego samego pakietu.
Generowanie SBOM dla zgodności z bezpieczeństwem
SE-0509 dodało natywne generowanie Software Bill of Materials w Swift 6.3. Dokumenty SBOM wymieniają wszystkie zależności i ich wersje do audytu bezpieczeństwa i zgodności regulacyjnej.
# Generowanie SBOM w formacie CycloneDX
swift build --sbom-spec cyclonedx
# Generowanie SBOM przy użyciu dedykowanej subkomendy
swift package generate-sbom --format spdx
# Wynik zawiera:
# - Nazwę i wersję pakietu
# - Wszystkie tranzytywne zależności
# - Informacje o licencjach
# - URL repozytoriów źródłowychŚrodowiska korporacyjne i kontrakty rządowe coraz częściej wymagają dokumentacji SBOM. Formaty CycloneDX i SPDX integrują się ze standardowymi narzędziami do skanowania podatności.
Cele binarne i dystrybucja XCFramework
Cele binarne umożliwiają dystrybucję prekompilowanych frameworków zamiast kodu źródłowego. XCFrameworks łączą binarki dla wielu platform i architektur.
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..."
)
]
)
// Generowanie sumy kontrolnej:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zipCele binarne skracają czas budowania dla konsumentów i chronią zastrzeżone implementacje. Suma kontrolna zapewnia integralność pobierania.
Typowe pytania rekrutacyjne dotyczące Swift Package Manager
Rozmowy techniczne na stanowiska iOS często zawierają pytania o SPM. Zakres obejmuje od podstawowego użycia po decyzje architektoniczne.
P: Czym SPM różni się od CocoaPods i Carthage?
SPM integruje się z Xcode i toolchainem Swift bez zewnętrznych narzędzi. CocoaPods używa centralnego repozytorium specyfikacji i modyfikuje strukturę workspace Xcode. Carthage buduje frameworki w osobnym kroku bez integracji z Xcode. SPM rozwiązuje zależności i buduje w jednym zunifikowanym procesie. Dokumentacja Apple dotycząca pakietów Swift obejmuje oficjalne narzędzia.
P: Co dzieje się podczas rozwiązywania zależności?
SPM rekurencyjnie odczytuje manifesty Package.swift, budując graf zależności. Następnie stosuje ograniczenia wersji, aby znaleźć kompatybilne wersje dla wszystkich pakietów. Resolver zapisuje dokładne wersje do Package.resolved. Konflikty występują, gdy dwa pakiety wymagają niekompatybilnych wersji wspólnej zależności.
P: Jak rozwiązać konflikt zależności diamentowej?
Gdy pakiet A i B oba zależą od pakietu C z niekompatybilnymi wymaganiami wersji, SPM nie może rozwiązać zależności. Rozwiązania obejmują: aktualizację jednego konsumenta do obsługi szerszego zakresu wersji, forkowanie restrykcyjnego pakietu lub użycie aliasów modułów, jeśli konflikt dotyczy różnych pakietów o tej samej nazwie modułu.
// Aliasowanie modułów dla konfliktów nazw
.target(
name: "MyApp",
dependencies: [
.product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
]
)P: Kiedy używać celu binarnego zamiast dystrybucji źródłowej?
Cele binarne sprawdzają się w zastrzeżonych SDK, gdzie ekspozycja źródła jest niedopuszczalna, dużych zależnościach gdzie czas kompilacji wpływa na produktywność deweloperów oraz prekompilowanych bibliotekach dostawców. Dystrybucja źródłowa pozostaje preferowana dla projektów open source i wewnętrznych bibliotek, gdzie debugowanie w zależnościach dodaje wartość.
Migracja z CocoaPods do Swift Package Manager
Migracja wymaga zastąpienia wpisów Podfile odniesieniami do pakietów SPM. Nie wszystkie CocoaPods mają odpowiedniki SPM, więc przed rozpoczęciem należy zweryfikować dostępność na Swift Package Index.
# Przed: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'// Po: Zależności pakietów w Xcode
// File > Add Package Dependencies dla każdego:
// 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.0Po migracji należy usunąć Podfile, Podfile.lock i katalog Pods. Uruchomienie pod deintegrate usuwa modyfikacje workspace CocoaPods. Instrukcje import w plikach Swift pozostają niezmienione.
Najlepsze praktyki SPM dla aplikacji produkcyjnych
- Przypinanie głównych wersji za pomocą
from:dla stabilności przy jednoczesnym otrzymywaniu mniejszych aktualizacji i łatek - Commitowanie
Package.resolveddla zapewnienia odtwarzalnych budowań w całym zespole - Używanie lokalnych pakietów podczas aktywnego rozwoju, przełączanie na zdalne URL przed mergowaniem
- Separowanie zależności tylko do testów za pomocą
testTarget, aby uniknąć ich dołączania do wydań - Dokumentowanie minimalnej wersji narzędzi Swift na górze manifestu:
// swift-tools-version: 5.10 - Walidowanie budowań pakietów na CI przed tagowaniem wydań
Komentarz // swift-tools-version: musi pojawić się w pierwszej linii Package.swift. Określa on, której wersji API PackageDescription używa manifest. Swift 6.0 dodał elastyczność pozwalającą na umieszczenie tego komentarza w kolejnych liniach dla nagłówków licencji.
Kluczowe wnioski dla deweloperów iOS używających SPM
- SPM integruje się natywnie z Xcode, eliminując narzut konfiguracji CocoaPods i Carthage
- Manifest
Package.swiftużywa kodu Swift, umożliwiając deklaracje zależności sprawdzane typowo - Wymagania wersji obsługują zakresy wersjonowania semantycznego, dokładne wersje i odniesienia do gałęzi
Package.resolvedblokuje wersje zależności dla odtwarzalnych budowań- Swift 6.2 dodał tryby językowe dla poszczególnych celów i ustawienia ścisłego bezpieczeństwa pamięci
- Swift 6.3 wprowadził generowanie SBOM dla dokumentacji zgodności
- Cele binarne dystrybuują prekompilowane XCFrameworks, gdy dystrybucja źródłowa jest niepraktyczna
- Pytania rekrutacyjne koncentrują się na konfliktach rozwiązywania, strategiach migracji i kompromisach architektonicznych między SPM a alternatywami
Dla kompleksowego przygotowania do rozmów iOS warto przejrzeć moduły zarządzanie stanem SwiftUI i programowanie zorientowane na protokoły na SharpSkill.
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Znajdziesz błąd w iOS?
Prawdziwy fragment kodu, ukryty błąd, jedna próba dziennie. Bez konta, żeby spróbować.

Autor:
Anthony Fillion-MailletZałożyciel SharpSkill
Programista fullstack od ponad 10 lat. Prowadzi SharpSkill i odpowiada za wszystko, co się tu ukazuje.
Zaktualizowano 20 września 2026
Udostępnij
Powiązane artykuły

CloudKit ze SwiftUI w 2026: wzorce synchronizacji między urządzeniami
Kompletny przewodnik wdrażania synchronizacji CloudKit ze SwiftUI: CKSyncEngine, integracja ze SwiftData, rozwiązywanie konfliktów i najlepsze praktyki dla iOS 2026.

Combine vs async/await w Swift: Wzorce Progresywnej Migracji
Kompletny przewodnik po migracji z Combine do async/await w Swift: progresywne strategie, wzorce mostkowania i współistnienie paradygmatów w bazach kodu iOS.

Pytania rekrutacyjne o dostępność iOS w 2026: VoiceOver i Dynamic Type
Przygotuj się do rozmów iOS z kluczowymi pytaniami o dostępność: VoiceOver, Dynamic Type, semantyczne traits i audyty.