この記事は、Swift Package Manager (以下 SwiftPM) の Version 3 から 4 への変更内容をまとめたものです。
有効に活用するためにはさらに掘り下げていきたいところですが、この記事では概要にとどめています。なお SwiftPM の基本的な使い方はすでに 参考になるスライド、記事、ツール がありますのでそちらを参考にしてください。
はじめに
SwiftPM は Swift 3 で登場しました。まだ発展途上で CocoaPods や Carthage に変わる存在とまではいかないものの、すでに Swift 製のコマンドラインツールやサーバーサイド Swift で活用されています。
さて今回の WWDC17 ではどのような発表があったのか、ビデオとスライドで確認しました。ただこれまで見た限り Session 402「What’s New in Swift」 で少し触れられているだけで詳しくは語られていないようです。
そこで Swift Evolution を確認しました。
Swift Evolution
検索欄に「Package Manager」と入力して SwiftPM 関連を抽出しました。
 
14 件のプロポーザルが抽出されますが Swift 4 で実装されたものは次の 6 件です。
Swift 4 で実装されたもの
- SE-0146 Package Manager Product Definitions
- SE-0149 Package Manager Support for Top of Tree development
- SE-0150 Package Manager Support for branches
- SE-0158 Package Manager Manifest API Redesign
- SE-0162 Package Manager Custom Target Layouts
- SE-0175 Package Manager Revised Dependency Resolution
このほか、すでに実装されていましたが Swift 4 に関わるものとして次のプロポーザルがあります。
Swift 3.1 で実装されたもの
それぞれの概要
SE-0151 Package Manager Swift Language Compatibility Version
- 後方互換性維持のため Swift 3.1 で実装されました。
Example
let package = Package(
    name: "Pancake",
    ...
    swiftLanguageVersions: [3, 4])
事例
SwiftPM Version 3
- 
swiftLanguageVersions: [3]- Swift 3 でコンパイルされます。
 
- 
swiftLanguageVersions: [4]- SwiftPM Version 3 が Swift 4 をサポートしていないためエラーになります。
 
- 
swiftLanguageVersions: [3, 4]- Swift 3 でコンパイルされます。
 
SwiftPM Version 4
- 
swiftLanguageVersions: [3]- Swift 3 でコンパイルされます。
 
- 
swiftLanguageVersions: [4]- Swift 4 でコンパイルされます。
 
- 
swiftLanguageVersions: [3, 4]- Swift 4 でコンパイルされます。
 
SE-0152 Package Manager Tools Version
- 後方互換性維持のため Swift 3.1 で実装されました。
SwiftPM Version 4 を使用している場合
Package のツールバージョンを確認
$ swift package tools-version
4.0.0
Version 3 に設定
$ swift package tools-version --set 3.0.0
$ swift package tools-version
3.0.0
使用中のツールバージョンに設定
$ swift package tools-version --set-current
$ swift package tools-version
4.0.0
SE-0146 Package Manager Product Definitions
- Product が導入されました。
- Package 内で任意の Target を限定して公開できるようになりました。(従来は Package を分割する必要がありました)
 
- マニフェスト(Package.swift)が Version 3 の場合は既存コードへの影響はありません。
SE-0149 Package Manager Support for Top of Tree development
- 
$ swift package editコマンドに--pathオプションが追加されました。
- 既存コードへの影響はありません。
SE-0150 Package Manager Support for branches
- 依存する Package のブランチやリビジョンを指定できるようになりました。(従来は Version(タグ)を指定する必要がありました)
- 既存コードへの影響はありません。
Example
import PackageDescription
let package = Package(
    name: "Pancake",
    dependencies: [
        .Package(url: "../PancakeCore", branch: "matcha"),
    ]
)
Example
import PackageDescription
let package = Package(
    name: "Pancake",
    dependencies: [
        .Package(url: "../PancakeCore", revision: "0123456789012345678901234567890123456789"),
    ]
)
リビジョンは 40 文字のコミットハッシュを指定します。
SE-0158 Package Manager Manifest API Redesign
- マニフェストの既存 API が再設計されました。
- Version の指定方法などが変更されました。
 
- 新機能追加は別のプロポーザルで行われています。
SE-0162 Package Manager Custom Target Layouts
- マニフェストで Target を明示的に宣言するようになりました。(省略不可)
- 
SourcesやTestsのパスを任意に指定できるようになりました。(従来は規定がありました)
- 
Targetクラスに 3 つのプロパティが追加されました。- 
path: Package のルートディレクトリを基準にソースファイルのパスを指定します。
- 
sources: Target に含めるソースを指定します。デフォルトはnilですべてのファイルが対象になります。
- 
exclude: ソースから除外するディレクトリやファイルを指定します。sourcesの設定より優先されます。(従来はPackageクラスで設定していましたがこちらは削除されました)
 
- 
- マニフェストが Version 3 の場合は既存コードへの影響はありません。
Example
.target(name: "Pancake", path: "Sources/Pancake", exclude: ["Tests"]),
.testTarget(name: "PancakeTests", dependencies: ["Pancake"], path: "Sources/Pancake/Tests"),
Version 4 への移行
前述のとおり Package のマニフェストが Version 3 の場合は既存コードへの影響はありませんが、Version 4 へ移行する場合はマニフェストを更新する必要があります。
Package.swift
Sources/
Tests/
import PackageDescription
let package = Package(
    name: "Pancake",
    targets: [
        .target(name: "Pancake", path: "Sources"),
        .testTarget(name: "PancakeTests", dependencies: ["Pancake"], path: "Tests"),
    ]
)
SE-0175 Package Manager Revised Dependency Resolution
- 依存関係解決処理の改善が図られました。
- 
$ swift package pin/unpinコマンドが廃止されました。
- 
$ swift package fetchコマンドが$ swift package resolveコマンドに置き換えられました。
- 
Package.pinsファイルがPackage.resolvedファイルに置き換えられました。
 
- 
参考
- [swift-build-dev] Swift 4 Package Manager Update
- Swift Package Manager Manifest API Redesign
- State of the Swift PM from the Swift PM PM @ericasadun
- http://ericasadun.com/2017/06/06/state-of-the-swift-pm-from-the-swift-pm-pm/
- 実践 Swift Package Manager @ikesyo
- https://speakerdeck.com/ikesyo/shi-jian-swift-package-manager
- Swift Package Manager (SwiftPM) で作るコマンドラインツール」@mono0926
- http://qiita.com/mono0926/items/e8fdd97115780204f797
- 実践Server Side Swift @noppoMan722
- https://speakerdeck.com/noppoman/shi-jian-server-side-swift
- swift-tweets/swtws @koher
- https://github.com/swift-tweets/swtws
以上、詳しくは今後別の記事で紹介します。