iOSアプリのリリース管理術


主に今年学んだリリース周りの諸々の取り組み方やTipsについてご紹介します。
(体系だった感じでは無いですし、網羅性には欠けると思います)

# CI環境

[fastlane](https://fastlane.tools) + [CircleCI](https://circleci.com)で行っています。

去年まではJenkins使っていました(違う職場ですが)が、[Travis CI](http://travis-ci.org)上でビルド・配布のシェルスクリプトを実行するようになり、現在は[fastlane](https://fastlane.tools)を使うようになった、という変遷があります。

TravisとCircleCIはiOSアプリビルドに関しては、大差無いですが、[CircleCI](https://circleci.com)の方がXcode 6.3対応が早かったので乗り換えました。
しかし、[Xcode 7 betaはTravisの方が早くて](http://blog.travis-ci.com/2015-08-26-xcode-70-beta-is-now-available/)、うーんという感じです。

fastlane使っていると、CI環境の設定ファイル(ymlファイルなど)がかなり薄くなるので、CI環境乗換簡単ではあるのですが、CircleCIもわりと早めに対応してくれるであろう期待はあるので、Travisに戻ることはしていません。

この記事書いている時は、Xcode GMが出るであろう数日前という微妙なタイミングで、かつGMリリース日か翌日くらいにはGM版でビルドしたものを申請したいので、それを確実に期待出来るCIサービスも無いかなという判断で、手元のマシンでfastlane実行でしのいでいます。

今はiOSアプリ一人開発体制なので、それでもほとんど困りませんが、毎年こういうことがあるので、
[fastlane](https://fastlane.tools) + [Jenkins](https://jenkins-ci.org)が良いかなと思ってきました。
Jenkinsは、その設定やビルドスクリプトが厚くなってメンテナンスがけっこう大変という思い出があるのですが、fastlane使えばほとんどそちらに寄せられてそういう問題が起こりにくくなると思っていて、相性良いと思います。

というより、fastlaneはCIサービス・Jenkins・手元でのビルド、どれとも相性良くちょっと書き換えれば簡単にスイッチ出来てとても素晴らしいです(　´･‿･｀)

## ビルド対象

デバッグ実行版・AdHoc配布版・Release版の3種類のビルド環境を用意するのが定番だと思いますが、Release版についてはCI環境で何をビルドするべきか、というのは少し迷いました。

2種類選択肢があると思っていて、

- Releaseビルド設定で、Provisioning ProfileはAdHoc版を用いて、[Fabric](http://fabric.io)などで配布
- Releaseビルド設定で、Provisioning ProfileもAppStore版を用いて、Apple TestFlightで配布

まず、後者はiOS 8以降の場合にしか出来ないので、iOS 7も対象の場合は前者一択ですね。
僕は後者で行っています。

理由としては、以下ですね。

- Release版のビルド設定が1つで済む
- iTunesConnectに申請するそのもので試せるので、ミスが入りにくく安心

難点としては、以下が上げられます。

- アップロード完了から配布されるまで15-30分程度タイムラグがある
	- 頻度は少なめですし、実際はそんなにネックに感じません
- 常に最新版しかインストール出来ない
	- 特に、アップデートのテストしたい時に困ります
	- AppStoreにリリースされているものから開発版へのアップデートのテストは出来ますが、それ以前の版からのテストが出来ない
- 内部テスターの場合、配布先がアカウント登録して「管理者」・「法務」・「技術」のいずれかの権限を与えられている必要がある
	- なので、配布先は実質社内メンバーに限られます
	- ただし、外部テスターを利用すればメールアドレスだけで済むのも、社内メンバー以外の関係者に配布する場合もほぼ問題無い
		- 外部テスターはレビューが必要だが、翌日くらいに通り(審査もとても緩い)、さらに2回目以降は即時

参考: [新TestFlightの使用方法 - Qiita](http://qiita.com/annaok/items/9e803fbb03391cf1b388)

# リリースハンドリング

## リリース日予測術

主に、[Average App Store Review Times](http://appreviewtimes.com/)を見ています。

普段は、5 daysくらいが多いですが、7 daysとなっていてグラフも右肩上がりで、今は混んできていることが分かります(　´･‿･｀)

![Screen Shot 2015-09-07 at 6.55.55 AM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/2f615dd3-34ab-b365-312e-dd59628f94d1.png "Screen Shot 2015-09-07 at 6.55.55 AM.png")

アプリ版がリリースされたため、普段はそちら見ています:
[Review Times](http://reviewtimes.cocoanaut.com/)

サクッと確認出来るのはもちろん、レビュー所要平均日数が変化したときに通知が来たりしてとても便利です。

Apple公式情報~~が[App Review - Support - Apple Developer](https://developer.apple.com/support/app-review/)あたりにあったはずですが、久々に見たら消えてる？？~~ から[App Store - Support - Apple Developer](https://developer.apple.com/support/app-store/)にへURL変更となりました。
(@koogawa さん、ありがとうございます！)

さらに、申請日時点でのレビュー所要平均日数から、審査終了日を予測して毎回記録して、実績と比較しています。

![Screen_Shot_2015-09-07_at_7_00_30_AM.jpg](https://qiita-image-store.s3.amazonaws.com/0/19398/b49cbbae-6c32-a590-7f9a-11dcd2dc4a71.jpeg "Screen_Shot_2015-09-07_at_7_00_30_AM.jpg")

これは[今開発中のPlayer!](https://itunes.apple.com/jp/app/player!-minnadetsukurusupotsunyusu/id897872395)でちょうど今朝2.0アップデートをした実際のリリース管理ですが、今回はぴったり予想通りでした。

毎回、こういう予想と評価を繰り返した結果、[Average App Store Review Times](http://appreviewtimes.com/)を元にした予想日の前後1日程度に収まることが8割程度で、けっこう信頼出来る審査終了予想日を提示できるようになりました。
ただし、リジェクトリスクは常にあるので、リリース日がとても大事な時はバッファを持たせたり、いざとなれば特急申請もありなどと用意しています。

## リリースIssueを作る

上のスクリーンショットの1番上のがそれにあたりますが、次のリリースに向けての作業開始したくらいのタイミングで作っています。
そのリリースに向けての相談ごとや懸念点などを随時まとめていけて、便利です。

こんな感じに、リリースに際してのチェック事項なども記載しています。

![Screen Shot 2015-09-07 at 7.36.01 AM.png](https://qiita-image-store.s3.amazonaws.com/0/19398/60114bfb-4cdb-e0ae-4dfa-68239d03bf74.png "Screen Shot 2015-09-07 at 7.36.01 AM.png")

申請前・リリース前などにざっと見返して見落としが無いかチェックして作業しています。

リリースが完了したタイミング(App Storeに並んだタイミング)でクローズしています。

そのリリース時だけでなく、あとで見返す時にも良い記録となっていて良いです(　´･‿･｀)

## リリースノートを軽微な感じにするとレビュー時間が短くなるという噂は本当？

[Rebuild: Aftershow 86: The Japanese Protocol (N)](http://rebuild.fm/86a/)の7分30秒あたりで、「軽微なバグ修正」など、リリースノートを軽微な感じにするとレビュー時間が短くなるかも、みたいな話があって、しばらく実践してた時期がありました。

ただ、上述の評価をした結果、それをやった場合とそうでない場合でレビュー所要時間に差が感じられなかったため、その策はやめました(　´･‿･｀)


## レビュー通過後、リリース前にプロモーションコードを用いたテスト

上述の「Releaseビルド設定で、Provisioning ProfileもAppStore版を用いて、Apple TestFlightで配布」にてテストしている場合、プロモーションコードを用いたテストは基本的にスキップして問題無いと思っています。

関係者に事前配布したい場合も、プロモーションコードを待つのではなく外部テスター使った方が早く出来て便利ですし。
ただ、以下のタイミングでは行うようにしています。

- 初回リリース時
	- なんとなく不安なので(　´･‿･｀)
- Apple TestFlightではなくプロモーションコードを用いてApp Store経由でインストールしないとテスト出来ない場合

「プロモーションコードを用いてApp Store経由でインストールしないとテスト出来ない場合」なんて無いと思っていましたが、先日、[Smart App Banner](https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html)経由でアプリを起動するテストがこれにあたることに気付きました。

[ios - How to test Smart App Banner Urls on in Dev environment - Stack Overflow](http://stackoverflow.com/questions/13078147/how-to-test-smart-app-banner-urls-on-in-dev-environment)

> The following worked for me using an iOS 6 device, because it didn't work with iOS 8.

以前はAppStore版に上書きインストールでも行けたらしいですが、iOS 8だとアプリじゃ無くてApp Storeが開く挙動になってしまっていて、テスト不可でした(´・︵・｀)

特に`app-argument`にWeb URLを指定しておいて該当記事を開く、ということを実装したかったので、プッシュ通知経由で起こして疑似的に再現するなどして多分OKという状態で申請し、レビュー後に「プロモーションコードを用いてApp Store経由でインストール」して無事動作しました(　´･‿･｀)

---

ちょっと雑多な内容となりましたが、僕の今年学んだ色々なTipsを詰め込んだつもりです(　´･‿･｀)