SPM (Swift Package Manager), Apple tarafından üçüncü taraf kütüphanelerin bağlanması, derlenmesi ve güncellenmesini otomatikleştirmek için geliştirilen, Swift ekosistemine yerleşik bir paket yöneticisidir. SPM, sürüm 3.0'dan (2016) itibaren Swift derleyicisinin bir parçasıdır ve ayrı bir kurulum gerektirmez. CocoaPods ve Carthage'un aksine SPM, doğrudan derleyici ve Xcode ile entegre olur ve modern Swift projelerinde standart bağımlılık yönetim aracı haline gelir. Bu makalede Package.swift'in yapısını, SPM komutlarını, özel paket oluşturmayı ve alternatif yöneticilerden geçişi inceleyeceğiz.
Önemli Noktalar
SPM (Swift Package Manager), Swift dili için resmi paket yöneticisidir ve swiftc derleyicisi ile Xcode geliştirme ortamına yerleşiktir. Geliştiricilerin üçüncü taraf kütüphaneler eklemesine, sürümlerini yönetmesine ve kendi paketlerini yayınlamasına olanak tanır. SPM ilk olarak Swift 3.0'da (Eylül 2016) bir komut satırı aracı olarak ortaya çıktı ve Xcode 11'den (2019) itibaren grafik arayüzle tam entegrasyon sağladı — bağımlılıklar artık File → Add Packages menüsü aracılığıyla ekleniyor.
SPM, bağımlılıkların kaynak kodunu otomatik olarak Git depolarından indirir, ana projeyle paralel olarak derler ve sonuçları önbelleğe alarak sonraki derlemelerin daha hızlı olmasını sağlar. CocoaPods'un aksine SPM, ayrı bir çalışma alanı (xcworkspace) oluşturmaz — bağımlılıklar ana Xcode projesinin bir parçası haline gelir. Swift.org Developer Survey (2024) anketine göre, iOS geliştiricilerinin %67'si SPM kullanmaktadır ve bu, onu Swift ekosistemindeki en popüler bağımlılık yönetim aracı yapmaktadır.
SPM üç platformu destekler: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux) ve sunucu tarafı Swift (Vapor, Kitura). Linux'ta SPM, Xcode olmadan tamamen komut satırı üzerinden çalışır.
SPM üç temel kavram etrafında inşa edilmiştir: paketler (packages), ürünler (products) ve hedefler (targets). Paket, Package.swift manifestosu olan bir Git deposudur. Ürün, derleme sonucudur (bir kütüphane veya çalıştırılabilir dosya). Hedef, paket içinde bir derleme birimine derlenen bir modüldür.
Bir geliştirici Package.swift'e bir bağımlılık eklediğinde, SPM aşağıdaki adımları gerçekleştirir:
~Library/Caches/org.swift.swiftpm/ konumunda saklar.Package.resolved dosyası, geliştirme ekibinin aynı kütüphane setiyle çalışması için tüm bağımlılıkların tam sürümlerini sabitler. Bu dosya sürüm kontrolüne (git) eklenmelidir.
SPM'nin alternatiflere göre önemli bir avantajı merkezi bir kayıt gerektirmemesidir. Paketler herhangi bir herkese açık Git deposunda bulunabilir: GitHub, GitLab, Bitbucket ve şirketin özel Git sunucularında. Swift 5.2'den itibaren SPM, kaynak kodu sağlamadan XCFramework olarak dağıtılan ikili bağımlılıkları (binary targets) destekler.
Package.swift, paket yapısını ve bağımlılıklarını tanımlayan bir Swift dosyasıdır. Dosya Swift'in kendisinde yazılır (JSON veya YAML değil), bu da manifest içinde koşullu mantık, hesaplanmış sabitler ve işlevler kullanılmasına olanak tanır.
Package.swift'in temel yapısı:
// 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"]
),
]
)
Anahtar elemanları inceleyelim:
// swift-tools-version: 5.9 — SPM sürümünü belirten yönerge; kullanılabilir manifest sözdizimi buna bağlıdır.name — Xcode'da görüntülenen ve bağımlılık bağlantılarında kullanılan paket adı.platforms — Minimum platform sürümleri; SPM, paketin daha eski bir işletim sistemi sürümünde derlenmesine izin vermez.products — Paketin "dışa aktardığı" şey: bir kütüphane (.library) veya çalıştırılabilir (.executable).dependencies — URL ve sürümle birlikte harici paketlerin listesi; from:, exact:, branch:, revision: destekler.targets — Derleme hedefleri; her hedef, ilgili dizinden (Sources/TargetName/) bağımlılıklar, kaynaklar ve swift dosyalarının bir listesini içerir.Tam sürüm, dal ve commit belirtme örneği:
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'dan itibaren Package.swift, statik ve dinamik kütüphaneler için daha hassas bağlayıcı yapılandırmasına olanak tanıyan static framework ve linkerSettings desteği eklemiştir.
Swift Package Manager, terminal üzerinden çalışmak için bir dizi komut sağlar. Komutlar, paketin kök dizininden (Package.swift'in bulunduğu yer) çalıştırılır.
# Kütüphaneli yeni bir paket oluştur
swift package init --type library
# Çalıştırılabilir paket oluştur (konsol uygulaması)
swift package init --type executable
# Projeyi derle
swift build
# Release yapılandırmasında derle
swift build -c release
# Testleri çalıştır
swift test
# Belirli bir testi çalıştır
swift test --filter "MyLibraryTests/testExample"
# Bağımlılıkları indir ve çözümle
swift package resolve
# Bağımlılıkları mevcut en son sürümlere güncelle
swift package update
# Bağımlılık grafiğini göster
swift package show-dependencies
# Derleme önbelleğini temizle
swift package clean
# Xcode projesi oluştur (Xcode 11'den önce)
swift package generate-xcodeproj
Xcode içinde çalışırken bu komutların çoğu otomatik olarak yürütülür: proje açıldığında bağımlılıklar çözümlenir, ⌘B ile derleme başlar, ⌘U ile testler başlar. Ancak, Xcode'un bulunmadığı CI/CD boru hatları (GitHub Actions, GitLab CI, Jenkins) için terminal komutlarını bilmek gerekir.
swift package resolve komutu Package.resolved dosyasını oluşturur veya günceller. Bu dosya, geçişli olanlar dahil tüm bağımlılıkların tam sürümlerini sabitler ve git'e eklenmelidir. Güncel kütüphane sürümleriyle çalışmak için her yeni özellik dalından önce swift package update çalıştırılması önerilir.
Kendi SPM paketinizi oluşturmak, çok modüllü projelerde iş mantığını kapsüllemek ve açık kaynak kütüphaneler yayınlamak için kullanışlıdır. Adım adım süreci inceleyelim.
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
swift package init komutu aşağıdaki yapıyı oluşturur:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
SPM otomatik olarak Sources/ ve Tests/ dizinlerini tarar: Sources içindeki her alt dizin bir hedefe (target) karşılık gelir.
Bağımlılıkları ekleyelim ve hedef platformları yapılandıralım:
// 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 bir Git deposuna gönderin ve bir SemVer etiketi oluşturun:
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 herhangi bir geliştirici, .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0") kullanarak paketinizi ekleyebilir.
Alamofire, Swift için en popüler HTTP istemcisidir. SPM aracılığıyla ekleyelim ve bir GET isteği yapalım.
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) kullanıcı alındı")
case .failure(let error):
print("Hata: (error.localizedDescription)")
}
}
}
Swinject kütüphanesi, Swift için bir DI kapsayıcısı sağlar. .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0") aracılığıyla eklenir.
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'ın swift-log paketi, birden çok arka ucu (OSLog, konsol, dosyalar) destekleyen birleşik bir günlük kaydı API'si sağlar.
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("Ağ isteği başlatıldı", metadata: [
"url": "(requestURL)",
"method": "GET"
])
logger.warning("Yanıt süresi 2 saniyeyi aştı")
logger.error("Bağlantı hatası: internet yok")
Bu üç örnek, SPM'nin tipik kullanım senaryolarını kapsar: HTTP istemcileri, DI kapsayıcıları ve sistem altyapısı. Kütüphane seçimi tesadüfi değildir — Alamofire, Swinject ve swift-log, GitHub'da en çok yıldız alan ilk 20 Swift paketi arasındadır.
Projeniz CocoaPods veya Carthage kullanıyorsa, SPM'ye geçiş birkaç adımda yapılır. Süreç güvenlidir: SPM bağımlılıkları, aynı projede CocoaPods ve Carthage ile bir arada bulunabilir ve kademeli geçişe olanak tanır.
.xcworkspace'i silin, .xcodeproj'u açın ve Clean Build Folder yapın.rm -rf Carthage/.2025 itibarıyla SPM, popüler Swift kütüphanelerinin büyük çoğunluğunu desteklemektedir. İstisnalar, modül haritası olmayan bazı ObjC çerçeveleridir. Bir kütüphane henüz SPM'yi desteklemiyorsa — README'sindeki Installation bölümünü kontrol edin; çoğu yazar en son sürümlerde SPM desteğini zaten eklemiştir.
Sıkça Sorulan Sorular
SPM, Swift derleyicisi ve Xcode'a yerleşiktir, gem veya Homebrew aracılığıyla kurulum gerektirmez. CocoaPods, merkezi bir Specs kayıt defteri kullanır ve ayrı bir çalışma alanı oluşturur. Carthage, proje entegrasyonu olmadan çerçeveler aracılığıyla çalışır. SPM, derleyici düzeyinde entegre edilmiş tek yöneticidir: bağımlılıklar ana kodla paralel olarak çözümlenir, önbelleğe alınır ve derlenir.
Evet, SPM, Swift + Objective-C karma projelerini destekler. Bir SPM paketindeki ObjC dosyaları, doğru bir modulemap olması koşuluyla otomatik olarak bir Umbrella Header'a dahil edilir. Ancak SPM, modül haritası olmayan statik ObjC kütüphanelerini desteklemez. ObjC kütüphanelerinin yalnızca modulemap sağlıyorlarsa veya saf C ile yazılmışlarsa SPM aracılığıyla bağlanması önerilir.
SPM, anlamsal sürümleme (SemVer) kullanır. Paket A, Alamofire 5.8+ gerektiriyorsa ve Paket B, Alamofire 5.9+ gerektiriyorsa, SPM her ikisini de karşılayan 5.9.x sürümünü seçecektir. Çakışma çözülemezse (bir paket 5.x, diğeri 6.x gerektiriyorsa), SPM bir hata bildirecektir. Bu durumda, paketlerden birini güncellemeniz veya bağımlılığı her iki gereksinimle de uyumlu bir sürüme değiştirmeniz gerekir.
macOS'ta: ~Library/Caches/org.swift.swiftpm/ ve ~/Library/Developer/Xcode/DerivedData/. Linux'ta: ~cache/swiftpm/. Derleme sırasında SPM, kaynak kodunu ve derlenmiş nesne dosyalarını önbelleğe alır. Önbelleği tamamen temizlemek için swift package reset komutunu çalıştırın — bu komut, geçerli proje için bağımlılık önbelleğini ve DerivedData'yı kaldırır.
Evet, Swift 5.2'den itibaren SPM, ikili hedefleri (binary targets) destekler. Kapalı kaynaklı bir kütüphane XCFramework olarak dağıtılır ve .xcframework yoluna Package.swift'te belirtilir. Kaynak kodu ifşa edilmez. İkili bir hedef, .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework") aracılığıyla belirtilir. Bu, lisans anlaşmalarını ihlal etmeden ticari SDK'ların bağlanmasına olanak tanır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun