Apple Watch 対応プロジェクトで APIKit がリンクできなくて困った話

# (追記) 注意: この記事に書かれた内容はすでに古くなっています

コメントで作者の ishkawa さんに教えて頂きましたが 1.1.0 で watchOS と tvOS に対応されたとのことです。
https://github.com/ishkawa/APIKit/releases/tag/1.1.0

したがって、現在は普通にビルドできるようになったため、以下の手順はもう必要ありません。

# 本題に入る前に: Carthage について

Carthage というのは Swift 製のライブラリ管理ツールで、最近のイケてる iOS 開発ではよく使われているらしい。読み方はカルタゴ。

[プロジェクトの release ページ](https://github.com/Carthage/Carthage/releases) からダウンロードできるほか、 Homebrew でもインストールできる。

今回使ったバージョンは 0.11.0 。

```
$ carthage version
0.11.0
```

# XCode でビルドエラーが起きた

Cartfile はこんな感じになってる。


```
github "ikesyo/Himotoki" ~> 1.3
github "ishkawa/APIKit" ~> 1.0.0
```

carthage update を実行する。

```
$ carthage update
*** Fetching APIKit
*** Fetching Himotoki
*** Fetching Result
*** Downloading APIKit.framework binary at "1.0.0"
*** Checking out Himotoki at "1.3.1"
*** Downloading Result.framework binary at "1.0.1: A New Beginning"
*** xcodebuild output can be found in /var/folders/b2/22_2434x6zqc2v02cn1x_vyr0000gn/T/carthage-xcodebuild.DN1obc.log
*** Building scheme "Himotoki-Mac" in Himotoki.xcodeproj
*** Building scheme "Himotoki-tvOS" in Himotoki.xcodeproj
*** Building scheme "Himotoki-watchOS" in Himotoki.xcodeproj
*** Building scheme "Himotoki-iOS" in Himotoki.xcodeproj
```

普通ならこれでビルドできるようになるはずなんだけど、 XCode でビルドを実行すると、 WatchOS ターゲットで ```No such module 'APIKit'``` というエラーが出た。確かに Carthage/Build の下を見ると iOS ディレクトリには APIKit.framework が作られているのに watchOS ディレクトリにはない。

APIKit のリポジトリに [Add build targets for watchOS and tvOS #102](https://github.com/ishkawa/APIKit/pull/102) という pull request があって、 watchOS 対応のコードが追加されているかと思ったら、どうやらこれはマージされなかったようだ。そのため 1.0.0 にはこの機能は含まれていない (タイミングの問題ではなく実装方法が良くなかったという理由なので、開発版を使えばいいという話でもない)。

# 解決策?

本来は APIKit の方で対応してもらうのが筋なんだろうけど、今すぐビルドしたい！ このプロジェクトを！ という状態だったので、そのためにはとにかくこの pull request を手元でコンパイルできればいい。

GitHub では pull/102/head のようなブランチ名を指定すると pull request の内容がチェックアウトできるので、試しに Cartfile のバージョン指定のところにこれを書いてみたがうまくいかなかった。 リビジョンハッシュを指定してもダメ。しかたがないので一旦 fork して、 pull request にブランチ名を付けて push した 。

https://github.com/knzm/APIKit/tree/tv-watch-target

(deleted-tv-watch-target-feature ブランチが pull request の内容そのままで、 tv-watch-target ブランチがそれを master とマージしたもの)

Cartfile を以下のように書き換えて、

```diff
diff --git a/Cartfile b/Cartfile
index c39ed70..bb92519 100644
--- a/Cartfile
+++ b/Cartfile
@@ -1,3 +1,3 @@
 github "ikesyo/Himotoki" ~> 1.3
-github "ishkawa/APIKit" ~> 1.0.0
+github "knzm/APIKit" "tv-watch-target"
```

carthage update を実行したら watchOS 用に APIKit がビルドされて、プロジェクト本体のコンパイルも通るようになった。

```
$ carthage update
*** Fetching APIKit
*** Fetching Himotoki
*** Fetching Result
*** Downloading Result.framework binary at "1.0.1: A New Beginning"
*** Checking out Himotoki at "1.3.1"
*** Checking out APIKit at "5b4f6602ec2b467396e6cfa37e5c866e32668105"
*** xcodebuild output can be found in /var/folders/b2/22_2434x6zqc2v02cn1x_vyr0000gn/T/carthage-xcodebuild.592BVI.log
*** Building scheme "Himotoki-tvOS" in Himotoki.xcodeproj
*** Building scheme "Himotoki-watchOS" in Himotoki.xcodeproj
*** Building scheme "Himotoki-Mac" in Himotoki.xcodeproj
*** Building scheme "Himotoki-iOS" in Himotoki.xcodeproj
*** Building scheme "APIKit-tvOS" in APIKit.xcworkspace
*** Building scheme "APIKit-watchOS" in APIKit.xcworkspace
*** Building scheme "APIKit-Mac" in APIKit.xcworkspace
*** Building scheme "APIKit-iOS" in APIKit.xcworkspace
```

# 余談

最近 GitHub 前提のパッケージ管理システムが増えてきて、それ自体は物事がシンプルになっていいと思うけど、今回みたいなことが起きたときにローカルのリポジトリを指定できないのはちょっと不便だなあ。