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 2026: Membuat, Menerbitkan, dan Pertanyaan Wawancara

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.

Package.swiftswift
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.

Package.swiftswift
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.

AppDelegate.swiftswift
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.

Package.swift di consuming packageswift
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.

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

Package.swift dengan fitur Swift 6.2+swift
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.

Package.swift dengan binary targetswift
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 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 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 dan protocol-oriented programming di SharpSkill.

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tantangan harian

Bisakah kamu menemukan bug di iOS?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri 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