SPM (Swift Package Manager) — Apple tərəfindən üçüncü tərəf kitabxanalarının qoşulmasını, qurulmasını və yenilənməsini avtomatlaşdırmaq üçün hazırlanmış Swift ekosisteminin daxili paket meneceridir. SPM Swift 3.0 (2016-cı il) versiyasından etibarən Swift kompilyatorunun tərkibinə daxildir və ayrıca quraşdırma tələb etmir. CocoaPods və Carthage-dən fərqli olaraq, SPM birbaşa kompilyator və Xcode ilə inteqrasiya olunub, bu da onu müasir Swift layihələrində asılılıqların idarə edilməsi üçün standart alətə çevirir. Məqalədə Package.swift quruluşu, SPM əmrləri, öz paketlərin yazılması və alternativ menecerlərdən miqrasiyanı nəzərdən keçirəcəyik.
Əsas məqamlar
SPM (Swift Package Manager) — Swift dili üçün rəsmi paket meneceri, swiftc kompilyatoruna və Xcode inkişaf mühitinə daxildir. O, proqramçılara üçüncü tərəf kitabxanalarını qoşmağa, onların versiyalarını idarə etməyə və öz paketlərini nəşr etməyə imkan verir. SPM ilk dəfə Swift 3.0-da (sentyabr 2016) komanda sətri aləti kimi ortaya çıxdı, Xcode 11-dən (2019) isə qrafik interfeyslə tam inteqrasiya əldə etdi — indi asılılıqlar File → Add Packages menyusu vasitəsilə əlavə edilir.
SPM asılılıqların mənbə kodunu Git repozitoriyalarından avtomatik endirir, onları əsas layihə ilə paralel qurur və nəticələri keşləyir ki, təkrar qurmalar daha sürətli olsun. CocoaPods-dan fərqli olaraq, SPM ayrıca workspace (xcworkspace) yaratmır — asılılıqlar əsas Xcode layihəsinin bir hissəsi olur. Swift.org Developer Survey (2024) sorğusuna görə, SPM-dən iOS tərtibatçılarının 67%-i istifadə edir, bu da onu Swift ekosistemində asılılıqların idarə edilməsi üçün ən populyar alət edir.
SPM üç platformanı dəstəkləyir: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) və server Swift (Vapor, Kitura). Linux-da SPM Xcode olmadan tamamilə komanda sətri vasitəsilə işləyir.
SPM üç əsas konsepsiya ətrafında qurulub: paketlər (packages), məhsullar (products) və hədəflər (targets). Paket — Package.swift manifesti olan Git repozitoriyasıdır. Məhsul — qurma nəticəsidir (kitabxana və ya icra olunan fayl). Hədəf — paket daxilində qurma vahidinə kompilyasiya olunan moduldur.
Proqramçı Package.swift-ə asılılıq əlavə etdikdə, SPM aşağıdakı addımları yerinə yetirir:
~Library/Caches/org.swift.swiftpm/-də saxlayır.Package.resolved faylı bütün asılılıqların dəqiq versiyalarını təsbit edir ki, tərtibatçı komandası eyni kitabxana dəsti ilə işləsin. Bu fayl versiya nəzarət sisteminə (git) əlavə edilməlidir.
SPM-nin analoqlarından əsas üstünlüyü mərkəzləşdirilmiş reyestrin olmamasıdır. Paketlər istənilən ictimai Git repozitoriyasında yerləşə bilər: GitHub, GitLab, Bitbucket, həmçinin şirkətin öz Git serverlərində. Swift 5.2 versiyasından SPM ikili asılılıqları (binary targets) dəstəkləyir — mənbə kodu təqdim edilmədən XCFramework vasitəsilə yayılan qapalı kitabxanalar.
Package.swift — paketin strukturunu və onun asılılıqlarını təsvir edən Swift faylıdır. Fayl Swift dilində yazılır (JSON deyil, YAML deyil), bu da manifest daxilində şərti məntiq, hesablanan sabitlər və funksiyalardan istifadə etməyə imkan verir.
Package.swift-in əsas strukturu:
// 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"]
),
]
)
Əsas elementləri nəzərdən keçirək:
// swift-tools-version: 5.9 — SPM versiyasını göstərən direktiv; manifestin mövcud sintaksisi bundan asılıdır.name — Xcode-da göstərilən və asılılıq keçidlərində istifadə olunan paket adı.platforms — platformaların minimal versiyaları; SPM köhnə ƏS versiyasında paketi qurmağa icazə verməz.products — paketin "ixrac etdiyi" şey: kitabxana (.library) və ya icra olunan fayl (.executable).dependencies — URL və versiya ilə xarici paketlərin siyahısı; from:, exact:, branch:, revision: dəstəklənir.targets — qurma hədəfləri; hər hədəf asılılıqların, resursların və müvafiq kataloqdan (Sources/TargetName/) swift fayllarının siyahısını ehtiva edir.Dəqiq versiya, budaq və kommit göstərilməsi nümunəsi:
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"),
]
Swift 5.9 versiyasından Package.swift-ə static/framework və linkerSettings dəstəyi əlavə edilib, bu da statik və dinamik kitabxanalar üçün linkləməni daha dəqiq konfiqurasiya etməyə imkan verir.
Swift Package Manager terminal vasitəsilə işləmək üçün bir sıra əmrlər təqdim edir. Əmrlər paketin kök kataloqundan (Package.swift-in olduğu yerdən) işə salınır.
# Kitabxana ilə yeni paket yarat
swift package init --type library
# İcra olunan paket yarat (konsol tətbiqi)
swift package init --type executable
# Layihəni qur
swift build
# Buraxılış konfiqurasiyasında qur
swift build -c release
# Testləri işə sal
swift test
# Xüsusi testi işə sal
swift test --filter "MyLibraryTests/testExample"
# Asılılıqları endir və həll et
swift package resolve
# Asılılıqları ən son mövcud versiyalara yenilə
swift package update
# Asılılıq qrafını göstər
swift package show-dependencies
# Qurma keşini təmizlə
swift package clean
# Xcode layihəsi yarat (Xcode 11-ə qədər)
swift package generate-xcodeproj
Xcode daxilində işləyərkən bu əmrlərin əksəriyyəti avtomatik yerinə yetirilir: asılılıqlar layihə açıldıqda həll edilir, qurma ⌘B, testlər ⌘U ilə işə salınır. Lakin terminal əmrlərini bilmək CI/CD pipeline-ları (GitHub Actions, GitLab CI, Jenkins) üçün zəruridir, çünki Xcode mövcud deyil.
swift package resolve əmri Package.resolved faylını yaradır və ya yeniləyir. Bu fayl bütün asılılıqların, o cümlədən tranzitiv olanların dəqiq versiyalarını təsbit edir və git-ə əlavə edilməlidir. Hər yeni feature budağından əvvəl swift package update-i işə salmaq tövsiyə olunur ki, kitabxanaların cari versiyaları ilə işləyəsiniz.
Öz SPM paketinizi yaratmaq çoxmodullu layihələrdə biznes məntiqini inkapsulyasiya etmək və open-source kitabxanaları nəşr etmək üçün faydalıdır. Addım-addım prosesə baxaq.
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
swift package init əmri aşağıdakı strukturu yaradır:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
SPM avtomatik olaraq Sources/ və Tests/ kataloqlarını skan edir: Sources daxilindəki hər altkataloq hədəfə (target) uyğun gəlir.
Asılılıqlar əlavə edək və hədəf platformaları konfiqurasiya edək:
// 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
}
}
Paketi Git repozitoriyasına göndərin və SemVer teqi yaradın:
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
Bundan sonra istənilən tərtibatçı paketinizi .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0") vasitəsilə qoşa bilər.
Alamofire — Swift üçün ən məşhur HTTP müştərisidir. Onu SPM vasitəsilə əlavə edək və GET sorğusu yerinə yetirək.
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) istifadəçi əldə edildi")
case .failure(let error):
print("Xəta: \(error.localizedDescription)")
}
}
}
Swinject kitabxanası Swift üçün DI konteyneri təqdim edir. .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0") vasitəsilə qoşulur.
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()
Apple-dan swift-log paketi — çoxlu backend-ləri (OSLog, konsol, fayllar) dəstəkləyən vahid loqlama API-sidir.
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("Şəbəkə sorğusu başladı", metadata: [
"url": "\(requestURL)",
"method": "GET"
])
logger.warning("Cavab müddəti 2 saniyəni keçdi")
logger.error("Qoşulma xətası: internet yoxdur")
Bu üç nümunə SPM-nin tipik istifadə ssenarilərini əhatə edir: HTTP müştəriləri, DI konteynerləri və sistem infrastrukturu. Kitabxanaların seçimi təsadüfi deyil — Alamofire, Swinject və swift-log GitHub-da ən çox ulduz toplamış Swift paketlərinin ilk 20-liyinə daxildir.
Layihə CocoaPods və ya Carthage istifadə edirsə, SPM-ə miqrasiya bir neçə addımda yerinə yetirilir. Proses təhlükəsizdir: SPM asılılıqları CocoaPods və Carthage ilə eyni layihədə birgə mövcud ola bilər, bu da tədricən miqrasiyaya imkan verir.
.xcworkspace-i silin, .xcodeproj-u açın və Clean Build Folder edin.rm -rf Carthage/.2025-ci ilə olan məlumata görə, SPM populyar Swift kitabxanalarının böyük əksəriyyətini dəstəkləyir. İstisnalar modul xəritəsi (modulemap) olmayan bəzi ObjC freymvorklarıdır. Kitabxana hələ SPM-i dəstəkləmirsə — onun README faylında Installation bölməsini yoxlayın; müəlliflərin əksəriyyəti ən son versiyalarda SPM dəstəyi əlavə edib.
Tez-tez verilən suallar
SPM Swift kompilyatoru və Xcode-a daxildir, gem və ya Homebrew vasitəsilə quraşdırma tələb etmir. CocoaPods mərkəzləşdirilmiş Specs reyestrindən istifadə edir və ayrıca workspace yaradır. Carthage layihə ilə inteqrasiya olunmadan freymvorklar vasitəsilə işləyir. SPM kompilyator səviyyəsində inteqrasiya olunmuş yeganə menecerdir: asılılıqlar həll edilir, keşlənir və əsas kodla paralel qurulur.
Bəli, SPM Swift + Objective-C qarışıq layihələrini dəstəkləyir. SPM paketi daxilindəki ObjC faylları düzgün modulemap şərti ilə avtomatik olaraq Umbrella Header-a daxil olur. Lakin SPM modul xəritəsi olmayan statik ObjC kitabxanalarını dəstəkləmir. ObjC kitabxanalarını SPM vasitəsilə yalnız modulemap təqdim etdikdə və ya təmiz C dilində yazıldıqda qoşmaq tövsiyə olunur.
SPM semantik versiyalaşdırmadan (SemVer) istifadə edir. Əgər A paketi Alamofire 5.8+ tələb edirsə, B paketi isə Alamofire 5.9+ tələb edirsə, SPM hər ikisini təmin edən 5.9.x versiyasını seçəcək. Əgər konflikt həll olunmazsa (bir paket 5.x, digəri 6.x tələb edir), SPM xəta bildirəcək. Bu halda paketlərdən birini yeniləmək və ya asılılığı hər iki tələbə uyğun versiyaya dəyişmək lazımdır.
macOS-da: ~Library/Caches/org.swift.swiftpm/ və ~/Library/Developer/Xcode/DerivedData/. Linux-da: ~cache/swiftpm/. Qurma zamanı SPM mənbə kodunu və kompilyasiya olunmuş obyekt fayllarını keşləyir. Keşi tam təmizləmək üçün swift package reset əmrini yerinə yetirin — bu əmr cari layihə üçün asılılıq keşini və DerivedData-nı silir.
Bəli, Swift 5.2-dən SPM ikili hədəfləri (binary targets) dəstəkləyir. Qapalı kitabxana XCFramework kimi təqdim edilir, Package.swift-də isə .xcframework-ə yol göstərilir. Mənbə kodu açıqlanmır. Binary target .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework") vasitəsilə göstərilir. Bu, lisenziya müqavilələrini pozmadan kommersiya SDK-larını qoşmağa imkan verir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun