SPM (Swift Package Manager) — a Swift ökoszisztéma beépített csomagkezelője, amelyet az Apple fejlesztett a harmadik féltől származó könyvtárak csatlakoztatásának, építésének és frissítésének automatizálására. Az SPM a Swift 3.0 (2016) verziótól kezdve a Swift fordító részét képezi, és nem igényel külön telepítést. A CocoaPods-tól és Carthage-től eltérően az SPM közvetlenül integrálódik a fordítóval és az Xcode-dal, így ez a szabványos függőségkezelő eszköz a modern Swift projektekben. A cikkben áttekintjük a Package.swift felépítését, az SPM parancsokat, saját csomagok írását és a migrációt alternatív kezelőkből.
Főbb pontok
SPM (Swift Package Manager) — a hivatalos csomagkezelő a Swift nyelvhez, beépítve a swiftc fordítóba és az Xcode fejlesztői környezetbe. Lehetővé teszi a fejlesztők számára, hogy harmadik féltől származó könyvtárakat csatlakoztassanak, kezeljék azok verzióit, és saját csomagokat tegyenek közzé. Az SPM először a Swift 3.0-ban (2016. szeptember) jelent meg parancssori eszközként, és az Xcode 11-től (2019) kezdve teljes mértékben integrálódott a grafikus felülettel — a függőségek most a File → Add Packages menüponton keresztül adhatók hozzá.
Az SPM automatikusan letölti a függőségek forráskódját Git-tárakból, párhuzamosan építi őket a fő projekttel, és gyorsítótárazza az eredményeket, hogy az újraépítések gyorsabbak legyenek. A CocoaPods-tól eltérően az SPM nem hoz létre külön munkaterületet (xcworkspace) — a függőségek a fő Xcode-projekt részévé válnak. A Swift.org Developer Survey (2024) felmérés szerint az iOS-fejlesztők 67%-a használja az SPM-et, így ez a legnépszerűbb függőségkezelő eszköz a Swift ökoszisztémában.
Az SPM három platformot támogat: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) és szerver Swift (Vapor, Kitura). Linuxon az SPM teljes mértékben parancssoron keresztül működik, Xcode nélkül.
Az SPM három kulcsfogalom köré épül: csomagok (packages), termékek (products) és célok (targets). A csomag egy Git-tár a Package.swift manifeszttel. A termék az építés eredménye (könyvtár vagy végrehajtható fájl). A cél egy modul a csomagon belül, amely egy építési egységgé fordul.
Amikor a fejlesztő függőséget ad hozzá a Package.swift-hez, az SPM a következő lépéseket hajtja végre:
~Library/Caches/org.swift.swiftpm/ címbe.A Package.resolved fájl rögzíti az összes függőség pontos verzióját, hogy a fejlesztői csapat azonos könyvtárkészlettel dolgozzon. Ezt a fájlt hozzá kell adni a verziókezelő rendszerhez (git).
Az SPM fő előnye az alternatívákkal szemben — nincs központi nyilvántartás. A csomagok bármely nyilvános Git-tárban lehetnek: GitHub, GitLab, Bitbucket, valamint a vállalat saját Git-szerverein. A Swift 5.2 verziótól kezdve az SPM támogatja a bináris függőségeket (binary targets) — zárt könyvtárakat, amelyek XCFrameworkön keresztül terjeszthetők forráskód megadása nélkül.
Package.swift — egy Swift fájl, amely leírja a csomag szerkezetét és függőségeit. A fájl magában Swift-ben íródik (nem JSON, nem YAML), ami lehetővé teszi feltételes logika, számított konstansok és függvények használatát a manifeszten belül.
A Package.swift alapstruktúrája:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyLibrary",
platforms: [
.iOS(.v16),
.macOS(.v13)
],
products: [
.library(
name: "MyLibrary",
targets: ["MyLibrary"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
.package(url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"),
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
"Alamofire",
"Kingfisher"
]
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"]
),
]
)
Tekintsük át a kulcselemeket:
// swift-tools-version: 5.9 — irányelv, amely jelzi az SPM verzióját; a manifeszt elérhető szintaxisa ettől függ.name — a csomag neve, amely megjelenik az Xcode-ban és függőségi hivatkozásokban használatos.platforms — a platformok minimális verziói; az SPM nem engedi a csomag építését régebbi OS-verzión.products — amit a csomag "exportál": könyvtár (.library) vagy végrehajtható fájl (.executable).dependencies — külső csomagok listája URL-lel és verzióval; támogatottak: from:, exact:, branch:, revision:.targets — építési célok; minden cél tartalmazza a függőségek, erőforrások és swift fájlok listáját a megfelelő könyvtárból (Sources/TargetName/).Példa pontos verzió, ág és commit megadására:
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git",
exact: "1.17.3"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",
branch: "main"),
.package(url: "https://github.com/apple/swift-log.git",
revision: "e5c6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4"),
]
A Swift 5.9 verziótól kezdve a Package.swift támogatja a static/framework és linkerSettings elemeket, ami lehetővé teszi a linkelés pontosabb konfigurálását statikus és dinamikus könyvtárak esetén.
A Swift Package Manager parancskészletet biztosít a terminálon keresztüli munkához. A parancsok a csomag gyökérkönyvtárából (ahol a Package.swift található) futtathatók.
# Új csomag létrehozása könyvtárral
swift package init --type library
# Végrehajtható csomag létrehozása (konzolalkalmazás)
swift package init --type executable
# Projekt építése
swift build
# Építés release konfigurációban
swift build -c release
# Tesztek futtatása
swift test
# Adott teszt futtatása
swift test --filter "MyLibraryTests/testExample"
# Függőségek letöltése és feloldása
swift package resolve
# Függőségek frissítése a legújabb elérhető verziókra
swift package update
# Függőségi gráf megjelenítése
swift package show-dependencies
# Építési gyorsítótár törlése
swift package clean
# Xcode-projekt generálása (Xcode 11 előtt)
swift package generate-xcodeproj
Az Xcode-on belüli munka során a legtöbb parancs automatikusan végrehajtódik: a függőségek a projekt megnyitásakor feloldódnak, az építés a ⌘B, a tesztek a ⌘U billentyűkkel indulnak. A terminálparancsok ismerete azonban szükséges a CI/CD pipeline-okhoz (GitHub Actions, GitLab CI, Jenkins), ahol az Xcode nem érhető el.
A swift package resolve parancs létrehozza vagy frissíti a Package.resolved fájlt. Ez a fájl rögzíti az összes függőség pontos verzióját, beleértve a tranzitívakat is, és hozzá kell adni a git-hez. Javasolt a swift package update futtatása minden új funkcióág előtt, hogy a könyvtárak aktuális verzióival dolgozzon.
Saját SPM-csomag létrehozása hasznos az üzleti logika elkülönítéséhez többmodulos projektekben és open-source könyvtárak közzétételéhez. Tekintsük át a folyamatot lépésről lépésre.
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
A swift package init parancs a következő struktúrát hozza létre:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
Az SPM automatikusan beolvassa a Sources/ és Tests/ könyvtárakat: a Sources-on belüli alkönyvtárak mindegyike egy cél (target) lesz.
Adjunk hozzá függőségeket, és konfiguráljuk a célplatformokat:
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyNetworkKit",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(
name: "MyNetworkKit",
targets: ["MyNetworkKit"]
),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"),
],
targets: [
.target(
name: "MyNetworkKit",
dependencies: ["Alamofire"]
),
.testTarget(
name: "MyNetworkKitTests",
dependencies: ["MyNetworkKit"]
),
]
)
// Sources/MyNetworkKit/MyNetworkKit.swift
import Foundation
import Alamofire
public struct NetworkClient {
private let session: Session
public init() {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
self.session = Session(configuration: configuration)
}
public func fetchData(from url: String) async throws -> Data {
let response = try await session.request(url).serializingData().value
return response
}
}
Tolja fel a csomagot a Git-tárba, és hozzon létre SemVer-címkét:
git init
git add .
git commit -m "Initial commit: MyNetworkKit"
git remote add origin https://github.com/username/MyNetworkKit.git
git push -u origin main
git tag 1.0.0
git push --tags
Ezt követően bármely fejlesztő csatlakoztathatja a csomagot a .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0") segítségével.
Az Alamofire a legnépszerűbb HTTP-kliens Swift-hez. Adjuk hozzá SPM-en keresztül, és hajtsunk végre egy GET-kérést.
import Alamofire
func fetchUsers() {
AF.request("https://jsonplaceholder.typicode.com/users")
.validate()
.responseDecodable(of: [User].self) { response in
switch response.result {
case .success(let users):
print("\(users.count) felhasználó érkezett")
case .failure(let error):
print("Hiba: \(error.localizedDescription)")
}
}
}
A Swinject könyvtár DI-konténert biztosít Swift-hez. A .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0") segítségével csatlakoztatható.
import Swinject
let container = Container()
container.register(NetworkServiceProtocol.self) { _ in NetworkService() }
container.register(DataRepositoryProtocol.self) { r in
DataRepository(networkService: r.resolve(NetworkServiceProtocol.self)!)
}
let repository = container.resolve(DataRepositoryProtocol.self)
repository?.loadData()
A swift-log csomag az Apple-től — egységes naplózási API, amely több háttérrendszert támogat (OSLog, konzol, fájlok).
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("Hálózati kérés elindult", metadata: [
"url": "\(requestURL)",
"method": "GET"
])
logger.warning("Válaszidő meghaladta a 2 másodpercet")
logger.error("Kapcsolódási hiba: nincs internet")
Ez a három példa lefedi az SPM tipikus használati eseteit: HTTP-kliensek, DI-konténerek és rendszerinfrastruktúra. A könyvtárak kiválasztása nem véletlen — az Alamofire, Swinject és swift-log a GitHub legtöbb csillaggal rendelkező Swift-csomagjainak top 20-ában található.
Ha a projekt CocoaPods-ot vagy Carthage-t használ, az SPM-re való migráció néhány lépésben történik. A folyamat biztonságos: az SPM-függőségek együtt élhetnek a CocoaPods-szal és Carthage-dzsel ugyanabban a projektben, lehetővé téve a fokozatos migrációt.
.xcworkspace-et, nyissa meg a .xcodeproj-t, és hajtsa végre a Clean Build Folder műveletet.rm -rf Carthage/ terminálban.2025-re az SPM a népszerű Swift könyvtárak túlnyomó többségét támogatja. Kivételek néhány modultérkép (modulemap) nélküli ObjC-keretrendszer. Ha egy könyvtár még nem támogatja az SPM-et — ellenőrizze az Installation szakaszt a README-ben; a szerzők többsége már hozzáadta az SPM-támogatást a legújabb verziókban.
Gyakran ismételt kérdések
Az SPM be van építve a Swift fordítóba és az Xcode-ba, nem igényel telepítést gem-en vagy Homebrew-n keresztül. A CocoaPods központi Specs nyilvántartást használ, és külön munkaterületet hoz létre. A Carthage keretrendszereken keresztül működik, projekt-integráció nélkül. Az SPM az egyetlen fordítószinten integrált kezelő: a függőségek feloldódnak, gyorsítótárazódnak és párhuzamosan épülnek a fő kóddal.
Igen, az SPM támogatja a Swift + Objective-C vegyes projekteket. Az ObjC-fájlok az SPM-csomagon belül automatikusan bekerülnek az Umbrella Header-be, feltéve, hogy a modulemap helyes. Az SPM azonban nem támogatja a modultérképpel nem rendelkező statikus ObjC könyvtárakat. Javasolt az ObjC könyvtárakat SPM-en keresztül csak akkor csatlakoztatni, ha rendelkeznek modulemap-pel vagy tiszta C-ben íródtak.
Az SPM szemantikus verziókezelést (SemVer) használ. Ha az A csomag Alamofire 5.8+-t, a B csomag pedig Alamofire 5.9+-t igényel, az SPM az 5.9.x verziót választja, amely mindkettőnek megfelel. Ha az ütközés feloldhatatlan (az egyik csomag 5.x-et, a másik 6.x-et igényel), az SPM hibát jelez. Ebben az esetben frissíteni kell az egyik csomagot, vagy a függőséget mindkét követelménnyel kompatibilis verzióra kell váltani.
macOS rendszeren: ~Library/Caches/org.swift.swiftpm/ és ~/Library/Developer/Xcode/DerivedData/. Linuxon: ~cache/swiftpm/. Az építés során az SPM gyorsítótárazza a forráskódot és a lefordított objektumfájlokat. A gyorsítótár teljes törléséhez futtassa a swift package reset parancsot — ez a parancs törli a függőségi gyorsítótárat és a DerivedData-t az aktuális projekthez.
Igen, a Swift 5.2-től kezdve az SPM támogatja a bináris célokat (binary targets). A zárt könyvtár XCFrameworkként kerül szállításra, a Package.swift-ben pedig meg kell adni az .xcframework elérési útját. A forráskód nem kerül nyilvánosságra. A bináris cél a .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework") segítségével adható meg. Ez lehetővé teszi kereskedelmi SDK-k csatlakoztatását a licencszerződések megsértése nélkül.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is