本番のアプリから「テスト環境に切り替えるボタン」を消した理由と、#if DEBUG では足りなかった話

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

「切り替えボタンは App Store 版に入れない」の文字と、Debug・TestFlight・Release の札

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 でビルドする時の設定のまとまり)を、使う人に合わせて分けました。

金色、青、紫の3本の鍵が白い背景に並んでいる写真
ビルドは3種類。ボタンを出すのは、そのうちの一部だけ(イメージ写真)
構成 使う人 既定の接続先 切り替えのボタン
Debug 開発中の Mac とシミュレーター テスト 出す
TestFlight オーナー本人だけ テスト 出す
Release スタッフ(App Store 版) 本番 入れない

TestFlight の構成を別に作ったのは、オーナーが、実機を Mac につながずに試したかったからです。最初は「開発用のビルドにだけ出す」と決めていましたが、それではオーナーが iPhone だけで本番とテストを行き来できません。そこで、TestFlight 用の構成を足し、そのビルドはオーナー本人にしか配らないことにしました。

3つのビルドの構成のうち、開発用と TestFlight 用には切り替えのボタンを出し、App Store 用にはボタンを入れず、本番にだけつながる
3つのビルドの構成と、ボタンを出す範囲
設定の画面の見本。Debug と TestFlight では接続先の切り替えが出て、画面の上に接続先が常に表示され、Release の App Store 版には切り替えが無い
ビルドの構成による設定の画面の違い(デモ)

#if DEBUG では、TestFlight のビルドを拾えなかった

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

TestFlight に上げるビルドは Debug ではないので、#if DEBUG で囲んだコードは入らない。ビルドの構成ごとに独自のフラグ ENABLE_ENV_SWITCH を付け、Debug と TestFlight にだけ付けて Release には付けない
独自のフラグで切り替えの部品を囲む

私たちは、XcodeGen(設定ファイルから Xcode のプロジェクトを作る道具)を使っているので、構成ごとの設定は project.yml に書いています。

YAMLproject.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 を付けない
Swift切り替えの部品の囲み方(仕組みが分かる短い見本)
var body: some View {
    Form {
        // …ふだんの設定の項目…
        #if ENABLE_ENV_SWITCH
        Section("接続先") {
            EnvironmentPicker()
        }
        #endif
    }
}

フラグで囲んだコードは、Release のビルドでは、アプリの中にそもそも入りません。画面で隠しているだけではないので、どんな操作をしても、App Store 版で切り替えることはできません。

本当に入っていないかを、毎回確かめる

フラグの付け忘れや、囲み忘れがあると、App Store 版にボタンが入ってしまいます。そこで、2つの方法で確かめています。

ノートパソコンのキーボードに虫めがねを当てている写真
入っていないことは、毎回、確かめる(イメージ写真)
  • UI テスト(画面を自動で操作するテスト)で、Release の構成で起動した時に、切り替えのボタンが出ないことを確かめる
  • 審査に出す前に、できあがったアプリの実行ファイルの中に、切り替えの部品だけが持つ文字列が無いことを、自動の検査で確かめる

2つ目の検査の作り方は、こちらに書いています。

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

まとめ

本番のアプリから「テスト環境に切り替えるボタン」を消した理由と、#if DEBUG では足りなかった話:要点のまとめ。スタッフがテスト側で入力する事故を防ぐため、App Store 版には接続先の切り替えのボタンを入れない
この記事の要点
  • スタッフがテスト側で入力する事故を防ぐため、App Store 版には接続先の切り替えのボタンを入れない
  • Debug・TestFlight・Release の3つの構成に分け、TestFlight のビルドはオーナー本人だけに配る
  • TestFlight のビルドは DEBUG ではないので、#if DEBUG ではなく、独自のフラグで切り替えの部品を囲む
  • ボタンが入っていないことを、UI テストとアーカイブの検査で毎回確かめる

この記事は、AI(Claude)の支援を受けて作成し、筆者が内容を確認しています。

  • SwiftUI
  • Xcode
  • ビルド構成
  • TestFlight
  • テスト環境
  • XcodeGen

関連する記事

この記事に関連するサービス・アプリ

ブログの一覧へ