Section 7/181 menit

7. Swift Package Manager: Advanced Usage

7. Swift Package Manager: Advanced Usage

Resolving Conflicts & Pinning

swift
# Cek dependency graph
swift package show-dependencies --format json | jq .

# Update semua package ke versi terbaru yang diizinkan
swift package update

# Pin versi spesifik (edit Package.resolved atau gunakan exact version)
# Di Package.swift:
.package(url: "https://github.com/Alamofire/Alamofire", exact: "5.9.1")

# Reset resolved file (jika konflik)
rm Package.resolved
swift package resolve

Local Package untuk Development

swift
// Gunakan local package saat develop library secara paralel dengan app

// Package.swift
let package = Package(
    name: "MyApp",
    dependencies: [
        // Production: gunakan remote
        // .package(url: "https://github.com/myorg/MyLibrary", from: "1.0.0"),
        
        // Development: gunakan local path (uncomment saat develop library)
        .package(path: "../MyLibrary"),
    ],
    targets: [
        .target(
            name: "MyApp",
            dependencies: ["MyLibrary"]
        )
    ]
)

Binary Targets: Percepat Build dengan Pre-compiled Framework

swift
// Gunakan binary target untuk dependency yang jarang berubah
// dan build-time-nya lama (Firebase, GoogleMLKit, dll)

.binaryTarget(
    name: "FirebaseAnalytics",
    url: "https://github.com/firebase/firebase-ios-sdk/releases/download/10.25.0/FirebaseAnalytics.zip",
    checksum: "abc123..."
)

// Atau local .xcframework
.binaryTarget(
    name: "MyPrecompiledSDK",
    path: "Frameworks/MyPrecompiledSDK.xcframework"
)

SPM Plugin: Integrasi Tool di Build Process

swift
// Buat build tool plugin yang dijalankan setiap build

// Package.swift
.plugin(
    name: "GenerateResources",
    capability: .buildTool(),
    dependencies: ["ResourceGenerator"]
),

// Plugin implementation
import PackagePlugin

@main
struct GenerateResourcesPlugin: BuildToolPlugin {
    func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
        let resourceFiles = target.directory.appending("Resources")
        let outputFile = context.pluginWorkDirectory.appending("GeneratedResources.swift")
        
        return [
            .buildCommand(
                displayName: "Generate Resources",
                executable: try context.tool(named: "ResourceGenerator").path,
                arguments: [resourceFiles.string, outputFile.string],
                inputFiles: [resourceFiles],
                outputFiles: [outputFile]
            )
        ]
    }
}