Swift Package Manager 2026: Membuat, Menerbitkan, dan Pertanyaan Wawancara
Kuasai Swift Package Manager dengan tutorial lengkap ini. Pelajari cara membuat package, mengelola dependensi, menerbitkan library, dan persiapkan diri untuk wawancara iOS.

Swift Package Manager (SPM) menangani manajemen dependensi dan distribusi package untuk proyek Swift. Berbeda dengan CocoaPods atau Carthage, SPM terintegrasi langsung ke dalam Xcode dan toolchain Swift, tanpa memerlukan instalasi eksternal. Swift 6.2 dan 6.3 memperkenalkan pengaturan keamanan memori yang ketat, isolasi aktor default, dan sistem Swift Build baru, menjadikan SPM pilihan definitif untuk pengembangan iOS modern.
Swift Package Manager menyelesaikan dependensi, mengunduh kode sumber, mengompilasi modul, dan menghubungkannya ke binary akhir. Satu file manifest Package.swift mendefinisikan semuanya: dependensi, target, produk, dan pengaturan build.
Struktur dan Sintaks Manifest Package.swift
Setiap Swift package dimulai dengan file Package.swift di root repository. Manifest ini menggunakan kode Swift untuk mendeklarasikan struktur package, dependensi, dan konfigurasi build.
import PackageDescription
let package = Package(
name: "NetworkKit",
platforms: [
.iOS(.v15),
.macOS(.v12)
],
products: [
.library(
name: "NetworkKit",
targets: ["NetworkKit"]
)
],
dependencies: [
.package(
url: "https://github.com/Alamofire/Alamofire.git",
from: "5.9.0"
)
],
targets: [
.target(
name: "NetworkKit",
dependencies: ["Alamofire"]
),
.testTarget(
name: "NetworkKitTests",
dependencies: ["NetworkKit"]
)
]
)Array platforms menentukan target deployment minimum. Bagian products mendefinisikan apa yang dapat diimpor oleh package lain. Bagian targets mencantumkan unit kompilasi dengan dependensi masing-masing.
Membuat Swift Package dari Command Line
Perintah swift package init membuat scaffolding package baru dengan struktur direktori standar. Flag --type menentukan apakah package menghasilkan library atau executable.
# Membuat library package
mkdir NetworkKit && cd NetworkKit
swift package init --type=library
# Struktur yang dihasilkan:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │ └── NetworkKit/
# │ └── NetworkKit.swift
# └── Tests/
# └── NetworkKitTests/
# └── NetworkKitTests.swiftMenjalankan swift build mengompilasi package. Menjalankan swift test mengeksekusi test suite. Kedua perintah menggunakan konfigurasi dari Package.swift tanpa setup tambahan.
Persyaratan Versi Dependensi dan Resolusi
SPM mendukung tiga strategi spesifikasi versi: versi eksak, rentang versi, dan referensi branch atau commit. Pilihan ini mempengaruhi reprodusibilitas dan fleksibilitas.
dependencies: [
// Semantic versioning: 5.9.0 hingga major berikutnya
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
// Versi eksak: terkunci ke 5.9.1
.package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
// Rentang versi: 5.8.0 hingga 5.9.9
.package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
// Referensi branch: untuk pengembangan
.package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
// Referensi commit: dipinkan ke commit tertentu
.package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]File Package.resolved mencatat versi eksak yang diselesaikan selama resolusi dependensi. File ini sebaiknya di-commit ke version control untuk build yang reproducible di seluruh anggota tim dan sistem CI.
Referensi branch dan commit melewati semantic versioning. Menggunakan branch: "main" di aplikasi produksi berarti push apa pun ke main dapat merusak build. Cadangkan referensi branch untuk pengembangan aktif terhadap fitur yang belum dirilis.
Menambahkan Package ke Proyek Xcode
Xcode mengintegrasikan SPM melalui menu File. Navigasi ke File, lalu Add Package Dependencies. Masukkan URL repository, pilih aturan versi, dan pilih target mana yang harus menghubungkan dependensi.
import UIKit
import Alamofire // Tersedia setelah ditambahkan via Xcode
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
AF.request("https://api.example.com/health").response { response in
print(response.result)
}
return true
}
}Xcode menyimpan referensi package dalam file .xcodeproj dan versi yang diselesaikan dalam Package.resolved di root proyek. Folder Derived Data menyimpan cache package yang diunduh.
Pengembangan Package Lokal dengan Dependensi Path
Selama pengembangan, menunjuk ke path lokal alih-alih URL remote memungkinkan iterasi cepat tanpa menerbitkan versi antara. Teknik ini cocok untuk setup monorepo dan pengembangan fitur.
dependencies: [
// Path lokal untuk pengembangan
.package(path: "../NetworkKit"),
// URL remote untuk rilis
// .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]Beralih antara dependensi lokal dan remote dengan mengomentari baris yang tidak aktif. Xcode dan Swift CLI menyelesaikan dependensi path relatif terhadap consuming package.
Siap menguasai wawancara iOS Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Menerbitkan Swift Package ke GitHub
Menerbitkan memerlukan repository Git dengan tag versi semantik. SPM memperlakukan tag Git sebagai versi rilis. Swift Package Index mengindeks package publik secara otomatis.
# Inisialisasi repository dan push
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/NetworkKit.git
git push -u origin main
# Buat tag versi
git tag 1.0.0
git push origin 1.0.0
# Package lain sekarang dapat bergantung pada:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")Ikuti konvensi semantic versioning: increment versi major untuk breaking changes, minor untuk fitur baru, dan patch untuk bug fixes. SPM mengasumsikan kepatuhan terhadap aturan ini saat menyelesaikan persyaratan versi from:.
Pengaturan Package Swift 6.2 dan 6.3
Swift 6.2 memperkenalkan konfigurasi mode bahasa per-target dan pengaturan keamanan memori yang ketat. Swift 6.3 menambahkan integrasi Swift Build sebagai sistem build opt-in.
import PackageDescription
let package = Package(
name: "SafeNetworkKit",
platforms: [.iOS(.v17)],
products: [
.library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
],
targets: [
.target(
name: "SafeNetworkKit",
swiftSettings: [
// Aktifkan mode bahasa Swift 6 untuk target ini saja
.swiftLanguageMode(.v6),
// Aktifkan pemeriksaan keamanan memori ketat (SE-0458)
.enableExperimentalFeature("StrictMemorySafety"),
// Set isolasi aktor default (SE-0466)
.enableExperimentalFeature("GlobalActorIsolation")
]
)
]
)Pengaturan swiftLanguageMode memungkinkan adopsi bertahap fitur Swift 6 di seluruh codebase. Target dapat menggunakan mode bahasa yang berbeda dalam package yang sama.
Generasi SBOM untuk Kepatuhan Keamanan
SE-0509 menambahkan generasi Software Bill of Materials secara native di Swift 6.3. Dokumen SBOM mencantumkan semua dependensi dan versinya untuk audit keamanan dan kepatuhan regulasi.
# Generate SBOM dalam format CycloneDX
swift build --sbom-spec cyclonedx
# Generate SBOM menggunakan subcommand khusus
swift package generate-sbom --format spdx
# Output mencakup:
# - Nama dan versi package
# - Semua dependensi transitif
# - Informasi lisensi
# - URL repository sumberLingkungan enterprise dan kontrak pemerintah semakin memerlukan dokumentasi SBOM. Format CycloneDX dan SPDX terintegrasi dengan alat pemindaian kerentanan standar.
Binary Target dan Distribusi XCFramework
Binary target memungkinkan distribusi framework yang sudah dikompilasi alih-alih kode sumber. XCFramework menggabungkan binary untuk berbagai platform dan arsitektur.
import PackageDescription
let package = Package(
name: "AnalyticsSDK",
platforms: [.iOS(.v14)],
products: [
.library(name: "AnalyticsSDK", targets: ["AnalyticsSDK"])
],
targets: [
.binaryTarget(
name: "AnalyticsSDK",
url: "https://releases.example.com/AnalyticsSDK-2.0.0.xcframework.zip",
checksum: "abc123def456..."
)
]
)
// Generate checksum:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zipBinary target mengurangi waktu build untuk konsumen dan melindungi implementasi proprietary. Checksum memastikan integritas unduhan.
Pertanyaan Wawancara Umum Tentang Swift Package Manager
Wawancara teknis untuk posisi iOS sering mencakup pertanyaan SPM. Pertanyaan ini berkisar dari penggunaan dasar hingga keputusan arsitektur.
Q: Bagaimana SPM berbeda dari CocoaPods dan Carthage?
SPM terintegrasi ke dalam Xcode dan toolchain Swift tanpa alat eksternal. CocoaPods menggunakan repository spec pusat dan memodifikasi struktur workspace Xcode. Carthage membangun framework dalam langkah terpisah tanpa integrasi Xcode. SPM menyelesaikan dependensi dan membangun dalam satu proses terpadu. Dokumentasi Apple tentang Swift packages mencakup tooling resmi.
Q: Apa yang terjadi selama resolusi dependensi?
SPM membaca manifest Package.swift secara rekursif, membangun grafik dependensi. Kemudian menerapkan constraint versi untuk menemukan versi yang kompatibel untuk semua package. Resolver menulis versi eksak ke Package.resolved. Konflik terjadi ketika dua package memerlukan versi yang tidak kompatibel dari dependensi bersama.
Q: Bagaimana menangani konflik diamond dependency?
Ketika package A dan B sama-sama bergantung pada package C dengan persyaratan versi yang tidak kompatibel, resolusi SPM gagal. Solusinya termasuk: memperbarui satu konsumen untuk mendukung rentang versi yang lebih luas, mem-fork package yang membatasi, atau menggunakan module aliasing jika konflik antara package berbeda dengan nama modul yang sama.
// Module aliasing untuk konflik nama
.target(
name: "MyApp",
dependencies: [
.product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
]
)Q: Kapan menggunakan binary target alih-alih distribusi sumber?
Binary target cocok untuk SDK proprietary di mana paparan sumber tidak dapat diterima, dependensi besar di mana waktu kompilasi mempengaruhi produktivitas developer, dan library vendor yang sudah dikompilasi. Distribusi sumber tetap lebih disukai untuk proyek open source dan library internal di mana debugging ke dalam dependensi memberikan nilai.
Migrasi dari CocoaPods ke Swift Package Manager
Migrasi memerlukan penggantian entri Podfile dengan referensi package SPM. Tidak semua CocoaPods memiliki ekuivalen SPM, jadi verifikasi ketersediaan di Swift Package Index sebelum memulai.
# Sebelum: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'// Sesudah: Package dependencies di Xcode
// File > Add Package Dependencies untuk setiap:
// https://github.com/Alamofire/Alamofire.git from 5.9.0
// https://github.com/SwiftyJSON/SwiftyJSON.git from 5.0.0
// https://github.com/onevcat/Kingfisher.git from 7.0.0Hapus Podfile, Podfile.lock, dan direktori Pods setelah migrasi. Jalankan pod deintegrate untuk menghapus modifikasi workspace CocoaPods. Statement import dalam file Swift tetap tidak berubah.
Praktik Terbaik SPM untuk Aplikasi Produksi
- Pin versi major dengan
from:untuk stabilitas sambil menerima update minor dan patch - Commit
Package.resolveduntuk memastikan build yang reproducible di seluruh tim - Gunakan package lokal selama pengembangan aktif, beralih ke URL remote sebelum merge
- Pisahkan dependensi khusus test menggunakan
testTargetuntuk menghindari bundling di build rilis - Dokumentasikan versi Swift tools minimum di bagian atas manifest:
// swift-tools-version: 5.10 - Validasi build package di CI sebelum membuat tag rilis
Komentar // swift-tools-version: harus muncul di baris pertama Package.swift. Ini menentukan versi API PackageDescription mana yang digunakan manifest. Swift 6.0 menambahkan fleksibilitas untuk mengizinkan komentar ini di baris berikutnya untuk header lisensi.
Poin Penting untuk Developer iOS yang Menggunakan SPM
- SPM terintegrasi ke Xcode secara native, menghilangkan overhead setup CocoaPods dan Carthage
- Manifest
Package.swiftmenggunakan kode Swift, memungkinkan deklarasi dependensi yang type-checked - Persyaratan versi mendukung rentang semantic versioning, versi eksak, dan referensi branch
Package.resolvedmengunci versi dependensi untuk build yang reproducible- Swift 6.2 menambahkan mode bahasa per-target dan pengaturan keamanan memori yang ketat
- Swift 6.3 memperkenalkan generasi SBOM untuk dokumentasi kepatuhan
- Binary target mendistribusikan XCFramework yang sudah dikompilasi ketika distribusi sumber tidak praktis
- Pertanyaan wawancara fokus pada konflik resolusi, strategi migrasi, dan trade-off arsitektur antara SPM dan alternatif
Untuk persiapan wawancara iOS yang komprehensif, tinjau modul manajemen state SwiftUI dan protocol-oriented programming di SharpSkill.
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Bisakah kamu menemukan bug di iOS?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 20 September 2026
Bagikan
Artikel terkait

CloudKit dengan SwiftUI di 2026: pola sinkronisasi data lintas perangkat
Panduan lengkap untuk menerapkan sinkronisasi CloudKit dengan SwiftUI: CKSyncEngine, integrasi SwiftData, resolusi konflik, dan praktik terbaik untuk iOS 2026.

Combine vs async/await di Swift: Pola Migrasi Progresif
Panduan lengkap migrasi dari Combine ke async/await di Swift: strategi progresif, pola jembatan, dan koeksistensi paradigma di basis kode iOS.

Pertanyaan Wawancara Aksesibilitas iOS di 2026: VoiceOver dan Dynamic Type
Persiapkan wawancara iOS dengan pertanyaan kunci aksesibilitas: VoiceOver, Dynamic Type, trait semantik, dan audit.