Swift

[swift]デバッグ時に接続先を変更する(URLがころころ変わる場合)

More than 3 years have passed since last update.

デバッグ時にはテスト環境に接続したいというケースが多々あります。今回は特にImmutable Infrastructure環境下でテスト環境のURLがころころ変わる場合に使えるテスト/本番環境の切り替え方法です。

単純なケース

コード上でDebug or Releaseを切り替えるだけの単純な場合。
プロジェクトの[Build Settings] -> [Other Swift Flags]のDebugの欄にだけ-D DBGオプションを付ける。

3.png

上記で設定したFlagをコードから参照して接続先を変更する。

class func getURL() -> String {
    #if DBG
        return "https://test.hogehoge.com"
    #else
        return "https://hogehoge.com"
    #endif
}

for Immutable Infrastructure

テスト環境がImmutable Infrastructureのケース。毎回環境を作り直すので、テストするたびにURLが変わっていたりする。例えばAWS Beanstalkだとhogehoge-ランダム文字列.elasticbeanstalk.comという感じのURLが割り当てられる。

URLが変わるたびにコード上のURLを書き換えると、git上に無駄なdiffが発生してしまうのでイケてない。これを解決する方法です。

まずはプロジェクトに接続先定義ファイルを作る。

2.png

定義ファイルにはこんな感じで接続先URLを書く。本当はjsonとかで書いたほうがそれっぽいけど不要なのでシンプルに。

test-server.txt
https://hogehoge-hugahuga.elasticbeanstalk.com

ファイルを作ったら、gitignoreでそのファイルをgitの管理対象外にする。

.gitignore
# 以下を追記
test-server.txt

これでどんな状態になっているかと言うと、XCodeのプロジェクト上ではtest-server.txtが存在するが、git環境には含まれていない状態になる。つまりこの環境をpush後、cloneした人の環境ではtest-server.txtが見つかりませんエラーが出る。

このままでは不親切なので、新しくcloneした人のためにスクリプトファイルを作ってgitの環境に入れて上げる。pod installとかもついでに実行してもらえばいい。

script/setup.sh
echo "https://hogehoge-hugahuga.elasticbeanstalk.com" > test-server.txt
pod install

gitignoreを書き換えているのでキャッシュを削除してpush。

git rm --cached .
git add -A
git commit -m "hogehoge"

開発者はcloneした後にセットアップスクリプトを実行する。

git clone [レポジトリ]
cd [レポジトリ]
./script/setup.sh

これで「URL定義ファイルがプロジェクトには含まれているがgitignoreされている状態」が作り出せる。あとはテスト環境のURLが変わるたびにserver-test.txtの内容を書き換えて上げればいい。gitへの影響は一切ない。

あ、ファイルの内容はこんなかんじで読み込んでます。

class func getURL() -> String {
    #if DBG
        if let debugFilePath = NSBundle.mainBundle().pathForResource("test-server", ofType: "txt") as String? {
            let fileHandle = NSFileHandle(forReadingAtPath: debugFilePath)
            let urlString = NSString(data: fileHandle!.readDataToEndOfFile(), encoding: NSUTF8StringEncoding) as String
            // delete space character
            return urlString.stringByReplacingOccurrencesOfString("\\s", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: nil)
        }
        else {
            return "https://hogehoge-hugahuga.elasticbeanstalk.com"
        }
    #else
        return "https://hogehoge.com"
    #endif
}

もっとスマートな方法があれば教えて下さい!