SPM: nedir, Swift Package Manager ve Package.swift

Yazar: IT Sectr Yayınlanma: 2026-02-13 Okuma süresi: 11 dk

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 derleyicisine yerleşik, ayrı kurulum gerektirmeyen bir paket yöneticisidir; iOS, macOS, Linux ve sunucu platformlarında çalışır.
  • Package.swift, bildirimsel formatta paket adını, platformları, bağımlılıkları ve hedef modülleri (targets) tanımlayan bir manifest dosyasıdır.
  • SPM, anlamsal sürümleme (SemVer) ile bağımlılıkları çözer, kaynak kodunu önbelleğe alır ve hız için paketleri paralel olarak derler.
  • Komutlar: swift package init (paket oluşturma), swift package update (bağımlılıkları güncelleme), swift build (derleme), swift test (testleri çalıştırma).
  • CocoaPods/Carthage'dan SPM'ye geçiş Xcode üzerinden yapılır: File → Add Package Dependency, ardından podfile ve Cartfile kaldırılır.

SPM nedir?

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.

Swift Package Manager nasıl ç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:

  1. Klonlama — SPM, belirtilen URL'den bağımlılığın Git deposunu indirir.
  2. Sürüm çözümleme — SemVer etiketlerini (örn. 2.1.3) analiz eder ve belirtilen aralıkta uygun sürümü seçer.
  3. Geçişli çözümleme — Bağımlılıkların bağımlılıklarını kontrol eder ve çakışmasız bir sürüm grafiği oluşturur.
  4. Önbelleğe alma — İndirilen kaynak kodunu ~Library/Caches/org.swift.swiftpm/ konumunda saklar.
  5. Derleme — Ana projenin bayraklarıyla tüm paket hedeflerini derler.

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 — proje manifestosu

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
// 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:

swift
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.

Temel SPM komutları

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.

bash
# 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 paketinizi oluşturma

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.

Adım 1: Başlatma

bash
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library

Adım 2: Dizin yapısı

swift package init komutu aşağıdaki yapıyı oluşturur:

text
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.

Adım 3: Package.swift düzenleme

Bağımlılıkları ekleyelim ve hedef platformları yapılandıralım:

swift
// 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"]
        ),
    ]
)

Adım 4: Kod yazma

swift
// 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
    }
}

Adım 5: Yayınlama

Paketi bir Git deposuna gönderin ve bir SemVer etiketi oluşturun:

bash
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.

SPM kullanım örnekleri

Örnek 1: Ağ istekleri için Alamofire ekleme

Alamofire, Swift için en popüler HTTP istemcisidir. SPM aracılığıyla ekleyelim ve bir GET isteği yapalım.

swift
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)")
            }
        }
}

Örnek 2: Swinject — bağımlılık enjeksiyonu

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.

swift
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()

Örnek 3: Yapılandırılmış günlük kaydı için Swift-log

Apple'ın swift-log paketi, birden çok arka ucu (OSLog, konsol, dosyalar) destekleyen birleşik bir günlük kaydı API'si sağlar.

swift
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.

CocoaPods ve Carthage'dan geçiş

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.

CocoaPods → SPM

  1. Xcode'da: File → Add Package Dependency, paket URL'sini girin.
  2. Sürümü seçin ve paketi gerekli hedeflere ekleyin.
  3. SPM aracılığıyla tüm bağımlılıkları ekledikten sonra Podfile'daki satırları silin.
  4. .xcworkspace'i silin, .xcodeproj'u açın ve Clean Build Folder yapın.

Carthage → SPM

  1. Xcode File → Add Package Dependency aracılığıyla paketleri ekleyin.
  2. Cartfile'dan bağımlılıkları silin.
  3. Build Phases'dan Carthage derleme betiklerini silin.
  4. Önbelleği temizleyin: terminalde 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, CocoaPods ve Carthage'dan nasıl farklıdır?

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.

SPM, Objective-C projeleri için kullanılabilir mi?

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 sürüm çakışmalarını nasıl çözer?

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.

İndirilen SPM paketleri nerede saklanır?

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.

SPM, kapalı kaynak (özel) kütüphaneleri destekler mi?

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

  • SPM (Swift Package Manager), Swift'e yerleşik, ayrı kurulum gerektirmeyen ve Xcode ile derleyiciye entegre bir paket yöneticisidir.
  • Package.swift, Swift'te yazılmış, paket adını, platformları, bağımlılıkları, ürünleri ve derleme hedeflerini tanımlayan bildirimsel bir manifestodur.
  • SPM, paket kaynağı olarak Git depolarını kullanır ve sürümleri SemVer ile çözer, daha hızlı sonraki derlemeler için kaynak kodunu önbelleğe alır.
  • Ana komutlar: swift package init (paket oluştur), swift build (derle), swift test (test et), swift package update (bağımlılıkları güncelle).
  • Özel bir paket, swift package init ile oluşturulur, Git'te yayınlanır ve SemVer etiketiyle URL aracılığıyla diğer projeler tarafından kullanılabilir.
  • CocoaPods/Carthage'dan SPM'ye geçiş güvenlidir: bağımlılıklar bir arada bulunabilir, geçiş Xcode'da File → Add Package Dependency aracılığıyla yapılır.
  • SPM, Swift ekosistemindeki standart bağımlılık yönetim aracıdır ve iOS geliştiricilerinin %67'si tarafından kullanılmaktadır (Swift.org Developer Survey, 2024).

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.

Projeyi tartış

Ayrıca okuyun