Swift Package Manager
Swift Package Manager 入門
1. Swift Package Manager (SPM) とは?
Swift Package Manager (SPM) は、Appleが開発したSwift言語用の公式パッケージマネージャーです。コードの依存関係を管理し、ビルドプロセスを自動化する役割を担います。
SPMの主な目的
- 依存関係の管理: 外部ライブラリやフレームワークの自動ダウンロードと管理
- ビルドの自動化: コンパイル、リンク、実行の一元管理
- モジュールの組織化: コードをモジュール単位で整理し、再利用可能な形で提供
SPMを利用するメリット
- 標準化: Swift言語の標準ツールとして、他のツールとの連携が容易
- シンプルさ: 複雑な設定不要で、最小限のコードでパッケージを作成可能
- バージョン管理: セマンティックバージョニングによる依存関係の適切な管理
- クロスプラットフォーム: macOS、Linux、Windowsで動作
- Xcodeとの連携: Xcodeプロジェクトでの直接利用が可能
2. 基本的な使い方
パッケージの作成
新しいSwiftパッケージを作成するには、swift package init コマンドを使用します:
# ライブラリパッケージの作成swift package init
# 実行可能なパッケージの作成swift package init --type executable
# 特定の名前でパッケージを作成swift package init --name MyPackagePackage.swift(マニフェストファイル)
Package.swiftは、パッケージの設定を定義するマニフェストファイルです。基本的な構造は以下の通りです:
import PackageDescription
let package = Package( name: "MyPackage", platforms: [ .macOS(.v12), .iOS(.v15) ], products: [ .library( name: "MyLibrary", targets: ["MyLibrary"] ), ], dependencies: [ .package(url: "https://github.com/apple/swift-algorithms", from: "1.0.0"), ], targets: [ .target( name: "MyLibrary", dependencies: [ .product(name: "Algorithms", package: "swift-algorithms") ] ), .testTarget( name: "MyLibraryTests", dependencies: ["MyLibrary"] ), ])主要な設定項目
name: パッケージ名platforms: 対応プラットフォームと最小バージョンproducts: 生成されるライブラリや実行可能ファイルdependencies: 外部パッケージの依存関係targets: ソースコードの構成単位(ビルド対象)
基本コマンド
# パッケージのビルドswift build
# 実行可能ファイルの実行swift run
# テストの実行swift test
# 依存関係の解決swift package resolve
# パッケージ情報の表示swift package describe3. 依存関係の管理
外部パッケージの追加
外部パッケージを依存関係に追加するには、Package.swiftのdependencies配列に追加します:
dependencies: [ // GitHub上のパッケージ .package(url: "https://github.com/apple/swift-algorithms", from: "1.0.0"),
// 特定のバージョンを指定 .package(url: "https://github.com/apple/swift-collections", exact: "1.1.0"),
// バージョン範囲を指定 .package(url: "https://github.com/apple/swift-log", "1.0.0"..<"2.0.0"),
// ブランチを指定 .package(url: "https://github.com/example/package", branch: "main"),
// コミットを指定 .package(url: "https://github.com/example/package", revision: "abc123"),]バージョン指定の方法
SPMでは、セマンティックバージョニング(SemVer)に基づいた複数のバージョン指定方法があります:
from: "1.0.0": 指定したバージョン以上の最新版を使用"1.0.0"..<"2.0.0": 範囲指定(1.0.0以上、2.0.0未満)exact: "1.1.0": 特定のバージョンのみを使用upToNextMajor(from: "1.0.0"): メジャーバージョンが変わらない範囲で最新版を使用upToNextMinor(from: "1.1.0"): マイナーバージョンが変わらない範囲で最新版を使用branch: "develop": 特定のブランチを使用revision: "abc123": 特定のコミットを使用
依存関係の更新
# 依存関係を最新版に更新swift package update
# 特定のパッケージのみ更新swift package update PackageName
# 依存関係の解決のみ実行(更新はしない)swift package resolvePackage.resolved ファイル
Package.resolvedファイルは、プロジェクトで使用している依存関係の正確なバージョンを記録します:
- 目的: 再現可能なビルドを保証
- 管理: Gitでバージョン管理に含める
- 更新:
swift package update時に自動更新 - 内容: 各依存関係の正確なコミットハッシュとバージョン情報
{ "pins": [ { "identity": "swift-algorithms", "kind": "remoteSourceControl", "location": "https://github.com/apple/swift-algorithms", "state": { "revision": "b14b7f4c528c942f121c8b860b9410b2bf57825e", "version": "1.2.0" } } ]}4. Xcodeとの連携
XcodeプロジェクトでSPMパッケージを利用する
Xcode 11以降では、SPMパッケージを直接Xcodeプロジェクトに統合できます:
1. パッケージの追加
- Xcodeでプロジェクトを開く
- File > Add Package Dependencies… を選択
- パッケージのURLを入力(例:
https://github.com/apple/swift-algorithms) - バージョン指定を選択:
- Up to Next Major Version(推奨)
- Up to Next Minor Version
- Exact Version
- Branch
- Commit
- Add Packageをクリック
- 使用するプロダクトを選択してターゲットに追加
2. パッケージの使用
import Algorithms
struct ContentView: View { let numbers = [1, 2, 3, 4, 5]
var body: some View { VStack { ForEach(numbers.chunked(into: 2), id: \.self) { chunk in Text("\(chunk)") } } }}3. パッケージの管理
- パッケージの更新: Project Navigator の Package Dependencies で右クリック → Update Package
- パッケージの削除: Project Navigator で削除したいパッケージを選択 → Delete
Swift Packageとしてのプロジェクト開発
Swift Packageは、Xcodeで直接開発できます:
# Swift Packageを作成swift package init --type library --name MyAwesomeLibrary
# XcodeでPackage.swiftを開くopen Package.swiftXcodeが自動的にSwift Packageとして認識し、以下の機能が利用できます:
- コード補完
- ビルド
- テスト実行
- デバッグ
- ドキュメント生成
旧来の方法(参考情報)
注意: この方法はXcode 11以前の古い方法で、現在は推奨されません。
# Xcodeプロジェクトファイルを生成(非推奨)swift package generate-xcodeproj現在は、Package.swiftを直接Xcodeで開くことが推奨されています。
5. 発展的なトピック
ライブラリと実行可能ファイルの作成
ライブラリの作成
ライブラリは他のプロジェクトから利用可能なコードを提供します:
products: [ .library( name: "MyLibrary", targets: ["MyLibrary"] ),]実行可能ファイルの作成
実行可能ファイルは、直接実行できるプログラムを作成します:
products: [ .executable( name: "MyCLITool", targets: ["MyCLITool"] ),]
targets: [ .executableTarget( name: "MyCLITool", dependencies: [] ),]import Foundation
print("Hello, Swift Package Manager!")リソース(画像、データファイルなど)の扱い
Swift 5.3以降では、パッケージにリソースファイルを含めることができます:
リソースの定義
targets: [ .target( name: "MyLibrary", dependencies: [], resources: [ // 特定のファイルを指定 .process("Resources/config.json"),
// ディレクトリ全体をコピー .copy("Assets"),
// パターンマッチングでファイルを指定 .process("Data", localization: .base), ] ),]リソースの利用
import Foundation
// リソースファイルへのアクセスguard let resourceURL = Bundle.module.url(forResource: "config", withExtension: "json") else { fatalError("設定ファイルが見つかりません")}
let data = try Data(contentsOf: resourceURL)let config = try JSONDecoder().decode(Config.self, from: data)ディレクトリ構造の例
MyPackage/├── Package.swift├── Sources/│ └── MyLibrary/│ ├── MyLibrary.swift│ ├── Resources/│ │ └── config.json│ └── Assets/│ ├── icon.png│ └── data.txt└── Tests/ └── MyLibraryTests/ └── MyLibraryTests.swiftプラグインの利用
Swift 5.6以降では、ビルドプロセスを拡張するプラグインが利用できます:
コマンドプラグイン
targets: [ .plugin( name: "MyCodeGenPlugin", capability: .command( intent: .custom(verb: "generate-code", description: "Generate Swift code"), permissions: [ .writeToPackageDirectory(reason: "Generate source files") ] ) ),]ビルドツールプラグイン
targets: [ .target( name: "MyLibrary", dependencies: [], plugins: ["SwiftProtobuf"] ),]プラグインの実行:
# コマンドプラグインの実行swift package plugin generate-code
# 利用可能なプラグインの確認swift package plugin --list