iOS10のサポートを切るときにやったこと

先日、自社アプリのサポートOSを10.0 -> 11.0に変更する対応をしました。
実装するうえで参考になる記事が少なく、手探りでやっていったので、そのときの手順・ハマった点などをメモしておきます:pencil:

# iOS10を切ることにした経緯
もともとチーム内に「管理面や新しい機能を取り入れていくことなどを考えると、古いバージョンを切りたいね」という話がありました。
さくっと調べてみたところ、2019年8月末時点で色々なアプリがiOS10を切り始めていることがわかりました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【iOS10のサポート切ってるアプリ】<br>* Twitter<br>* Slack<br>* Yahoo系列アプリ（ヤフオク、Yahoo!カーナビ、Yahoo! MAPなど）<br>* Kyash<br>* bitFlyer<br>* Eight<br>* SHOWROOM<br>* Airレジ<br>* テラー<br><br>意外と多いな？🤔</p>&mdash; orimomo / engineer📱 (@orimomo_147cm) <a href="https://twitter.com/orimomo_147cm/status/1167761272621785088?ref_src=twsrc%5Etfw">August 31, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

iOS10のサポートを切ると、iPhone5以前のユーザーがアプデできなくなってしまうので、
iPhone5以前を使っているユーザーがどれくらいいるのかを調べたところ、全ユーザーの1％程度でした。
「これはいけそうだね:thumbsup:」という話になり、プロジェクトが立ち上がったのがつい3ヶ月くらい前のことです。

# 実際にやったこと
Xcode11.0使用。

## 最低動作バージョンの変更
まずはわかりやすいところから。
### PROJECTの変更
PROJECTから`iOS Deployment Target`を11.0に変更します。
<img width="1009" alt="スクリーンショット 2019-11-04 0.20.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/e6d2c2f6-d245-a234-b137-c9fe98f7800b.png">

### TARGETSの変更
合わせてTARGETSの`Deployment Info`のTargetを変更します。
（TARGETSが一つだけのときはPROJECTのバージョンを変えるとTARGETSも合わせて変わってくれるけど、複数あるときは自分でポチポチする必要があるっぽい。）
Extensionなどがある場合は、それらも同じように変更します。
PROJECTとTARGETSのバージョンが揃っていないと、意図しないところでエラーになったりするので注意。
<img width="1010" alt="スクリーンショット 2019-11-04 0.20.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/a6029e25-1835-ea7b-447f-18a7daa0102c.png">
ちなみに、2つの設定の関係性がわからず調べたところ、優先度はTARGETS ＞ PROJECTのようでした。

* 個々のTARGETSの設定は、PROJECTの設定を上書きする
* TARGETSに設定がされていないときには、PROJECTの設定が有効になる

[Xcode Overview: Working with Targets](https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/WorkingwithTargets.html)
[iPhone - Xcode 4 target deployment target vs. project deployment target - Stack Overflow](https://stackoverflow.com/a/7105155/11934352)

## Podsプロジェクトの変更
もしCocoaPodを使っているなら、Podsプロジェクトにも変更を加える必要があります。
<img width="147" alt="スクリーンショット 2019-11-05 20.05.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112818/34246f42-fa65-64a1-9d43-3d75fb07de3e.png">
上の項目と同じようにPodsのPROJECTとTARGETSを手動でぽちぽちしていくこともできるとは思いますが、
[このStack Overflow](https://stackoverflow.com/a/57137706)のコメントにあるように、**Podsプロジェクトは自動生成されるもので、将来上書きされる可能性があるのに手動で編集するのは良くない**ということで、Podfileの変更だけで完結させるようにしました。

### プラットフォーム指定を変更
プラットフォームをiOS11以上として指定します。

```
platform :ios, '11.0'
```

こうすることでPROJECTの`iOS Deployment Target`が書き換わります。

### ビルド設定の追加
次にインストール後の後処理（`post_install`フック）の中でTargetを指定します。

```
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
    end
  end
end
```

参考：[iOS - Set deployment target for CocoaPods’s pod - Stack Overflow](https://stackoverflow.com/a/37289688/11934352)

こうすることでTARGETSの`Deployment Info`のTargetが書き換わります。

最後に`pod install`してあげればPodsプロジェクトにバージョンの変更が反映されるはずです。


## コードの変更
もし下記のようにiOS10.0やiOS11.0を判定して処理している箇所があったら、今後は不要なので削除します。

```swift
if #available(iOS 10.0, *) {
    // なにかの処理
}
```

## その他ハマったこと
### 他にもバージョンを変更しないといけない箇所があった
（あまり多くはないケースかもしれませんが）自社アプリにはsubtreeの形で共用リポジトリを組み込んでおり、そちらについてもPROJECTとTARGETSのバージョンを変更する必要がありました。
自分は完全に忘れていて、アーカイブするときに怒られるなどしました…。

### App Iconが無いと言われた
Bitriseが下記エラーでFailedしました。
>[Transporter Error Output]: ERROR ITMS-90704: “Missing App Icon. 
iOS Apps must include a 1024x1024px App Store I con in ONG format. Witchout providing the icon in the Asset Catalog or via iTunes Connect, apps cannot be submitted for App Review or Beta App Review. “

アイコンなんていじってないんだけどな〜と思いつつ、念のためAssetCatalogを見に行くと、たしかにStagingビルド用の1024x1024pxのAppIconが設定されていませんでした。
これまでは`[Transporter Warning Output]`で通っていたところなので、今回から`[Transporter Error Output]`で失敗するようになったのは、やっぱりサポートOSを11.0に変更したから…？:thinking:

（こんな感じで予想外のエラーが出たりするので、時間に余裕をもって対応することをおすすめします。）


# さいごに
以上の対応で無事リリースをし、大きな混乱もなくプロジェクトを終えることができました:tada:
致命的なミスはないかと思う（そう信じたい！）のですが、もし対応漏れなどあれば今後修正していくつもりです。

ここに書いた作業とは別に、会社の上の人の承認を得たり、ユーザーに事前告知しなければいけなかったりして、開発チームだけでなく全社を巻き込む必要があるのは少し大変ではあります。
が、うまく行けば会社にとっても、ユーザーにとっても、エンジニアにとってもメリットがあり、
実際、弊社ではAssetCatalogで色を一元管理できるようになりました（サポートOS11.0以上でないと使えない）！
[iOS 11Xcode 9新機能 Asset Catalogで色を定義できるようになりました ｜ Developers.IO](https://dev.classmethod.jp/smartphone/iphone/xcode-9-asset-catalogs-support-named-colors/)

ヤッタネ！
以上、この記事が、古いOSを切りたいと考えている方のお役に立てば幸いです:grin: