The Powerful Code

スタートアップを技術で支える - iOS開発やその周辺技術など -

[iOS] iPhoneの実機デバッグで自動的にMacのローカルサーバーと通信させる

最近、複数のスタートアップで開発に携わっています。 サーバーと連携したiOSアプリの開発をしているのですが、サーバー(API)側も並行して開発が進んでいて、 「最新のソースコードを取得して、ローカルでサーバーを起動後、iOSアプリと通信させる」 といったことが必要になっています。

ここで問題になってくるのが、通信先の指定方法です。 Macのローカルサーバーへの通信先を http://localhost:3000 などとしていると、 Macで起動したシミュレーターでは正常に通信できても、外部にある実機では通信できません。

この記事では、問題が発生しない通信先の指定方法 を紹介します。

手順

指定方法の手順を説明します。方法はシンプルです。

1. ユーザー定義のビルド設定

Xcodeではユーザー定義のビルド設定を追加することができます。 通信先のホスト名を追加しましょう。

ビルド設定の追加

該当するターゲットの Build Settings のタブを表示して、 Xcodeのメーニューから Editor > Add Build Setting > Add User-Defined Setting を選択します。

ホスト名の設定

Configurationごとに設定が可能です。 Debug に対しては localhost を指定して、Release に対しては公開後のホスト名を指定する といったことが出来ます。 (応用して、Ad Hoc配布用にConfigurationを追加して通信先を振り分けることも可能です)

それぞれ適切な値を指定してください。

2. Info.plist の設定

次にプロジェクトの Info.plist から、指定したビルド設定を参照するようにします。

Info.plistのキー追加と設定

適当なキー(ここでは APIBaseURL としました)を追加し、定義したビルド設定を参照できるよう値を http://${API_HOST} などとしましょう。

ビルド設定自体に http:// という文字列を含むことも考えたのですが、 2重のスラッシュがビルド設定の値には指定できないらしく、 MLで回答されていた内容 を参考にしてみました。

3. デバッグ時のスクリプト実行

実機ビルド時に設定が上書きされるよう実行スクリプトを指定しておきます。 ローカルサーバーが起動しているMacBookなどのIPアドレスが、ビルド後の Info.plist に含まれるようにするのが目的です。

実行スクリプトの追加

該当するターゲットの Build Phases のタブを表示して、 Xcodeのメニューから Editor > Add Build Phase > Add Run Script Build Phase を選択します。

指定するスクリプトは以下の通りです。

1
2
3
4
5
6
7
8
if [[ "${CONFIGURATION}" == "Debug" && "${PLATFORM_NAME}" != *simulator* ]]; then
    plist="${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}"
    ip=$(ifconfig en0 | grep "inet[^6]" | cut -d" " -f2)

    url=$(/usr/libexec/PlistBuddy -c "Print :APIBaseURL" $plist)
    url=$(echo $url | sed "s|\(http://\)[^:/]*\(.*\)|\1$ip\2|")
    /usr/libexec/PlistBuddy -c "Set :APIBaseURL $url" $plist
fi

3行目のIPアドレスの取得については、環境によって変更が必要になる場合があります。 Qiitaの記事 が参考になるので、適宜書き換えてください。 (MacBookを無線環境で利用していれば問題ないと思います)

5~7行目は、PlistBuddy でURLを取得して、ホスト部分をIPアドレスで置き換え、再び PlistBuddy で値の上書きをしています。

4. Info.plist の値取得

あとはソースコードの通信部分で、Info.plist で設定された通信先を取得する実装になっていれば動作します。 以下のようにURLを取得しましょう。

1
2
NSString *baseURLString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"APIBaseURL"];
NSURL *baseURL = [NSURL URLWithString:baseURLString];

まとめ

実機デバッグ時にMacで起動しているローカルサーバーと通信させる方法を紹介しました。

紹介したのは、ビルド時に生成される Info.plist の通信先の設定をMacのIPアドレスで書き換えるという方法です。 スクリプトは自動で実行されるので、一度設定してしまえば後の開発を効率良く進めることができます。 また、書き換えの対象とする Info.plist はビルド時に生成されるファイルであるため、 ソースコードの変更が生じることがなく、誤ってGitなどに変更をコミットすることもありません。

他にも良い方法があったら是非教えてください。

おまけ

今回はiOSのネイティブアプリを前提にしていましたが、Webアプリ開発やサイト構築時にも、実機のSafariで動作確認をする際に似たような問題が発生すると思います。 そのような場合は、Ghostlab がおすすめです。

複数実機・ブラウザでの動作同期や、アクセス用のQRコード発行、ファイル変更の監視などができます。 おすすめなので興味があれば利用してみてください!

(このブログもGhostlabを利用して表示確認しました)

定期購読をおすすめします!

follow us in feedly

 RSSリーダーで購読する