← すべての記事

iOS 27の起動画面ルール——4つのキーがなければリジェクト

AppleのiOS 27リリースノートは、起動画面(launch screen)についてこれまでドキュメントに書かれていただけの一文を、提出時の関門へと格上げしました。「27.0のSDK以降でビルドされたiOSおよびiPadOSアプリには、起動画面の搭載が必須です。アプリのInfo.plistには、UILaunchStoryboardNameUILaunchStoryboardsUILaunchScreenUILaunchScreensのいずれかのキーが含まれていなければなりません。起動画面を含まないアプリは、App Storeが27.0のSDKでビルドされたアプリの受付を開始した時点でリジェクトされます」1

要件そのものは古くからあります。AppleのXcodeガイドは「すべてのiOSアプリは起動画面を提供しなければならない」という一文から始まります2。iOS 27で新たに登場したのは、それを無視した場合の代償のほうです。

要点

  • iOS 27.0以降のSDKでビルドしたアプリは、4つのInfo.plistキーのいずれかで起動画面を宣言する必要があり、宣言のないビルドはApp Storeがリジェクトします1
  • 関門は提出時であって、実行時ではありません。Appleの表現は「App Storeが27.0のSDKでビルドされたアプリの受付を開始した時点でリジェクトされる」ですから、失敗はユーザーの端末上ではなくApp Store Connectで起きます1
  • 対象として名指しされているのはiOSとiPadOSだけです。同じ注記の中で、AppleはtvOS、visionOS、Mac Catalystへは適用範囲を広げていません1。同じサイクルで到来するシーンライフサイクルの義務化は事情が異なり、その移行ガイドはiOS 27、iPadOS 27、Mac Catalyst 27、tvOS 27、visionOS 27を名指しで縛っています3
  • 4つのキーのうち2つは単一の起動画面用(UILaunchScreenはプロパティリスト内で組み立て、UILaunchStoryboardNameはストーリーボードのファイル名を指定します)、残る2つはURLスキームごとに出し分けるためのものです(UILaunchScreensUILaunchStoryboards)。3つは辞書型で、文字列型はUILaunchStoryboardNameだけです4567
  • 近年のXcodeテンプレートから作ったプロジェクトはすでに要件を満たしており、しかもファイルではなくビルド設定を通じて満たしています811。したがって、リポジトリを4つのキーでgrepして監査しても、答えにはまったくたどり着けません。

規則を正確に読む

Appleの一文には重みのある要素が3つあり、解説記事ではその3つとも曖昧にされがちです。

第一に、引き金になるのはビルドに使うSDKであって、ユーザーが動かしているOSではありません。iOS 26に対してコンパイルされたバイナリは、そのままストアに残ります。新しいSDKの何かを取り込もうとXcode 27でリビルドした瞬間、この要件も一緒についてきます。

第二に、強制のポイントはApp Storeでの受付です。Appleが書いたのは「リジェクトされる」であり、失敗の場所は起動時ではなく審査時になります。この点が、同じサイクルで登場するシーンライフサイクルの義務化との違いです。あちらでのAppleの表現はアプリが「起動に失敗する」でした1。一方はビルドが1本リジェクトされるだけで済み、もう一方はユーザーの手元で動かないアプリを生みます。

第三に、適用範囲はiOSとiPadOSです。Appleの注記はこの2つのプラットフォームを挙げてそこで止まっています。CatalystやtvOSのターゲットを保守しているなら、この要件は「類推によって拡張される」のではなく「言及がない」と読むべきです。27サイクルは他の領域では十分に強制を効かせており、5つのプラットフォームにまたがるシーンライフサイクルから、Image PlaygroundからのImageCreatorの削除にまで及びます。それでも起動画面の注記だけは、範囲が狭いままです。

4つのキーのどれを使うか

Appleは起動画面の作り方を2通り用意し、そこに単数・複数という2つの区分が掛け合わさります。だから4つのキーがあるわけです。

UILaunchScreenは、ストーリーボードファイルを一切介さずに、プロパティリスト上で直接起動時のインターフェースを設定します。Appleの説明では「ストーリーボードに依存しない形でアプリ起動中のユーザーインターフェースを設定する」ための手段であり、背景色、画像、ナビゲーションバー・タブバー・ツールバーの表示可否を子キーで指定できます4。最初の画面がただの背景色というアプリなら、空のUILaunchScreen辞書だけで要件を満たせます。Xcode自身のビルドシステムもこの道を通ります。「GENERATE_INFOPLIST_FILEが有効な場合」、INFOPLIST_KEY_UILaunchScreen_Generationは「Info.plistファイル内のUILaunchScreenキーの値を空の辞書に設定する」のです8

UILaunchStoryboardNameは、ストーリーボードを拡張子なしのファイル名で指し示します。LaunchScreen.storyboardというファイルなら、値は文字列LaunchScreenです5。iOS 9からある古参で、4つの中で唯一、辞書ではなく文字列を取ります5。デザインされた起動画面を持つアプリや、Xcodeがいまもストーリーボードのテンプレートに追加するLaunchScreen.storyboardを同梱しているプロジェクトは、このキーを使うことになります2

複数形のほうは特定のケースのために存在し、どちらも配列ではなく辞書です67UILaunchScreensは3つの子キーを持ちます。起動画面設定の配列であるUILaunchScreenDefinitions(各要素がUILaunchScreenIdentifierを持つ)、URLスキームから識別子への対応表であるUIURLToLaunchScreenAssociations、そしてフォールバックのUIDefaultLaunchScreenです6UILaunchStoryboardsも同じ構造で、UILaunchStoryboardDefinitionsUIURLToLaunchStoryboardAssociationsUIDefaultLaunchStoryboardが対応します7。いずれを使っても、myapp://composeから開いたアプリに、ホーム画面から開いた場合とは違う起動画面を出せます。ただしAppleははっきり、ほとんどのアプリには不要だと書いています。「起動画面が1つで足りるなら、代わりにUILaunchScreenを使ってください」6

実務上の判断は1つの問いに収束します。起動画面がストーリーボードならUILaunchStoryboardNameを、そうでなければUILaunchScreenを宣言する。複数形のキーに手を伸ばすのは、なぜ必要なのかをすでに理解している場合だけにしましょう。

実際に引っかかるアプリ

現行のXcodeテンプレートから作ったアプリは、誰も手を触れなくても通過します。だからこそこの規則は軽く見られやすく、同時に足をすくわれやすいのです。危険にさらされているアプリ群には、ある共通点があります。チームの誰も、最近Info.plistを手で書いていないということです。

最大の分類は、自動生成されたプロパティリストです。そして最大の生成主体はXcode自身です。Xcode 13でデフォルトが変わりました。いくつかのテンプレートから作ったプロジェクトは「entitlementsやInfo.plistといった設定ファイルを必要としなくなり」、代わりにターゲットのInfoタブとビルド設定エディタでフィールドを設定するようになったのです9。クロスプラットフォームのツールチェーン、ラッパーフレームワーク、パッケージ時にplistを合成するビルドスクリプトが第二の層を重ね、それらのテンプレートはUILaunchScreenより前の時代のものかもしれません。ビルドシステムが書き出すファイルを、誰もレビューしないのです。

第二の分類は、削ぎ落とされたplistです。起動用ストーリーボードは、サイズ最適化の過程で、Interface Builderからの移行の途中で、あるいはプロジェクト最後のストーリーボードを片付けたときに巻き添えで、消えていきます。それでもビルドは通り続けたので、削除は安全に見えたわけです。

第三は引き継ぎプロジェクトですが、この母集団は一般に語られるより狭いものです。UILaunchStoryboardNameはiOS 9で登場したので、2015年から持ち越されたプロジェクトはすでに要件を満たすキーを持っています5。4つのいずれも持たないアプリは、それより古い世代です。つまり、iOS 7.0で導入され、iOS 13.0でAppleが「UILaunchImagesは非推奨になりました。代わりにXcodeの起動用ストーリーボードを使ってください」という一言とともに非推奨にしたUILaunchImagesで、いまも起動画像を宣言しているものです10UILaunchImagesの配列はAppleが挙げた4つに入っていないため、これに頼り続けストーリーボード参照を採り入れなかったプロジェクトには、要件が受け付けるものが何もありません。10年分のXcodeアップグレードを経てもキーは追加されていないでしょう。ビルドが一度も失敗しなかったからです。

ビルドシステムが書き出すInfo.plistを監査する

まず、そのファイルが存在しないかもしれないと受け入れるところから始めます。GENERATE_INFOPLIST_FILEは自動生成を有効にし、INFOPLIST_KEY_*のビルド設定はそれぞれ1つのキーをビルド生成物のplistに書き込みます8。起動画面に関係する設定は2つ。空のUILaunchScreen辞書を書き込むINFOPLIST_KEY_UILaunchScreen_Generationと、ストーリーボード名を書き込むINFOPLIST_KEY_UILaunchStoryboardNameです8。どちらもテキスト検索で見つかるものを何ひとつ残しません。Xcodeの現行のiOS SwiftUI Appテンプレートは共有設定にINFOPLIST_KEY_UILaunchScreen_Generation = YESを含んでいるので、そこから作ったプロジェクトは、リポジトリのどこにも起動画面を示す文字列がないまま要件適合のターゲットを持つことになります11

ファイルシステムではなく、ビルドシステムに尋ねましょう。

xcodebuild -showBuildSettings \
  -project YourApp.xcodeproj -target YourApp \
  -configuration Release -sdk iphoneos 2>/dev/null \
  | grep -E "^ +(GENERATE_INFOPLIST_FILE|INFOPLIST_FILE|INFOPLIST_KEY_UILaunch)"

手元のマシンでAce Citizenshipプロジェクトに対して実行すると、3行が返ってきます11

    GENERATE_INFOPLIST_FILE = YES
    INFOPLIST_FILE = Ace-Citizenship-Info.plist
    INFOPLIST_KEY_UILaunchScreen_Generation = YES

3行目が適合性の答えのすべてであり、リポジトリのどのファイルにもこの記述はありません。出力はこの順序で読んでください。GENERATE_INFOPLIST_FILE = YESに加えてINFOPLIST_KEY_UILaunchの行がYESになっていれば、ビルドシステムが代わりにキーを書き込みます。AppleはすべてのINFOPLIST_KEY_*設定を生成が有効であることに紐づけているため、GENERATE_INFOPLIST_FILE = NOのもとでは同じ行も無効なものとして読むべきですし、値がNOならいずれにせよ何も書き込まれません8。生成がオフなら、起動画面のキーはINFOPLIST_FILEのパスにあるはずなので、そのファイルを開いて4つのいずれかを探します。生成がオンでファイルパスもある場合、ビルドシステムは両者をマージし、どちらの側で宣言されていても要件は満たされます8

2つのフラグにはどちらも理由があります。-configuration Releaseが効いてくるのは、App Store審査が見るのはRelease成果物だからです。-sdk iphoneosが必要なのは、マルチプラットフォームのターゲットではXcodeがこれらの設定をSDKごとに書き出すからです。RepsプロジェクトはINFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*][sdk=iphonesimulator*][sdk=appletv*]向けに1回ずつ、計3回宣言しており、Banana Listは前の2つを宣言しています。-sdk iphoneosを外すとどれも解決されず、キーは出力から消え、適合しているターゲットが無防備に見えてしまいます11

続いて、実際に提出する成果物を確認します。plutil -pの出力では、先頭の半角スペース2つがトップレベルのキーを示します。

