Section 4/151 menit
4. Swift Package Manager: Cara Kerja Mendalam
4. Swift Package Manager: Cara Kerja Mendalam
Package.swift Anatomy
swift
// Package.swift — letakkan di root package/project
// swift-tools-version menentukan format Package.swift yang digunakan
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyLibrary",
defaultLocalization: "id", // Bahasa default untuk localizable resources
platforms: [
.iOS(.v16),
.macOS(.v13),
.watchOS(.v9),
.tvOS(.v16),
.visionOS(.v1)
],
products: [
// Library yang di-export
.library(name: "MyLibrary", targets: ["MyLibrary"]),
// Executable (untuk CLI tools)
// .executable(name: "mytool", targets: ["MyTool"]),
// Plugin
// .plugin(name: "MyPlugin", targets: ["MyPlugin"]),
],
dependencies: [
// Remote dengan version range
.package(
url: "https://github.com/Alamofire/Alamofire",
from: "5.9.0" // >= 5.9.0, < 6.0.0
),
// Exact version
.package(
url: "https://github.com/onevcat/Kingfisher",
exact: "7.11.0"
),
// Branch (untuk development)
.package(
url: "https://github.com/apple/swift-async-algorithms",
branch: "main"
),
// Commit hash (untuk reproducible build)
.package(
url: "https://github.com/nicklockwood/SwiftFormat",
revision: "0.54.3"
),
// Local path (untuk library internal yang di-develop paralel)
.package(path: "../MyInternalLib"),
// Version range eksplisit
.package(
url: "https://github.com/realm/SwiftLint",
"0.55.0"..<"1.0.0"
),
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
"Alamofire",
.product(name: "Kingfisher", package: "Kingfisher"),
// Conditional dependency
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms",
condition: .when(platforms: [.iOS, .macOS]))
],
path: "Sources/MyLibrary",
resources: [
.process("Resources"), // Auto-detect type
.copy("Assets/static-asset"), // Copy as-is
],
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency"),
.enableExperimentalFeature("AccessLevelOnImport"),
]
),
.testTarget(
name: "MyLibraryTests",
dependencies: ["MyLibrary"],
path: "Tests/MyLibraryTests"
),
// Binary target: pre-compiled framework
.binaryTarget(
name: "SomeClosedSourceSDK",
url: "https://example.com/SDK-1.0.xcframework.zip",
checksum: "abc123..."
),
// Build tool plugin
.plugin(
name: "GenerateCode",
capability: .buildTool(),
dependencies: ["CodeGenerator"]
),
]
)
Package.resolved: Lock File SPM
swift
// Package.resolved — auto-generated, HARUS di-commit ke Git
{
"pins": [
{
"identity": "alamofire",
"kind": "remoteSourceControl",
"location": "https://github.com/Alamofire/Alamofire",
"state": {
"revision": "f455c2975872ccd2d9c81594c658af65716e9b9a",
"version": "5.9.1"
}
},
{
"identity": "kingfisher",
"kind": "remoteSourceControl",
"location": "https://github.com/onevcat/Kingfisher",
"state": {
"revision": "...",
"version": "7.11.0"
}
}
],
"version": 3
}
SPM Command Line
swift
# Resolve: download/update semua dependencies sesuai Package.resolved
swift package resolve
# Update: update ke versi terbaru yang diizinkan, update Package.resolved
swift package update
# Update satu package spesifik
swift package update Alamofire
# Build
swift build
swift build -c release # Release build
# Test
swift test
swift test --filter MyLibraryTests.NetworkTests
# Clean build artifacts
swift package clean
# Reset cache packages (nuclear option)
swift package reset
# Generate Xcode project dari Package.swift (deprecated tapi masih berguna)
swift package generate-xcodeproj
# List dependencies
swift package show-dependencies
swift package show-dependencies --format json | jq .
# Audit untuk security vulnerabilities
swift package audit
# Describe package structure
swift package describe --type json