Swift Package Manager で外部ライブラリを使いコマンドラインツールを開発する

Linuxでも動くPure SwiftなコマンドラインツールでRedisとしゃべりたかったので、 [czechboy0/Socks](https://github.com/czechboy0)を使ってTCP接続した(Socks自体はCのライブラリ使ってる)。
Socksをビルドに組込み、MacのXcodeで開発できるように [Swift Package Manager](https://github.com/apple/swift-package-manager) を利用した。
サーバーサイドSwiftのWebアプリやライブラリ開発も同じような方法でできるんじゃないかと予想している。

## 準備

Xcode 8 beta と `swift-DEVELOPMENT-SNAPSHOT-2016-08-18-a` でないとSocksがビルドできないのでインストールしておく
https://swift.org/download/#releases

## プロジェクト作成

```
$ mkdir MyProject
$ cd MyProject/
$ swift package init --type executable

Creating executable package: MyProject
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/
```

## 外部ライブラリを組込む

```diff
diff --git a/Package.swift b/Package.swift
index 7f62404..ec40617 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,5 +1,8 @@
 import PackageDescription
 
 let package = Package(
-    name: "MyProject"
+    name: "MyProject",
+    dependencies: [
+        .Package(url: "https://github.com/czechboy0/Socks.git", majorVersion: 0, minor: 12)
+    ]
 )
```

```
$ swift package update

Cloning https://github.com/czechboy0/Socks.git
HEAD is now at 4b14189 Updated Swift 08-04 (#69)
Resolved version: 0.12.0
```

```
$ TOOLCHAINS=swift swift build

Compile Swift Module 'SocksCore' (14 sources)
Compile Swift Module 'Socks' (5 sources)
Compile Swift Module 'SocksCoreExampleTCPServer' (1 sources)
Compile Swift Module 'SocksCoreExampleTCPClient' (1 sources)
Compile Swift Module 'SocksExampleUDPServer' (1 sources)
Compile Swift Module 'SocksExampleUDPClient' (1 sources)
Compile Swift Module 'SocksExampleTCPServer' (1 sources)
Compile Swift Module 'SocksExampleTCPClient' (1 sources)
Compile Swift Module 'SocksCoreExampleTCPKeepAliveServer' (1 sources)
Compile Swift Module 'MyProject' (1 sources)
Linking ./.build/debug/SocksCoreExampleTCPClient
Linking ./.build/debug/SocksCoreExampleTCPServer
Linking ./.build/debug/MyProject
Linking ./.build/debug/SocksExampleUDPClient
Linking ./.build/debug/SocksExampleTCPClient
Linking ./.build/debug/SocksExampleTCPServer
Linking ./.build/debug/SocksExampleUDPServer
Linking ./.build/debug/SocksCoreExampleTCPKeepAliveServer
```

```
$ swift package generate-xcodeproj

generated: ./MyProject.xcodeproj
```

こういう構造のプロジェクトが生成される。Package.swift に新たなライブラリを追加したら `Dependencies` へ反映するためにまた生成し直す。

![Screen Shot 2016-08-21 at 1.01.23 AM.png](https://qiita-image-store.s3.amazonaws.com/0/229/6cc98c37-103e-0647-e8f6-55124af31012.png)

コマンドラインツール本体のコード。

```main.swift
import Socks

let address = InternetAddress(hostname: "localhost", port: 6379)

do {
    let client = try TCPClient(address: address)
    
    // set
    try client.send(bytes: "SET key1 hello\n".toBytes())
    let status = try client.receiveAll().toString()
    print("Received: \(status)")
    
    // get
    try client.send(bytes: "GET key1\n".toBytes())
    let str = try client.receiveAll().toString()
    print("Received: \(str)")
    
    try client.close()
} catch {
    print("Error \(error)")
}
```

これをXcodeから実行すると

![Screen Shot 2016-08-21 at 1.13.20 AM.png](https://qiita-image-store.s3.amazonaws.com/0/229/a6fc4cc4-5221-56e5-e1c6-309614bf972b.png)

SET/GET できることを確認できた