Swift Package Manager
44.1 Package.swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "WeatherKit",
platforms: [.macOS(.v14), .iOS(.v17)],
products: [
.library(name: "WeatherKit", targets: ["WeatherKit"]),
.executable(name: "weather-cli", targets: ["WeatherCLI"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.5.0"),
.package(url: "https://github.com/apple/swift-collections", from: "1.1.0"),
],
targets: [
.target(
name: "WeatherKit",
dependencies: [.product(name: "Collections", package: "swift-collections")],
resources: [.process("Resources")],
swiftSettings: [.enableUpcomingFeature("ExistentialAny")]
),
.executableTarget(
name: "WeatherCLI",
dependencies: ["WeatherKit", .product(name: "ArgumentParser", package: "swift-argument-parser")]
),
.testTarget(name: "WeatherKitTests", dependencies: ["WeatherKit"]),
],
swiftLanguageModes: [.v6]
)44.2 Commands
Concepts: products, targets, Package.resolved (lock file), resources (Bundle.module), binary targets (XCFrameworks), C/C++ targets, conditional dependencies by platform, plugins (build-tool plugins like SwiftGen/OpenAPI, command plugins like swift-format), local packages (.package(path:)), the Swift Package Index (swiftpackageindex.com), and registries.
swift package init --type library|executable|tool|macro|build-tool-plugin|command-plugin
swift build # debug build
swift build -c release
swift run weather-cli --city Pune
swift test --parallel
swift test --filter WeatherKitTests.ParserTests
swift package resolve | update | show-dependencies | describe
swift package add-dependency https://github.com/apple/swift-log --from 1.6.0 # (6.0)
swift package generate-documentation # with the DocC plugin
swift build --swift-sdk x86_64-swift-linux-musl # static Linux SDK (cross-compilation)44.3 Command-Line Tools with ArgumentParser
import ArgumentParser
@main
struct Weather: AsyncParsableCommand {
static let configuration = CommandConfiguration(abstract: "Fetch the weather for a city.")
@Argument(help: "The city name.") var city: String
@Option(name: .shortAndLong, help: "Units: metric or imperial.") var units = "metric"
@Flag(help: "Show verbose output.") var verbose = false
mutating func run() async throws {
if verbose { print("Fetching \(city) in \(units)...") }
print("☀️ 28°C in \(city)")
}
}