はじめに
iPhoneのマイクだけでハウリングを起こしやすい帯域を見つけるアプリを作っています。
プロジェクトの管理に XcodeGen を使っています。
XcodeGen は、ターミナルで打って走らせるコマンドラインツールです。xcodegen generate を打つと、project.yml に書いた内容から Xcode のプロジェクトを作り直します。
私は、画面を閉じても録音が続くようにしました。UIBackgroundModes に audio を足して、実機に入れて、アプリは動きました。その後、xcodegen generate を走らせました。
UIBackgroundModes が消えていました。そのまま実機に入れていました。
3行で再現できます
空のプロジェクトで試せます。project.yml はこちらです。
name: T
targets:
T:
type: application
platform: iOS
deploymentTarget: "17.0"
sources: [Sources]
info:
path: Sources/Info.plist
properties:
CFBundleShortVersionString: 1.0
CFBundleVersion: "17"
順に打ちます。
xcodegen generate
/usr/libexec/PlistBuddy -c "Add :UIBackgroundModes array" -c "Add :UIBackgroundModes:0 string audio" Sources/Info.plist
plutil -p Sources/Info.plist | grep -i backgroundmodes
ここまでは入っています。
"UIBackgroundModes" => [
0 => "audio"
]
もう一度 xcodegen generate を打ってから、同じものを見ます。
(何も出ません)
消えます。エラーも警告も出ません。
info.path を書くと、そのファイルは毎回作り直される
info.path を書くと、XcodeGen はそのファイルを毎回作り直します。
中身は info.properties に書いたものと、XcodeGen が必ず入れる分だけです。
手で Info.plist に足したものは、次に生成し直したときに黙って消えます。
手で開いて編集したファイルなので残っている気がしますが、残りません。
手元で消えたもの3つ
日付だけ並べます。
| いつ | 消えたもの |
|---|---|
| 2026-07-23 | A/B比較用の音源4本と、画面の向きの宣言 |
| 2026-08-12 |
CFBundleShortVersionString と CFBundleVersion
|
| 2026-08-20 | UIBackgroundModes |
音源4本は info.properties ではなく sources: の話ですが、同じ形です。project.yml に書いていないものは、生成し直したときに存在しなくなります。
音源が消えたときは、アプリは落ちませんでした。読み込みに失敗して合成音に切り替わるだけです。
用意した4曲が、一度も誰にも届いていませんでした。
走っていないテストと、出てくる「TEST SUCCEEDED」
同じことが、テストでも起きます。
UITests/ に新しいテストファイルを足して、xcodegen generate はしていません。つまり project.pbxproj に登録されていない状態です。
テストを走らせると、こう出ます。
TEST SUCCEEDED
1件も走っていません。通ったのではなく、走るものが無かっただけです。
これに気づくまで、そのテストが守っていると思って作業していました。
UITests/ にファイルを足したら、必ず xcodegen generate を打ちます。
打たないと、テストしたつもりで通ってしまいます。
数字はクォートで囲みます
上の project.yml をもう一度見てください。
CFBundleShortVersionString: 1.0
CFBundleVersion: "17"
生成された Info.plist はこうなります。
"CFBundleShortVersionString" => 1
"CFBundleVersion" => "17"
1.0 が 1 になります。YAMLが数値として読むためで、バージョン番号は必ずクォートで囲みます。
project.yml だけ直しても戻ります
バージョンを上げるときは、project.yml と Sources/Info.plist の両方を上げます。
片方だけ上げても、次に xcodegen generate を打つと project.yml 側の値に戻ります。上げたはずの番号が、下がって見えます。
消えていないかを確かめるコマンド
見るのは、生成された Info.plist そのものです。
plutil -p Sources/Info.plist | grep -i backgroundmodes
前と比べたいときは、控えと並べます。
diff <(plutil -p <控え>/Sources/Info.plist | sort) <(plutil -p Sources/Info.plist | sort)
いちばん確かなのは、ビルドしたアプリの中を見ることです。
plutil -p <ビルド先>/Check12Rec.app/Info.plist | grep -i backgroundmodes
手元のファイルではなく、実際に端末へ入るものを見ます。
おわりに
このキーが消えてもビルドは通り、アプリも起動して、エラーも警告も出ません。画面を閉じたときに録音が止まるだけなので、実際に画面を閉じてみるまで分かりません。
project.yml に書いていないものは無いのと同じ、というのは読めば当たり前です。
それでも、手で足したファイルがそのまま残っている気がして、何度も同じ形で失いました。
生成されるファイルを手で編集しない。どうしても手で確かめたいなら、生成し直した後に見る。
出典
- XcodeGen
-
AVAudioSession.Category.record | Apple Developer Documentation …
UIBackgroundModesにaudioを足す根拠。原文に「To continue recording audio when your app transitions to the background (for example, when the screen locks), add theaudiovalue to the UIBackgroundModes key」とあります
再現の手順は、この記事を書くときに空のプロジェクトで実際に走らせて確かめています。
チェックワンツー(App Store・無料) … アナライザーは、払わなくても使えます。