iOS 10が正式リリースされた今、そろそろ既存アプリのiOS 8サポートは切っても良いだろうかという考察

ご存じの通り、[iOS 10](http://www.apple.com/ios/ios-10/)が2016年9月13日(日本時間14日早朝)に正式リリースされました:tada: 

iOS 8は2年前の2014年9月17日正式リリースでしたが、現在iOS 8.0以上をサポート対象として開発中の[JOIN US iOS版アプリ](https://itunes.apple.com/jp/app/join-us/id918363882?mt=8;)において、そろそろそのサポートを切っても良いのでは？と考えました。
以下、iOS 8.0以上をサポートしている既存アプリを、iOS 9.0以上サポートに変更しても良いだろうか、という視点中心に古いiOSバージョンを切り捨てることの考察をしていきます。
(その他のバージョン間にも通じる話が多いはずなので、その場合適当に読み替え・解釈お願いします。)

# iOSのバージョンごとのシェア

2016年9月12日時点で、このようになっていて、9割弱がすでにiOS 9になっていました。

<img width="287" alt="Screen Shot 2016-09-15 at 1.12.01 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/19398/8898dfef-011c-f5c0-cfb5-5adcf0c46a3c.png">
https://developer.apple.com/support/app-store/

ただ、これはあくまでAppleの公表しているデータであって、開発しているアプリでのiOSバージョンサポートを検討する際はその実際のデータを見た方が良いです。
例として、今開発中の[JOIN US iOS版アプリ](https://itunes.apple.com/jp/app/join-us/id918363882?mt=8;)はiOS 8.0以上でインストール出来るように設定していますが、すでに94%ほどがiOS 9ユーザーとなっていました。([Google Analytics](https://www.google.com/analytics)・[Fabric](https://fabric.io)などで確認出来ます。)

これはあくまでiOS 10正式リリース直前のデータであって、今後iOS 8のシェアはもっと減っていくでしょう。(1年後のAppleの公表データは、上のグラフを参考に単純に考えるとiOS 8以下のシェアが3%程度になるはず。)

あとは、サポートiOSバージョンを絞ることによる開発効率アップ・新機能の導入しやすさと、数%のユーザーのインストール機会を奪ってしまうことと、どちらを優先するかですね。
個人的には、現在のシェアを見た時点で、ある程度iOS 8.0サポートを切りたい理由があれば、切っちゃって良いかなと感じました。

# iOS 8.0サポートを切るメリット

## 開発効率アップ

シミュレーターや検証機で開発する際、僕はその時点で一番シェアの大きな端末でメインに開発しつつ他のOSやデバイスでも問題無く動くように頭の中でイメージして、たまに適当に他の端末に切り替えて実際に確認しながら進めています。

iOS 10が登場したことで、OSバージョンだけでも大きくiOS 8・9・10の3種類(マイナーバージョンまで確認しようとするとさらにたくさん)で正常動作するように気を付けながら開発していく必要が出てきました。
ここでiOS 8.0を切ると、また2種類に戻って楽になりそうです(　´･‿･｀)

とはいえ、iOS 8.0以降では厄介な変更が少ない(iOS 6/7あたりはキツかったですが)ので、お行儀良い実装を心がけていれば、特定OSバージョンでのみバグることは稀で、開発工数に対してすごく差が出るところでも無い気もしています。

## 新機能を使いやすくなる

個人的には、毎年新iOS SDKに載る新機能を使いやすくなる、というのが大きいと思っています。
新しいiOSでしか使えない機能を使いたい場合、分岐コードが必要になって、段々汚くなってきますし、この場合はどちらでも正常動作するように丁寧な確認も必要となってきます。

また、[UIStackView](https://developer.apple.com/reference/uikit/uistackview)のようにUI実装が簡単になるコンポーネントは、処理分けして新OSでのみ使うのはむしろ手間なので、実質古いiOSサポートを切る(`UIStackView`の場合iOS 8を切る)まで使うことが出来ません。このコンポーネントは、使うとけっこう捗りそうなので早くiOS 8切りたいなーと思っていました。

一方、この類いの他の例として、iOS 10で登場した[OSLog](https://developer.apple.com/reference/os/oslog)は、さらにiOS 9切るまで使えず、まだしばらくお預けです(´・︵・｀)

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">一瞬乗り換えようかと思ったけど、iOS 10でしか使えないからダメだ(　´･‿･｀)<br><br>[iOS 10] OSLog でアプリログを出力する｜クラスメソッドブログ <a href="https://t.co/rzOy0nz9Yg">https://t.co/rzOy0nz9Yg</a></p>&mdash; M Ono (@_mono) <a href="https://twitter.com/_mono/status/775882025639170048">September 14, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## テストの手間削減

自動テストにもある程度関わりますが、手動の動作確認の手間が一番大きいと感じています。
開発面での理由よりもむしろこちらの手間の方が大きいかなと思うくらいです。
手動テストの手間は、対応OSの種類数にほぼ比例するはずです。

また、検証端末も揃えておく必要もあって、お金なども嵩みます。

# iOS 8.0サポートを続けるメリット

単純に、数%のユーザーを失わずに済む、ということに尽きるかと思います。

ただ、その既存アプリがiOS 8以上サポート(iOS 7を切る)という判断をしたことを思い出してみると、実は当時iOS 7を切り捨てた影響(シェア)の方が大きかったりということなどよくありそうです。
初期判断では潔く古いOS切れても、一旦リリースしてしまうとその後古いOSを切ることに抵抗感じたりしがちですが、基本的に気持ちの問題とみなして数値でドライに判断するのが得策かなと思います。

以上踏まえて、まだiOS 10が出たばかりなので、さすがに今すぐというのは早いと思うものの、次開発やテスト的にiOS 8対応が足かせになっていると感じたタイミングで潔く切るくらいがちょうど良いかなという結論に至りました。

しかし…

# 今回はもうiOS 8.0切りたいと思った理由

iOS 8.0はもう少しサポート続けようかなと思いつつ、Xcode 8・Swift 3.0への移行作業をしている時に以下の問題に気付きました。

## Alamofire 4.0がiOS 9.0以上のみのサポートになった

Alamofireを[最新の4.0.0](https://github.com/Alamofire/Alamofire/releases/tag/4.0.0)に上げたら、サポート対象が9.0以上になっていて、あれ？と思って調べたら、そのようなポリシーとのことでした。4.0ではiOS 10 SDKで使える[URLSessionTaskMetrics](https://developer.apple.com/reference/foundation/urlsessiontaskmetrics)も導入されたりした分、分岐コードがどんどん増えていくのを避けるために古いiOSのサポートを削る、というのは妥当だと思いました。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Alamofire 4.0で、iOS 8サポート切られることを今知った(　´･‿･<br><br>Swift 3 branch dropping iOS 8 support · Issue #1367 · Alamofire/Alamofire <a href="https://t.co/aD0u5ErajF">https://t.co/aD0u5ErajF</a></p>&mdash; M Ono (@_mono) <a href="https://twitter.com/_mono/status/775578409028104192">September 13, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

[Swift 3 branch dropping iOS 8 support · Issue #1367 · Alamofire/Alamofire](https://github.com/Alamofire/Alamofire/issues/1367) の以下の記述もあったり、 https://github.com/Alamofire/Alamofire/issues/1367#issuecomment-239779219 でその見解の詳細が引用されていたりして、参考になりました。
> Apple recommends that developers always support the two latest operating systems.

ちなみに、[3.5.0](https://github.com/Alamofire/Alamofire/releases/tag/3.5.0)はSwift 2.3対応かつ、iOS 8のサポートも継続されています。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Alamofire、Xcode 8対応でCocoaPodsのpreバージョン必要ななことと、Swift 2.3には3.5、Swift 3には4.0ということがとにかく理解されてなくて破滅してて大変に見えるし絶対サポートしたくない。</p>&mdash; Syo Ikeda / いけしょー (@ikesyo) <a href="https://twitter.com/ikesyo/status/776073125435879425">September 14, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ただ、個人的にはいきなりSwift 3.0に移行するのが得策と考えつつ作業していたため、iOS 8は切るしか無いかなという結論に至りました。
(結果的には「得策」じゃ無かったかもですが、結果論だと思っています。)

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Swift 2.3は完全無視してる(　´･‿･｀)<br>遠回りだ(　´･‿･｀)</p>&mdash; M Ono (@_mono) <a href="https://twitter.com/_mono/status/773830582115508224">September 8, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

代案としては、以下などありますね。

- 違うライブラリに乗り換え
    - けっこうな手間がかかるのはもちろん、ネットワーク系処理ライブラリのド定番であるAlamofire以外の選択を取るのは気が進まない
- 自前実装に切り替え
    - 数年前と比べて標準APIがかなり良い感じになったので充分ありだと思う
    - iOS 8サポート切ることにOK出た個人的事情もあり、Alamofire継続の方が工数抑えられて良さそう

ちなみに、今移行作業中ですが、Alamofireを[RxSwift](https://github.com/ReactiveX/RxSwift)と連携するための[RxAlamofire](https://github.com/ReactiveX/RxSwift)の対応で苦戦中です(　´･‿･｀)現時点でRxSwift 3.0.0・Alamofire 4.0とコンパイルの通るRxAlamofireのコードが見つからず、とりあえず自力で対応中です(　´･‿･｀)

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">RxAlamofireのRxSwift 3.0.0・Alamofire 4.0対応が熱い😇(つらい)</p>&mdash; M Ono (@_mono) <a href="https://twitter.com/_mono/status/776257729971183616">September 15, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
→ [良い感じのPull Request](https://github.com/RxSwiftCommunity/RxAlamofire/pull/41)来てました🎉

# iOS 8.0サポートを切った時の影響

というわけで、Xcode 8・Swift 3.0への移行とともにiOS 8.0サポートを切る、という判断になったのですが、その影響について書きます。

## 既存のiOS 8ユーザーはアプリをそのまま使える

iOS 8を切ったバージョンをリリースすると、iOS 8ユーザーは新規インストールを出来なくなってしまいますが、すでにインストール済みのiOS 8ユーザーは古いバージョンのアプリを使い続けることが出来ます。

ただ、JOIN USでは大きな変更タイミングで、アプリ内制御で強制アップデート(古いバージョンのアプリを起動するとAppStoreへ強制遷移させてアップデートを促すこと)を実施していますが、次のその実施タイミング以降使えなくなってしまいます。

## iOS 8ユーザーがiOS 9以上サポートのアプリをインストールしようとするとアラートが出る

また、iOS 8サポートを切ったからといって、iOS 8ユーザーから見えなくなってしまうというわけではありません。
iOS 9以上サポートのアプリをインストールしようとすると、下のスクショのアラートビューが表示されるので、アプリ使いたいユーザーはOSアップデートしてくれるかもしれません。
(1つのアプリのためにやるユーザーは少ないかもしれませんが、そういうアプリが増えてくれば期待出来そうです。)

<img width="320" alt="IMG_4742.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/19398/d517c0ac-015e-917c-8e4b-719f43bd2c08.png">
( @yabuchin_y さん提供のスクショです :bow: )

---

というわけで、新OSシェアがどんどん増えてくれると嬉しいです(　´･‿･｀)

![mate.png](https://qiita-image-store.s3.amazonaws.com/0/19398/1dbcec82-c712-3568-1d3a-3ae852a820be.png)
https://store.line.me/stickershop/product/1000854