本番のアプリから「テスト環境に切り替えるボタン」を消した理由と、#if DEBUG では足りなかった話
本番とテストの接続先を切り替えるボタンを、開発用と TestFlight 用のビルドにだけ出し、App Store 版には入れないことにしました。TestFlight のビルドは Debug ではないので #if DEBUG では分けられず、SWIFT_ACTIVE_COMPILATION_CONDITIONS の独自フラグで切った方法です。

TestFlight に上げるビルドは Debug ではないので、#if DEBUG で囲んだコードは TestFlight には入りません。「開発用と TestFlight には出し、App Store 版には入れない」と分けたい時は、ビルドの構成ごとに独自のフラグ(SWIFT_ACTIVE_COMPILATION_CONDITIONS に付ける ENABLE_ENV_SWITCH)を付けて切るのが答えでした。
私たちの業務アプリ(Kaitori Base)には、つなぐサーバーを「本番」と「テスト」で切り替えるボタンがあります。開発の途中で、同じアプリから両方を試せるようにするためのものです。
このボタンは、開発用と TestFlight 用のビルドにだけ出し、App Store 版(スタッフが使う版)には入れないことにしました。スタッフが知らないうちにテスト側に切り替わり、そこで仕事の入力をしてしまう事故を防ぐためです。この記事は、その決まりと、ボタンを確実に消すための作り方の記録です。
App Store 版にテスト環境の切り替えがあると、何が起きるか
私たちは、本番とテストで、サーバーもデータベースも分けています。テスト側に入力したものは、本番には出てきません。

一番確実なのは、スタッフが使うアプリに、切り替えのボタンそのものを入れないことです。設定で隠すのではなく、App Store 版のアプリには、切り替えの部品のコードが入らないようにしました。
3つのビルドの構成と、ボタンを出す範囲
アプリのビルドの構成(Xcode でビルドする時の設定のまとまり)を、使う人に合わせて分けました。

| 構成 | 使う人 | 既定の接続先 | 切り替えのボタン |
|---|---|---|---|
| Debug | 開発中の Mac とシミュレーター | テスト | 出す |
| TestFlight | オーナー本人だけ | テスト | 出す |
| Release | スタッフ(App Store 版) | 本番 | 入れない |
TestFlight の構成を別に作ったのは、オーナーが、実機を Mac につながずに試したかったからです。最初は「開発用のビルドにだけ出す」と決めていましたが、それではオーナーが iPhone だけで本番とテストを行き来できません。そこで、TestFlight 用の構成を足し、そのビルドはオーナー本人にしか配らないことにしました。


#if DEBUG では、TestFlight のビルドを拾えなかった
Swift では、開発用のビルドにだけコードを入れる時に、よく #if DEBUG を使います。けれども、この方法では、TestFlight 用のビルドに切り替えのボタンを入れられませんでした。

私たちは、XcodeGen(設定ファイルから Xcode のプロジェクトを作る道具)を使っているので、構成ごとの設定は project.yml に書いています。
configs:
Debug:
API_ENVIRONMENT_NAME: stg
SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) ENABLE_ENV_SWITCH"
TestFlight:
API_ENVIRONMENT_NAME: stg
SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) ENABLE_ENV_SWITCH"
Release:
API_ENVIRONMENT_NAME: prod
# ENABLE_ENV_SWITCH を付けないvar body: some View {
Form {
// …ふだんの設定の項目…
#if ENABLE_ENV_SWITCH
Section("接続先") {
EnvironmentPicker()
}
#endif
}
}フラグで囲んだコードは、Release のビルドでは、アプリの中にそもそも入りません。画面で隠しているだけではないので、どんな操作をしても、App Store 版で切り替えることはできません。
本当に入っていないかを、毎回確かめる
フラグの付け忘れや、囲み忘れがあると、App Store 版にボタンが入ってしまいます。そこで、2つの方法で確かめています。

- UI テスト(画面を自動で操作するテスト)で、Release の構成で起動した時に、切り替えのボタンが出ないことを確かめる
- 審査に出す前に、できあがったアプリの実行ファイルの中に、切り替えの部品だけが持つ文字列が無いことを、自動の検査で確かめる
2つ目の検査の作り方は、こちらに書いています。
アプリ開発TestFlight のビルド番号が食い違う問題と、審査に出す前の7つの自動検査TestFlight のビルド番号(CFBundleVersion)を上げても git に残らず、App Store Connect の番号と食い違いました。番号の決め方とアーカイブを1つのコマンドにまとめ、App Store 版では接続先や切り替えの部品など7項目を自動で検査するようにした記録です。

まとめ

- スタッフがテスト側で入力する事故を防ぐため、App Store 版には接続先の切り替えのボタンを入れない
- Debug・TestFlight・Release の3つの構成に分け、TestFlight のビルドはオーナー本人だけに配る
- TestFlight のビルドは DEBUG ではないので、#if DEBUG ではなく、独自のフラグで切り替えの部品を囲む
- ボタンが入っていないことを、UI テストとアーカイブの検査で毎回確かめる
この記事は、AI(Claude)の支援を受けて作成し、筆者が内容を確認しています。

