Swift Package Managerの使い方

# Swift Packager Manager(SwiftPM)とは？
ライブラリの依存関係を管理してくれるツールで、
`CocoaPods` や `Carthage` と同じようなものです。
マルチプラットフォームで使えるのでサーバーサイドSwift[^1]で採用されています。

GitHub: [apple/swift-package-manager](https://github.com/apple/swift-package-manager)

略称は `SPM`、`SwiftPM` の2つが見られますが、
ドキュメントでは後者が使われているので `SwiftPM` を使います。

ここでは使い方を紹介します。なおライブラリの作り方は別にまとめました。
[SwiftPM ライブラリとシステムモジュールを作る方法](http://qiita.com/_tid_/items/bb1b504b28d80153937b)

[^1]: [IBM-Swift/Kitura](https://github.com/IBM-Swift/Kitura)など。


## SwiftPMの使い方
### セットアップ
まずは作業ディレクトリを作成します。

```
$ makedir Sample
$ cd $_
$ swift package init --type=executable
```
```output
Creating executable package: Sample
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/
```

### 依存パッケージ(ライブラリ)を指定する
`Package.swift` に依存パッケージを指定します。

```swift
import PackageDescription

let package = Package(
    name: "Sample",
    dependencies: [
        .Package(url: "git@github.com:tid-kijyun/SamplePackage.git", majorVersion: 1)
    ]
)
```

#### バージョンの指定

依存パッケージの指定部分は複数のイニシャライザが用意されています。
これらを使うことで、より細かいバージョン指定が可能です。

```swift
.Package(url: String, versions: Range<Version>)

.Package(url: String, versions: ClosedRange<Version>)

.Package(url: String, majorVersion: Int)

.Package(url: String, majorVersion: Int, minor: Int)

.Package(url: String, _ version: Version)
```

```swift
// バージョン1.0.0以上1.2.0以下
.Package(url: "git@github.com:tid-kijyun/SamplePackage.git", versions: "1.0.0"..."1.2.0")

// バージョン1.0.0以上2.0.0未満
.Package(url: "git@github.com:tid-kijyun/SamplePackage.git", versions: "1.0.0"..<"2.0.0")

// メジャーバージョン1の最新版(上と同じ)
.Package(url: "git@github.com:tid-kijyun/SamplePackage.git", majorVersion: 1)

// メジャーバージョン1、マイナーバージョン2の最新版
.Package(url: "git@github.com:tid-kijyun/SamplePackage.git", majorVersion: 1, minor: 2)

// バージョンを固定する
未実装、ピン機能というのが実装されるようです。(SE-0145)
```

バージョンを文字列で指定する場合は下記フォーマットに従う必要があります。
このフォーマットに従っていないパッケージは利用できません。

```swift
"major.minor.patch[-prereleaseIdentifiers][+buildMetadata]"
```

#### @swift-3
GitHubを見ているとフォーマットに一致していない `3.0.1@swift-3` のようなタグを見かけるかもしれません。
この `@swift-3` はSwiftPMが自動判別して利用するオプションなので使う側は気にする必要はありません。

詳細は[Version-specific tag selection](https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md#version-specific-tag-selection)を参照してください。

### 依存パッケージのビルド
```shell
$ swift build
```
```output
Cloning git@github.com:Alamofire/Alamofire.git
HEAD is now at 7a17b1d Added release notes to the CHANGELOG and bumped the version to 4.2.0.
Resolved version: 4.2.0
Compile Swift Module 'Alamofire' (17 sources)
Compile Swift Module 'Sample' (1 sources)
Linking ./.build/debug/Sample
```

### コーディング
`Sources/main.swift` にコードを記述します。

```main.swift
import SamplePackage

sayHello()
```

### ビルド
```
$ swift build
```
```output
Compile Swift Module 'Sample' (1 sources)
Linking ./.build/debug/Sample
```

### 実行
```
$ .build/debug/Sample
```

### その他

#### Xcodeを使う
コマンドでXcodeのプロジェクトを生成できます。
ただし依存パッケージを追加・削除するたびに実行する必要があります。

```
$ swift package generate-xcodeproj
```

```output
generated: ./Sample.xcodeproj
```

#### SwiftPMを使用した時だけ実行するコード

SwiftPMのビルド環境では `SWIFT_PACKAGE` が定義されているのでこれを利用します。

```swift
#if SWIFT_PACKAGE
import SamplePackage
#endif
```

このようにすると、SwiftPMを使用した時だけ `import SamplePackage` が実行されます。

### 参考
[Swift Package Manager Documentation](https://github.com/apple/swift-package-manager/tree/master/Documentation)