お久しぶりです、社内で「ラブライブ、紅白出場おめでとうございます」と声をかけられる田村(@Utmrer)です。
私はiOS/Androidのクライアントサイドとサーバーサイドの実装をどちらも担当しているのですが、「ローカルサーバーで開発してるAPIを使いながら、アプリも開発する」ということをよくします。
その時に、アプリ側で通信するhostを本番環境のhostから自分のPCのローカルIP(192.168.1.XX, 10.0.1.YYなど)に変更してローカルサーバーとアプリを通信させていたのですが、IPv6サポートの流れからか、iOS9では出来なくなりました。*1
ローカルサーバーと通信出来ないとぶっつけ本番でデプロイする恐怖や、変更する度に開発環境にデプロイする煩わしさと戦わなければいけません。
それらを避けるためにiOS9でもローカルサーバーと通信する方法をご紹介します。
TL;DR
- IPアドレス指定での通信が出来なくなったのでローカルホスト名を使う
hostnameを使ってhostの設定を自動化すると楽ちん- ATSの設定もScriptで自動化出来る
Macのローカルホスト名を確認しよう
Macのローカルホスト名は
システム環境設定アプリから共有を選択すると表示されます。
このnozomi.localの部分があなたのローカルホスト名で、アプリが通信するhostです。
VagrantやMAMPで起動してるローカルサーバーのlocalhost:port(ex. localhost:8888)へ、Macと同じローカルネットワーク上のiPhoneのSafariからnozomi.local:8888という感じでアクセス出来るかと思います。
iPhoneからローカルサーバーと通信する
前項で確認した*.localのhostを本番環境のhostと置き換えればアプリとローカルサーバーが通信する準備が整ったのですが、App Transport Securityの影響でAllow Arbitrary Loads=YESにしてない場合は*.localのローカルサーバーとは通信は出来ない状態でしょう。
この設定も自動化して行きたいので環境別のhost設定からATSの設定まで自動化して行きましょう。
Info.plistにhostを持たせる
まずはこのようにInfo.plistに本番環境のhostを設定しておきましょう。
ServiceHostというKeyにexample.comという本番環境のhostが定義されています。
このServiceHostの値をビルド時に自動で設定します。サンプルコードではdiffを出したくないのでPreprocess Info.plist Fileを有効化しました。
Preprocess Info.plist Fileについて詳しくはこちら
ローカルホスト名はhostnameコマンドで取得できるのでBuild PhasesでScript追加してDebug Configurationの時だけInfo.plistを上書きするようにします。
Preprocessed-Info.plistを編集しているのでビルドの度にdiffが出てイライラすることもありません😊
そしてこのようにInfo.plistからhostを呼び出せばConfiguration毎に異なるhostへアクセス出来ます。
ATSの設定に*.localを含める
上記のようなATSの設定をしている場合、*.localはATS例外に含まれていないので通信できません。
*.localのhostもScriptでATS例外に追加しましょう!
上記のScriptをBuild Phasesに追加すると*.localもATS例外に追加出来ます。
Delete処理が入っているのはDerivedDataにPreprocessed-Info.plistのキャッシュが残っている場合があるからです。
ATSの環境別設定とPlistBuddyについてはこちらもご覧ください。 tech.connehito.com
今回ご紹介した内容を設定してあるサンプルプロジェクトも作ってみたのでもし良ければご覧ください。
特にBuild Phases辺りが肝です。
github.com
終わりに
以上で「iOS9でもローカルサーバーと通信する方法」&&「環境別の設定の切り替えを自動化」は終わりです。
「ナニソレイミワカンナイ」なところや、もっと簡単な方法があるよ〜って方は是非教えて下さい!ランチしながらPlistBuddyについて熱く語りましょう。