SPM (Swift Package Manager) — manajer paket bawaan ekosistem Swift, dikembangkan oleh Apple untuk mengotomatiskan koneksi, pembangunan, dan pembaruan pustaka pihak ketiga. SPM sudah menjadi bagian dari kompiler Swift sejak versi 3.0 (2016) dan tidak memerlukan instalasi terpisah. Tidak seperti CocoaPods dan Carthage, SPM terintegrasi langsung dengan kompiler dan Xcode, menjadikannya alat standar untuk pengelolaan dependensi dalam proyek Swift modern. Dalam artikel ini kita akan membahas struktur Package.swift, perintah SPM, penulisan paket sendiri, dan migrasi dari manajer alternatif.
Poin utama
SPM (Swift Package Manager) — manajer paket resmi untuk bahasa Swift, terintegrasi dalam kompiler swiftc dan lingkungan pengembangan Xcode. Alat ini memungkinkan pengembang untuk menghubungkan pustaka pihak ketiga, mengelola versinya, dan menerbitkan paket sendiri. SPM pertama kali muncul di Swift 3.0 (September 2016) sebagai alat baris perintah, dan mulai Xcode 11 (2019) mendapatkan integrasi penuh dengan antarmuka grafis — sekarang dependensi ditambahkan melalui menu File → Add Packages.
SPM secara otomatis mengunduh kode sumber dependensi dari repositori Git, membangunnya secara paralel dengan proyek utama, dan menyimpan cache hasilnya agar pembangunan ulang lebih cepat. Tidak seperti CocoaPods, SPM tidak menghasilkan workspace terpisah (xcworkspace) — dependensi menjadi bagian dari proyek Xcode utama. Menurut survei Swift.org Developer Survey (2024), 67% pengembang iOS menggunakan SPM, menjadikannya alat pengelolaan dependensi paling populer di ekosistem Swift.
SPM mendukung tiga platform: Apple (iOS, macOS, tvOS, watchOS, visionOS), Linux (Ubuntu, CentOS, Amazon Linux), dan Swift server (Vapor, Kitura). Di Linux, SPM bekerja sepenuhnya melalui baris perintah tanpa Xcode.
SPM dibangun di sekitar tiga konsep utama: paket (packages), produk (products), dan target (targets). Paket adalah repositori Git dengan manifes Package.swift. Produk adalah hasil pembangunan (pustaka atau file eksekusi). Target adalah modul di dalam paket yang dikompilasi menjadi satu unit pembangunan.
Ketika pengembang menambahkan dependensi ke Package.swift, SPM melakukan langkah-langkah berikut:
~Library/Caches/org.swift.swiftpm/.File Package.resolved menetapkan versi pasti dari semua dependensi sehingga tim pengembang bekerja dengan kumpulan pustaka yang identik. File ini harus ditambahkan ke sistem kontrol versi (git).
Keunggulan utama SPM dibandingkan alternatif — tidak adanya registri terpusat. Paket dapat berada di repositori Git publik mana pun: GitHub, GitLab, Bitbucket, serta di server Git internal perusahaan. Sejak Swift 5.2, SPM mendukung dependensi biner (binary targets) — pustaka tertutup yang didistribusikan melalui XCFramework tanpa menyediakan kode sumber.
Package.swift — adalah file Swift yang mendeskripsikan struktur paket dan dependensinya. File ditulis dalam Swift sendiri (bukan JSON, bukan YAML), yang memungkinkan penggunaan logika kondisional, konstanta yang dihitung, dan fungsi di dalam manifes.
Struktur dasar Package.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"]
),
]
)
Mari kita bahas elemen-elemen kunci:
// swift-tools-version: 5.9 — direktif yang menunjukkan versi SPM; sintaks manifes yang tersedia bergantung padanya.name — nama paket yang ditampilkan di Xcode dan digunakan dalam referensi dependensi.platforms — versi minimum platform; SPM tidak akan mengizinkan pembangunan paket pada versi OS yang lebih lama.products — apa yang "diekspor" oleh paket: pustaka (.library) atau file eksekusi (.executable).dependencies — daftar paket eksternal dengan URL dan versi; from:, exact:, branch:, revision: didukung.targets — target pembangunan; setiap target berisi daftar dependensi, sumber daya, dan file swift dari direktori yang sesuai (Sources/TargetName/).Contoh penentuan versi pasti, cabang, dan komit:
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"),
]
Sejak Swift 5.9, dukungan untuk static/framework dan linkerSettings telah ditambahkan ke Package.swift, memungkinkan konfigurasi penautan yang lebih tepat untuk pustaka statis dan dinamis.
Swift Package Manager menyediakan serangkaian perintah untuk bekerja melalui terminal. Perintah dijalankan dari direktori root paket (tempat Package.swift berada).
# Buat paket baru dengan pustaka
swift package init --type library
# Buat paket eksekusi (aplikasi konsol)
swift package init --type executable
# Bangun proyek
swift build
# Bangun dalam konfigurasi release
swift build -c release
# Jalankan tes
swift test
# Jalankan tes tertentu
swift test --filter "MyLibraryTests/testExample"
# Unduh dan selesaikan dependensi
swift package resolve
# Perbarui dependensi ke versi terbaru yang tersedia
swift package update
# Tampilkan grafik dependensi
swift package show-dependencies
# Bersihkan cache pembangunan
swift package clean
# Hasilkan proyek Xcode (sebelum Xcode 11)
swift package generate-xcodeproj
Saat bekerja di dalam Xcode, sebagian besar perintah ini dijalankan secara otomatis: dependensi diselesaikan saat proyek dibuka, pembangunan dimulai dengan ⌘B, tes dengan ⌘U. Namun, pengetahuan tentang perintah terminal diperlukan untuk pipeline CI/CD (GitHub Actions, GitLab CI, Jenkins), di mana Xcode tidak tersedia.
Perintah swift package resolve membuat atau memperbarui file Package.resolved. File ini menetapkan versi pasti dari semua dependensi, termasuk yang transitif, dan harus ditambahkan ke git. Disarankan untuk menjalankan swift package update sebelum setiap cabang fitur baru, agar bekerja dengan versi pustaka terkini.
Membuat paket SPM sendiri berguna untuk enkapsulasi logika bisnis dalam proyek multi-modul dan untuk menerbitkan pustaka open-source. Mari kita lihat proses langkah demi langkah.
mkdir MyNetworkKit
cd MyNetworkKit
swift package init --type library
Perintah swift package init membuat struktur berikut:
MyNetworkKit/
├── Package.swift
├── README.md
├── Sources/
│ └── MyNetworkKit/
│ └── MyNetworkKit.swift
└── Tests/
└── MyNetworkKitTests/
└── MyNetworkKitTests.swift
SPM secara otomatis memindai direktori Sources/ dan Tests/: setiap subdirektori di dalam Sources sesuai dengan target.
Mari tambahkan dependensi dan konfigurasikan platform target:
// 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
}
}
Dorong paket ke repositori Git dan buat tag SemVer:
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
Setelah itu, pengembang mana pun dapat menghubungkan paket Anda melalui .package(url: "https://github.com/username/MyNetworkKit.git", from: "1.0.0").
Alamofire — klien HTTP paling populer untuk Swift. Mari tambahkan melalui SPM dan lakukan permintaan GET.
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) pengguna diterima")
case .failure(let error):
print("Kesalahan: \(error.localizedDescription)")
}
}
}
Pustaka Swinject menyediakan wadah DI untuk Swift. Terhubung melalui .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0").
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()
Paket swift-log dari Apple — API pencatatan terpadu yang mendukung banyak backend (OSLog, konsol, file).
import Logging
var logger = Logger(label: "com.myapp.network")
logger.logLevel = .debug
logger.info("Permintaan jaringan dimulai", metadata: [
"url": "\(requestURL)",
"method": "GET"
])
logger.warning("Waktu respons melebihi 2 detik")
logger.error("Kesalahan koneksi: tidak ada internet")
Ketiga contoh ini mencakup skenario penggunaan SPM yang umum: klien HTTP, wadah DI, dan infrastruktur sistem. Pemilihan pustaka tidak kebetulan — Alamofire, Swinject, dan swift-log termasuk dalam 20 paket Swift paling banyak bintang di GitHub.
Jika proyek menggunakan CocoaPods atau Carthage, migrasi ke SPM dilakukan dalam beberapa langkah. Prosesnya aman: dependensi SPM dapat hidup berdampingan dengan CocoaPods dan Carthage dalam satu proyek, memungkinkan migrasi bertahap.
.xcworkspace, buka .xcodeproj, dan lakukan Clean Build Folder.rm -rf Carthage/ di terminal.Pada tahun 2025, SPM mendukung sebagian besar pustaka Swift populer. Pengecualian adalah beberapa framework ObjC tanpa peta modul (modulemap). Jika pustaka belum mendukung SPM — periksa bagian Installation di README-nya; sebagian besar penulis telah menambahkan dukungan SPM di versi terbaru.
Pertanyaan yang sering diajukan
SPM terintegrasi dalam kompiler Swift dan Xcode, tidak memerlukan instalasi melalui gem atau Homebrew. CocoaPods menggunakan registri terpusat Specs dan menghasilkan workspace terpisah. Carthage bekerja melalui framework tanpa integrasi dengan proyek. SPM adalah satu-satunya manajer yang terintegrasi di tingkat kompiler: dependensi diselesaikan, di-cache, dan dibangun secara paralel dengan kode utama.
Ya, SPM mendukung proyek campuran Swift + Objective-C. File ObjC di dalam paket SPM secara otomatis masuk ke Umbrella Header dengan syarat modulemap yang benar. Namun, SPM tidak mendukung pustaka statis ObjC yang tidak memiliki peta modul. Disarankan untuk menghubungkan pustaka ObjC melalui SPM hanya jika mereka menyediakan modulemap atau ditulis dalam C murni.
SPM menggunakan semantic versioning (SemVer). Jika paket A membutuhkan Alamofire 5.8+, dan paket B membutuhkan Alamofire 5.9+, SPM akan memilih versi 5.9.x yang memenuhi keduanya. Jika konflik tidak dapat diselesaikan (satu paket membutuhkan 5.x, yang lain 6.x), SPM akan melaporkan kesalahan. Dalam kasus tersebut, Anda perlu memperbarui salah satu paket atau mengubah dependensi ke versi yang kompatibel dengan kedua persyaratan.
Di macOS: ~Library/Caches/org.swift.swiftpm/ dan ~/Library/Developer/Xcode/DerivedData/. Di Linux: ~cache/swiftpm/. Saat membangun, SPM menyimpan cache kode sumber dan file objek yang dikompilasi. Untuk membersihkan cache sepenuhnya, jalankan swift package reset — perintah ini menghapus cache dependensi dan DerivedData untuk proyek saat ini.
Ya, sejak Swift 5.2, SPM mendukung target biner (binary targets). Pustaka tertutup disediakan sebagai XCFramework, dan di Package.swift ditentukan jalur ke .xcframework. Kode sumber tidak diungkapkan. Binary target ditentukan melalui .binaryTarget(name: "PrivateSDK", path: "Sources/PrivateSDK.xcframework"). Ini memungkinkan menghubungkan SDK komersial tanpa melanggar perjanjian lisensi.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga