いまどきの Xcode プロジェクトは Info.plist ファイルを持たず、GENERATE_INFOPLIST_FILE: YES でビルド時に自動合成する。

この自動合成には落とし穴がある。Xcode が知らない名前のキーは、エラーも警告も出さずに黙って捨てられる。

ビルドは緑。アプリも動く。でも狙った機能だけが静かに消えている。実際に踏んだので記録する。

いまどきの Xcode プロジェクトは Info.plist ファイルを持たず、GENERATE_INFOPLIST_FILE: YES でビルド時に自動合成する。この自動合成には落とし穴がある。Xcode が知らない名前のキーは、エラーも警告も出さずに黙って捨てられる。

何が起きたか

日記アプリで「ファイル App からバックアップを取り出せる」を売りにしようとして、INFOPLIST_KEY_UIFileSharingEnabled を設定に書いた。ビルドは緑。ところが書き出された plist を dump したら UIFileSharingEnabled が存在しなかった。表示名 (CFBundleDisplayName) も同じく消えていた。

差別化の土台になる機能が、エラーゼロのまま入っていない。審査に出す直前に気づいた。

原因

INFOPLIST_KEY_<名前> 方式で plist に入るのは、Xcode 自身がテンプレートとして知っているキーだけ。知らない名前は無視される。どのキーを知っているかは、Xcode.app の中身を grep すると分かる:

grep -r "INFOPLIST_KEY_UIFileSharingEnabled" /Applications/Xcode.app/Contents/ 2>/dev/null

ヒットしなければそのキーは自動合成に乗らない。

直し方

自動合成をやめて明示 plist に戻した。

  • Info.plist を自分で書く (XcodeGen なら info: セクション)
  • GENERATE_INFOPLIST_FILE: NO
  • 版番号 (CFBundleShortVersionString / CFBundleVersion) は自動で入らなくなるので自分で書く

見張りの仕組み

同じ事故を二度と踏まないように、ビルド後に書き出された実物の plist を dump して必須キーを数えるスクリプトをリリース手順に入れた。わざとキーを消して赤くなることも確認した。

ビルドが緑でも、plist は実物を開いて数える。 設定ファイルに書いた、は証拠にならない。