# 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. - Published: 2026-09-20 - Updated: 2026-09-20 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- 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. > **Funkcje SPM** > > 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. ```swift // Package.swift 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. ```bash # Tworzenie pakietu biblioteki mkdir NetworkKit && cd NetworkKit swift package init --type=library # Wygenerowana struktura: # NetworkKit/ # ├── Package.swift # ├── Sources/ # │ └── NetworkKit/ # │ └── NetworkKit.swift # └── Tests/ # └── NetworkKitTests/ # └── NetworkKitTests.swift ``` Uruchomienie `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ść. ```swift // Package.swift 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. > **Zależności od gałęzi w produkcji** > > 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ść. ```swift // AppDelegate.swift 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. ```swift // Package.swift w pakiecie konsumującym 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. ## Publikowanie pakietu Swift na GitHub Publikowanie wymaga repozytorium Git z tagami wersji semantycznych. SPM traktuje tagi Git jako wersje wydań. [Swift Package Index](https://swiftpackageindex.com) automatycznie indeksuje pakiety publiczne. ```bash # 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](https://semver.org): 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. ```swift // Package.swift z funkcjami Swift 6.2+ 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. ```bash # 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. ```swift // Package.swift z celem binarnym 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.zip ``` Cele 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](https://developer.apple.com/documentation/xcode/swift-packages) 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. ```swift // 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](https://swiftpackageindex.com). ```ruby # Przed: Podfile pod 'Alamofire', '~> 5.9' pod 'SwiftyJSON', '~> 5.0' pod 'Kingfisher', '~> 7.0' ``` ```swift // 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.0 ``` Po 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.resolved` dla 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ń > **Wersja narzędzi Swift** > > 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.swift` uż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.resolved` blokuje 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](/technologies/ios/interview-questions/swiftui-state-management) i [programowanie zorientowane na protokoły](/technologies/ios/interview-questions/protocol-oriented-programming) na SharpSkill. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/ios/swift-package-manager-tutorial-2026