plutil -p YourApp.xcarchive/Products/Applications/*.app/Info.plist \
  | grep -E '^  "UILaunch'

4月に配布用にビルドしたReturnのアーカイブに対して実行すると1行返り、起動画面のないバンドルに同じコマンドをかけると何も出力せずに終了コード1で終わります11

  "UILaunchScreen" => {

ここではPlistBuddyではなくplutilを使ってください。解決できないパスを渡すと、PlistBuddy -c "Print"は標準出力に「File Doesn’t Exist, Will Create:」と空のDict { }を書いて終了コード0で終わります。これを起動画面キーのgrepに流し込めば、誤りを示す唯一の行が飲み込まれ、キーが存在しない場合とまったく同じ空の出力が残ります。plutilは開けなかったファイル名を示し、終了コード1で終わります11

リポジトリの一斉走査にも役割は残っていますが、見た目より小さな役割です。読む価値のある、手で保守されているplistを見つけることです。

find . -name "Info.plist" \
  -not -path "*/build/*" -not -path "*/DerivedData/*" \
  -not -path "*/.build/*" -not -path "*/Carthage/*" -not -path "*/Pods/*" \
  -print0 | xargs -0 grep -L -E "UILaunchScreen|UILaunchStoryboard"

ここで出力されるパスはいずれも、ビルド設定と突き合わせて確認すべき候補であって、提出に失敗するターゲットではありません。Banana Listではこのコマンドはちょうど1行、./Banana List/Info.plistを返しますが、そのターゲットはそれでも起動画面を同梱しています。ビルド設定にINFOPLIST_KEY_UILaunchScreen_Generationがあり、アーカイブされたバンドルにはUILaunchScreenが含まれているからです。除外指定を外すと、同じコマンドはこのリポジトリで25行を返し、うち24行はbuild/配下のビルド成果物です。テストランナーのバンドル、XCTest.framework.xcresultのログ、watchアプリまで含まれます11

キーを手で追加する作業は、テキスト編集というよりいくつかの手順です。Appleの手順はこうです。ターゲットの設定でInfoタブを選び、Custom iOS Target PropertiesセクションでLaunch Screenキーを展開し、追加ボタンをクリックしてUILaunchScreenと入力してReturnキーを押します。続いてUILaunchScreenキーを選択し、もう一度追加をクリックして、必要な外観オプションの子キーを加えます2。Xcodeが生成するplistの場合は、ターゲットのビルド設定でINFOPLIST_KEY_UILaunchScreen_GenerationYESにすれば同じ結果になり、次回以降のビルドでも維持されます8。Xcode以外の何かが生成するplistなら、生成側のテンプレートに手を入れてください。出力ファイルをいくら編集しても、次のビルドで捨てられます。

この規則が言っていないこと

Appleは具体的な日付を公表していません。引き金は「App Storeが27.0のSDKでビルドされたアプリの受付を開始した時点」と表現されており、これは歴史的には秋のOSリリース前後に当たりますが、今回のサイクルについてAppleが文書で約束したわけではありません1。目にした具体的な日付は、すべて推測だと考えてください。

Appleはまた、既存のアプリが動かなくなるとも、TestFlightのビルドが影響を受けるとも、要件がiOSとiPadOSの外へ及ぶとも言っていません。この注記が扱っているのは新規ビルドの提出だけです。

修正そのものは小さいので、興味深い問いは「どう適合させるか」ではなく「すでに適合しているか」のほうです。手で保守しているプロジェクトなら、答えはほぼ確実にイエスです。plistが生成されるものなら、ストアが「ノー」と言い始める前に、ビルドシステムに尋ねて確かめておく価値があります。

FAQ

現行のXcodeテンプレートから作ったアプリは、すでに適合していますか?

ほぼ確実に適合しています。ただし証拠はファイルではなくビルド設定にあります。XcodeのiOS SwiftUI Appテンプレートは共有設定でINFOPLIST_KEY_UILaunchScreen_Generation = YESを設定しており、これがビルドシステムの生成するInfo.plistに空のUILaunchScreen辞書を書き込みます811。Release構成に対して-sdk iphoneos付きでxcodebuild -showBuildSettingsを実行し、INFOPLIST_KEY_UILaunchの行を探して確認してください。

リポジトリをUILaunchScreenでgrepしても何も見つからないのはなぜですか?

Xcode 13以降、いくつかのテンプレートから作ったプロジェクトはディスク上にInfo.plistを持たないからです。AppleはこれらのフィールドをターゲットのInfoタブとビルド設定エディタへ移しました9。起動画面はビルド時にINFOPLIST_KEY_UILaunchScreen_GenerationまたはINFOPLIST_KEY_UILaunchStoryboardNameから供給されます8。ソースファイルへのテキスト検索ではどちらの設定も見えませんし、見つかるInfo.plistはたいてい、ビルドシステムがマージする部分的な断片か、build/DerivedData/配下のビルド成果物です。

本当にどのキーも持っていない場合、何を追加すべきですか?

LaunchScreen.storyboardを同梱しているならUILaunchStoryboardName、そうでなければUILaunchScreenです45。単色の背景で起動するアプリなら空のUILaunchScreen辞書で十分で、これはXcodeがデフォルトで生成するものでもあります8。URLスキームごとに異なる起動画面を出すのでない限り、UILaunchScreensUILaunchStoryboardsは見送ってください。Apple自身の指針も「起動画面が1つで足りるなら、代わりにUILaunchScreenを使ってください」です6

この要件はTestFlightのビルドにも適用されますか?

Appleの注記には書かれていません。示されている結果は「App Storeが27.0のSDKでビルドされたアプリの受付を開始した時点」でのリジェクトという1点だけで、TestFlightでの配布はどこにも登場しません1。TestFlightのビルドもApp Store Connectとベータ審査を通るため、要件を満たさないビルドは審査に触れるあらゆる場所で落ちると考えるのが安全ですが、Appleがそう明記したわけではありません。この答えに依存する立場なら、沈黙をどちらに読むかを信じるのではなく、27.0のSDKでビルドしたものを実際にアップロードして試すべきです。

押さえておきたい点

iOS開発者向け: - ファイルをgrepする前にビルド設定へ問い合わせること。xcodebuild -showBuildSettings -configuration Release -sdk iphoneosを実行し、INFOPLIST_KEY_UILaunchScreen_GenerationまたはINFOPLIST_KEY_UILaunchStoryboardNameを探します8。リポジトリのテキスト検索ではどちらも見えません。 - 起動用ストーリーボードを同梱するならUILaunchStoryboardName、そうでなければUILaunchScreenを選びます。URLスキームごとに起動画面を出し分けるのでなければ、複数形のキーは見送りましょう。

クロスプラットフォームのツールチェーンで出荷しているチーム向け: - ソース管理下のファイルではなく、アーカイブされた.appバンドルをplutil -pで監査すること。審査が見るのは生成側の出力です。しかも不正なパスに対して、PlistBuddyは空の辞書を出して終了コード0で終わるのに対し、plutilははっきり失敗します。 - 生成後のファイルではなく、ビルド構成側のplistテンプレートに手を入れること。そうしないと次のビルドで修正が捨てられます。

リリース管理者向け: - 失敗が表面化するのは実行時ではなくApp Storeへの提出時なので、代償は本番障害ではなく審査1周分です。監査は最初の27.0 SDKでの提出より前に予定してください。リジェクトされてからでは遅すぎます。 - このチェックはシーンライフサイクルの移行と組み合わせて行いましょう。引き金は同じで、罰はあちらのほうが重いのです。


27サイクルは、提案を強制へ変える作業を続けています。ImageCreatorが動かなくなり、シーンライフサイクルは起動要件となり、起動画面は提出の関門になりました。同じSDKで届くその他の変更については、iOS 27のSwiftUI新機能をご覧ください。シリーズ全体のハブはAppleエコシステムシリーズです。

参考文献


  1. Apple, iOS & iPadOS 27 Release Notes, UIKitセクション。起動画面の要件の出典、New Features内(radar 168247372): “iOS and iPadOS apps built with the 27.0 SDK or later are required to include a launch screen. Your app’s Info.plist must contain one of the following keys: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen, or UILaunchScreens. Apps that don’t include a launch screen are rejected when the App Store begins accepting apps built with the 27.0 SDK.” ここで引用したシーンライフサイクルの文言も同じ出典で、Deprecations内に別途記載(radar 141837548): “Apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch.” この項目にプラットフォームの列挙はありません。2026年7月25日にAppleのドキュメントJSONと照合して確認。 

  2. Apple, Specifying your app’s launch screen, Xcodeドキュメント。「すべてのiOSアプリは起動画面を提供しなければならない」、サポートされる2つの方法(情報プロパティリストとユーザーインターフェースファイル)、およびここで引用したプロパティリストの手順の出典。ターゲットの設定でInfoタブを選び、Custom iOS Target PropertiesセクションでLaunch Screenキーを展開し、UILaunchScreenキーを追加してから、設定オプションの子キーを追加する。 

  3. Apple, Transitioning to the UIKit scene-based life cycle, Apple Developer Documentation。5プラットフォームの列挙の出典: “Beginning in iOS 27, iPadOS 27, Mac Catalyst 27, tvOS 27, and visionOS 27, apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch.” 

  4. Apple, UILaunchScreen, Information Property Listリファレンス。辞書型、iOSおよびiPadOS 14.0以降。「ストーリーボードに依存しない形でアプリ起動中のユーザーインターフェースを設定する」および子キー(UIColorNameUIImageNameUIImageRespectsSafeAreaInsetsUINavigationBarUITabBarUIToolbar)の出典。 

  5. Apple, UILaunchStoryboardName, Information Property Listリファレンス。文字列型、iOSおよびiPadOS 9.0以降(tvOS 9.0、watchOS 2.0も対象)。拡張子なしのファイル名という規則の出典。 

  6. Apple, UILaunchScreens, Information Property Listリファレンス。辞書型、iOSおよびiPadOS 14.0以降。子キーUILaunchScreenDefinitions(各要素がUILaunchScreenIdentifierを持つ設定の配列)、UIURLToLaunchScreenAssociationsUIDefaultLaunchScreen、および「If you need only one launch screen, use UILaunchScreen instead.」の出典。 

  7. Apple, UILaunchStoryboards, Information Property Listリファレンス。辞書型、iOSおよびiPadOS 9.0以降。子キーUILaunchStoryboardDefinitionsUIDefaultLaunchStoryboardUIURLToLaunchStoryboardAssociations、および単一の起動用ストーリーボードにはUILaunchStoryboardNameを使うようにという誘導の出典。 

  8. Apple, Build settings reference, Xcodeドキュメント。GENERATE_INFOPLIST_FILE(”Automatically generate an Info.plist file”)、INFOPLIST_FILE(ビルドシステムは “merges the values you specify in this file with other values it generates during the build process” であり、”When GENERATE_INFOPLIST_FILE is enabled, the build system also includes content from build settings in the merge process”)、INFOPLIST_KEY_UILaunchScreen_Generation(”sets the value of the UILaunchScreen key in the Info.plist file to an empty dictionary”)、INFOPLIST_KEY_UILaunchStoryboardNameの出典。 

  9. Apple, Xcode 13 Release Notes, Templates, Resolved Issues(radar 68254857): “Projects created from several templates no longer require configuration files such as entitlements and Info.plist files. Configure common fields in the target’s Info tab, and build settings in the project editor. These files are added to the project when additional fields are used.” 

  10. Apple, UILaunchImages, Information Property Listリファレンス。辞書の配列、iOS 7.0で導入、iOS 13.0で非推奨。「UILaunchImages has been deprecated; use Xcode launch storyboards instead.」の出典。 

  11. 著者による検証。macOS 26.5.2上のXcode 26.6(ビルド17F113)、2026年7月25日、出荷中の4つのiOSプロジェクト(Ace Citizenship、Banana List、Reps、Return)に対して実施。コマンド出力はそのまま再現しています。PlistBuddyの挙動は直接確認済み。/usr/libexec/PlistBuddy -c "Print" /nonexistent/Info.plistは「File Doesn’t Exist, Will Create:」に続けてDict { }を出力し終了コード0で終わる一方、同じパスに対するplutil -pは「The file “Info.plist” couldn’t be opened because there is no such file」と出力して終了コード1で終わります。テンプレートの設定値は、インストール済みXcodeツールチェーン内のiOS SwiftUI App.xctemplate/TemplateInfo.plistに由来します。 

関連記事

UIKitのシーン義務化:iOS 27で起動しなくなるもの

iOS 27 SDKでビルドしたアプリは、UIKitのシーンベースのライフサイクルを採用しなければ起動しません。タイムライン、移行手順、そしてエージェントスキルを解説します。

2 分で読める

canOpenURLが非推奨に:代わりに何を呼ぶべきか

Appleはわずか3文でcanOpenURLを非推奨とし、スキーム許可リストの上限を25エントリへ半減させました。代替手段と、そこでは実現できない唯一のチェックを整理します。

3 分で読める