iOS 27 SDK 以降でビルドする App は、Info.plist に Apple が認める起動スクリーン設定を入れ、Release Archive 内の最終 .app まで確認してから再アップロードしてください。現在 iOS 26 SDK を使う本番経路は一時的に維持できますが、今週中に Xcode 27 の検証ブランチへ移し、正式公開当日の修正は避けるべきです。
対象判定と今週の作業
この記事は、既存の iPhone/iPad App を Xcode 27 で TestFlight または App Store に提出する独立開発者と小規模チーム向けです。SwiftUI、UIKit、クロスプラットフォーム生成プロジェクト、複数 Target を管理している場合も対象になります。
対象になるかは、最低デプロイメントターゲットではなく、提出物をビルドした SDK で判断します。Apple は iOS 27 SDK 以降でビルドした iOS/iPadOS App に、指定された起動スクリーン設定を求めています。条件と ITMS-90870 の扱いは、Apple TN3208 の起動スクリーン要件 と iOS/iPadOS 27 Release Notes を基準にします。
2026年8月27日時点で、Xcode 27 の正式版リリース日と、App Store が iOS 27 SDK ビルドを本番受付する具体的な日付は、今回確認した Apple 資料では確定していません。Xcode 26 の本番経路を残しつつ、Xcode 27 Beta のブランチで修正と提出検証を先に済ませます。
宣言方式の比較
起動スクリーンは、見た目を作る作業というより、サーバー検証に通る宣言と実リソースの整合性を作る作業です。Apple が案内する方式を、プロジェクトの状態に合わせて選びます。
| 構成 | 主な宣言 | 選択の基準 | 確認する実体 |
|---|---|---|---|
| 新規 SwiftUI または整理済み構成 | UILaunchScreen |
plist を自動生成する構成でも、最終 Target への反映を管理しやすい場合 | Archive 内の Info.plist と起動時の表示 |
| 既存 UIKit | UILaunchStoryboardName または対応する起動スクリーン設定 |
既存の LaunchScreen.storyboard を使い続ける場合 |
storyboard の Target Membership と Archive 内リソース |
| 複数の起動条件がある App | UILaunchScreen の設定を構成別に管理 |
iPhone/iPad、複数 Target で表示要件が異なる場合 | 各 App Target の Release Archive |
| クロスプラットフォーム生成 | 生成元設定と iOS App Target の両方 | ビルドスクリプトが plist を上書きする場合 | 生成後 plist と最終 .app |
UILaunchScreen のキーと値の扱いは、Apple の UILaunchScreen リファレンス に合わせます。storyboard 方式を採る場合も、ファイル名だけを入力して終わりにせず、指定ファイルが実際のビルド対象に含まれることを確認します。
空のキー、存在しないファイル名、古い起動画像の参照を追加して検査だけを通そうとするのは危険です。宣言、Build Settings、リソース、表示結果の4つが一致していなければ、提出後の起動表示や別の検証エラーにつながります。
Target と生成設定の確認
同じリポジトリでも、修正すべき場所は1か所とは限りません。App 本体、通知拡張、ウィジェット、社内配布用 Target が別の plist を使う場合、提出対象の App Target を先に特定します。
SwiftUI では「Info.plist は自動生成」にしている構成があります。この場合、プロジェクト内に編集対象の plist ファイルが見つからなくても異常ではありません。INFOPLIST_KEY_... の Build Setting、Target の起動スクリーン項目、生成スクリプトを順に確認します。Apple の Build Settings Reference を参照し、Debug だけでなく Archive が使う Release 設定を調べます。
UIKit の旧プロジェクトでは、LaunchScreen.storyboard の Target Membership、Build Phases の Copy Bundle Resources、plist の storyboard 名を確認します。ファイルをプロジェクトナビゲーターに置いただけでは、提出用 .app に入るとは限りません。
クロスプラットフォームプロジェクトでは、生成処理の後に plist が書き換えられることがあります。ローカルで追加したキーが CI のスクリプトで消える、あるいは別の Bundle ID の plist に入るケースです。複数 Build Configuration があるなら、提出 Scheme が参照する組み合わせを固定してから確認します。
Archive 産物の一致性
プロジェクト設定が正しく見えても、最終バイナリが正しいとは限りません。修正の成否は、ソースの plist ではなく、Release Archive 内の .app/Info.plist と起動スクリーン関連リソースで判定します。
次の順番で確認します。
- Xcode 27 の対象環境で、提出用 Scheme と
ReleaseConfiguration を選びます。 - 不要なキャッシュ削除や Xcode の再インストールを先に行わず、まず Archive を作成します。
- Organizer から
.xcarchiveを開き、Products/Applications/<App名>.app/Info.plistを取り出します。 plutil -pでUILaunchScreen、UILaunchStoryboardNameなどの宣言を確認します。.app内に storyboard、画像、関連するアセットが存在し、宣言名と一致するか調べます。- Archive の Bundle ID、バージョン、署名対象が提出予定の App と一致することを確認します。
- 脱色した設定画面、plist の検査結果、Archive 作成ログを保存し、TestFlight へ再アップロードします。
例えば、次のように Archive 内の plist を直接調べます。
plutil -p \
"PayloadSample.xcarchive/Products/Applications/Sample.app/Info.plist"
unzip -l "PayloadSample.xcarchive" | grep -E \
"LaunchScreen|Assets.car"
実際のプロジェクト名、Bundle ID、アカウント名、保存先は公開ログから削除します。提出確認では、Apple のApp のアップロード手順 と ビルドステータスの説明 も照合します。
初回表示とアップロード結果
サーバー検証を通過しても、ユーザー側の表示を省略してはいけません。Apple の起動スクリーン設定ガイドに沿って、古いインストール状態だけで判断しないようにします。
まずシミュレーターで、空白画面、古い画像の残留、画像の裁切、セーフエリアからのはみ出しを確認します。その後、既存 App を削除してから再インストールし、初回起動を確認します。シミュレーターは素早い差分確認に使えますが、正式公開前は実機でも同じ確認を残します。
起動が速くなった、または遅くなったという感覚だけを性能結果として記録してはいけません。今回の合格条件は速度ではなく、次の3点です。
- Archive 内の最終
Info.plistに有効な起動スクリーン設定がある。 - 宣言したリソースが同じ
.appに含まれている。 - TestFlight へのアップロード後、
ITMS-90870が再発しない。
Xcode 27 Beta 5 について Apple が確認しているのは、TestFlight へビルドをアップロードできることです。Beta のアップロード可否と、正式 App Store 公開の受付開始は別の判定です。App Store Connect の最新リリースノートを確認し、正式版へ切り替える日には受け入れ条件を再確認します。
仕上げ用チェックリスト
- [ ] 提出物を作った SDK が iOS 27 SDK 以降か確認した
- [ ] 最低デプロイメントターゲットと SDK の条件を混同していない
- [ ] Apple が認める
UILaunchScreenまたは有効な storyboard 方式を選んだ - [ ] 空キー、無効なファイル名、存在しないリソースを設定していない
- [ ] App 本体と提出対象の各 Target を区別した
- [ ] Archive に使う Scheme と Configuration を固定した
- [ ] Release Archive 内の最終
Info.plistを直接確認した - [ ] 宣言した storyboard やアセットが
.app内に存在する - [ ] 既存 App を削除して初回起動を確認した
- [ ] シミュレーターだけでなく実機でも表示を確認した
- [ ] TestFlight へ再アップロードし、
ITMS-90870の消失を記録した - [ ] Xcode 26 の本番経路へ戻す手順と、Xcode 27 の検証結果を残した
本番用の macOS が1台しかない場合は、Xcode 26 と Xcode 27 の切り替えで署名、Scheme、キャッシュの状態が変わらないよう注意します。別環境で同じ Archive と TestFlight 検証を行う必要があるなら、リモート Mac の利用環境を一時的な検証先として分離する方法もあります。Mac の購入とレンタルの判断材料が必要な場合は、Mac mini の導入条件と比較してください。
よくある確認事項
ITMS-90870 の修正範囲
このエラーは、最低デプロイメントバージョンが iOS 27 だから発生するのではありません。iOS 27 SDK 以降で作った提出物に、必要な起動スクリーン設定が最終 plist として入っているかを確認します。ソースファイルだけを直して Archive を作り直さない場合、同じエラーが残ります。
SwiftUI の自動生成 plist
自動生成は、設定が必ず全 Target に入ることを意味しません。Release 用の Build Setting、提出 Scheme、生成スクリプトの上書き順を確認し、Archive 内の .app/Info.plist を正とします。Debug で表示できても、提出用構成で欠落していれば検証は通りません。
UILaunchScreen と LaunchScreen.storyboard
新規構成では UILaunchScreen を使うと宣言を整理しやすくなります。既存 UIKit App は storyboard を無理に置き換えず、UILaunchStoryboardName と実ファイルの関係を確認します。どちらを選んでも、空の宣言や実在しないリソースでは修正になりません。
Archive の調査対象
調べるのはプロジェクト直下の plist ではなく、.xcarchive 内の提出対象 .app です。plutil でキーを読み、同じ .app のリソース一覧と照合します。複数 Target がある場合は、Bundle ID も一緒に記録すると別 App の確認を防げます。
Xcode 27 Beta の提出範囲
Xcode 27 Beta 5 から TestFlight へアップロードできることは Apple の資料で確認できます。ただし、Beta でアップロードできることは App Store の正式公開受付を保証しません。まず TestFlight で検証し、正式版の Xcode、App Store Connect の対応状況、社内の回退手順を確認してから本番へ進めます。
運用環境の選び方
現在のローカル環境だけで修正を続ける方法は、普段使う Mac で完結する反面、Xcode 26 と Xcode 27 の共存、署名設定の変更、CI 用スクリプトの差分を見落としやすい点が弱点です。1台の開発機を検証中に占有し、失敗した Archive の再現環境も残りません。
一方、既存の iOS 打包サーバーをそのまま使う方法は、macOS や Xcode の更新権限が制限され、古い plist 生成処理や固定された Scheme が新しい SDK と衝突しやすくなります。今回のように「プロジェクトでは直っているが、サーバーの Archive では欠落する」問題には、独立した検証環境のほうが切り分けやすいです。
本番の打包機をすぐ置き換える必要はありません。現在の構成を回退先として残し、Xcode 27 の Archive、最終 plist、初回起動、TestFlight を別の Mac で通す短期検証なら、MESHLAUNCH の Mac レンタルを使う選択肢があります。物理デバイス接続や長期にわたる固定負荷が必要な場合は自前の Mac が向きますが、今回の互換性確認のように期間を限定できる作業では、購入前にリモート環境で確かめるほうが合理的です。
今週は、Xcode 27 の検証ブランチで ITMS-90870 を再現し、Archive 内の Info.plist を確認してから TestFlight に提出してください。App Store の正式受付日が未確定な段階では、本番経路を廃止せず、合格した Archive と回退手順をそろえてから切り替えるのが安全です。