# 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. - Published: 2026-09-20 - Updated: 2026-09-20 - Author: Anthony Fillion-Maillet - Reading time: 5 min --- 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. > **Fungsi SPM** > > 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. ```swift // Package.swift 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. ```bash # 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.swift ``` Menjalankan `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. ```swift // Package.swift 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. > **Dependensi Branch di Produksi** > > 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. ```swift // AppDelegate.swift 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. ```swift // Package.swift di consuming package 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. ## Menerbitkan Swift Package ke GitHub Menerbitkan memerlukan repository Git dengan tag versi semantik. SPM memperlakukan tag Git sebagai versi rilis. [Swift Package Index](https://swiftpackageindex.com) mengindeks package publik secara otomatis. ```bash # 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](https://semver.org): 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. ```swift // Package.swift dengan fitur Swift 6.2+ 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. ```bash # 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 sumber ``` Lingkungan 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. ```swift // Package.swift dengan binary target 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.zip ``` Binary 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](https://developer.apple.com/documentation/xcode/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. ```swift // 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](https://swiftpackageindex.com) sebelum memulai. ```ruby # Sebelum: Podfile pod 'Alamofire', '~> 5.9' pod 'SwiftyJSON', '~> 5.0' pod 'Kingfisher', '~> 7.0' ``` ```swift // 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.0 ``` Hapus 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.resolved` untuk memastikan build yang reproducible di seluruh tim - Gunakan package lokal selama pengembangan aktif, beralih ke URL remote sebelum merge - Pisahkan dependensi khusus test menggunakan `testTarget` untuk 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 > **Swift Tools Version** > > 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.swift` menggunakan kode Swift, memungkinkan deklarasi dependensi yang type-checked - Persyaratan versi mendukung rentang semantic versioning, versi eksak, dan referensi branch - `Package.resolved` mengunci 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](/technologies/ios/interview-questions/swiftui-state-management) dan [protocol-oriented programming](/technologies/ios/interview-questions/protocol-oriented-programming) di SharpSkill. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/id/blog/ios/swift-package-manager-tutorial-2026