iOS 27 SDKでアプリをビルドする際、UIScene lifecycleに対応していないと、アプリは起動すらしません。そして起動しないアプリはプッシュ登録を行わないため、通知は何のクラッシュレポートも残さないまま静かに止まります。症状は配信の問題に見えますが、実際は起動の問題です。

この落とし穴が厄介なのは、プッシュ通知とアプリ起動がコード上もチームの意識の上でも別々の領域だと思われがちだからです。iOS 27はこの2つを結びつけました。本記事では、何が壊れるのか、通知が沈黙するまでの正確な連鎖、影響を受ける対象、そして修正のための移行チェックリストを解説します。Pushwooshはカスタマーエンゲージメントプラットフォームであり、iOS SDKはすでにこの移行に対応済みですが、以下の対処法は弊社SDKの利用有無にかかわらず共通です。

📖

本記事はiOS 27リリース対応ガイドの一部です。SDK対応と合わせて、実際のデバイスリーチも確認しておく価値があります。

実際に何が壊れるのか

AppleはWWDC25で、iOS 26の次のリリースから、最新SDKでビルドされたすべてのUIKitアプリにUIScene lifecycleを必須とすることを発表しました。iOS 27がそのリリースです。この要件はすでに適用されています。

重要なのはトリガーの条件で、パニック気味の議論の多くはここを誤解しています。適用が始まるのは、Xcode 27でiOS 27 SDKに対してビルドしたときであり、既存アプリをユーザーがiOS 27上で起動しただけでは発動しません。現在公開中のビルドは、アップデート後の端末上でもそのまま動作します。問題が発生するのは、新SDKでビルドされた次回リリース以降です。この違いによって時間的猶予が生まれますが、それも次回の申請までです。

一方で変わらない点もあり、ここは煽り気味の記事がよく誇張する部分です。APNsのフロー自体は一切手が加えられていません。従来どおり認可をリクエストし、registerForRemoteNotifications()を呼び出し、didRegisterForRemoteNotificationsWithDeviceTokenデバイストークンを受け取ります。このコールバックは引き続きAppDelegateに残り、iOS 27時点ではこれに相当するscene側のAPIは存在しません。プッシュの仕組み自体は問題なく、Appleが変更したのは起動処理です。

プッシュ通知を沈黙させる障害の連鎖

scene manifestを持たないアプリをiOS 27 SDKでビルドすると、以下の順序で障害が発生します。

  1. UIKitは起動時にscene対応を要求しますが、Info.plistにUIApplicationSceneManifestが見つかりません。
  2. AppDelegateのいかなるメソッドも実行される前に、アプリは終了します。
  3. application(_:didFinishLaunchingWithOptions:)が一度も実行されないため、registerForRemoteNotifications()も呼ばれません。
  4. 登録が行われないためdidRegisterForRemoteNotificationsWithDeviceTokenも呼ばれず、アプリはAPNsトークンを一切受け取りません。
  5. トークンがなければ配信もありません。しかもアプリは起動時にクラッシュしているため、ログは起動処理を指し示し、通知パイプラインの問題だとは示しません。

デバッグに時間がかかる理由は、症状と原因が大きく離れているためです。配信が届かないという事実を見て、まずプッシュプロバイダー、ペイロード、証明書を疑ってしまいます。しかし実際の原因は3段階上流にある、通知とは無関係なマニフェストファイルにあります。

影響を受けるのは誰か

この要件はUIKitアプリを対象としますが、影響の受け方はスタック次第です。

スタック影響度
ネイティブUIKit直接影響します。AppDelegateのライフサイクルを管理しているなら、移行作業もそのチームの担当です。
SwiftUIすでにscene ベースのAppプロトコルとWindowGroupを使用していればリスクは低めです。カスタムウィンドウロジックを持つUIApplicationDelegateAdaptorにまだ依存しているアプリは要確認です。
Flutter最新バージョンでは未改変のAppDelegateを持つアプリは自動移行されますが、カスタムのネイティブロジックは手動での移行が必要です。
React Nativeネイティブモジュールや、AppDelegateにフックするサードパーティSDKラッパーの有無に依存します。
スタック
1 / 4
ネイティブUIKit
影響度
直接影響します。AppDelegateのライフサイクルを管理しているなら、移行作業もそのチームの担当です。
スタック
2 / 4
SwiftUI
影響度
すでにscene ベースのAppプロトコルとWindowGroupを使用していればリスクは低めです。カスタムウィンドウロジックを持つUIApplicationDelegateAdaptorにまだ依存しているアプリは要確認です。
スタック
3 / 4
Flutter
影響度
最新バージョンでは未改変のAppDelegateを持つアプリは自動移行されますが、カスタムのネイティブロジックは手動での移行が必要です。
スタック
4 / 4
React Native
影響度
ネイティブモジュールや、AppDelegateにフックするサードパーティSDKラッパーの有無に依存します。

クロスプラットフォームチームにとって本当に厄介なのはフレームワーク自体ではなく、その上に重なっているSDKです。AppDelegateをラップする形でインストールされるプッシュ系・解析系SDKは、そのベンダーがscene対応を提供するまでscene移行をブロックする可能性があります。@mainのエントリーポイントを依存先が握っている場合、待たされるのは自チームのリリースだけではありません。実際に、チームがコントロールできる部分はすべて完了していたにもかかわらず、非協力的な依存先1つのせいで移行が2週間止まった事例も見てきました。移行が1日で終わると考える前に、使用しているプッシュ通知SDKのscene対応状況を確認してください。弊社のFlutterプラグインをご利用の場合は、既知の移行問題ページを最初に確認することをおすすめします。

移行チェックリスト

この対処法自体は2019年にsceneが導入されて以来変わっていません。変わったのは、任意ではなくなったという点です。

  • scene manifestを追加する。 Info.plistにUIApplicationSceneManifestを追加するか、UIApplicationDelegateとUISceneDelegateのメソッドを使ってコード上でsceneを設定します。
  • SceneDelegateを作成する。 存在しない場合は追加し、ターゲットに実際にコンパイルされることを確認してください。プロジェクト内に存在するがビルドソースに追加されていないSceneDelegateはよくある落とし穴です。
  • ウィンドウ生成処理を移行する。 ウィンドウの所有権はAppDelegateから外れます。UIWindow(frame:)UIWindow(windowScene:)に置き換え、ルートビューをsceneからホストします。
  • UIライフサイクル処理を移行する。 フォアグラウンド、バックグラウンド、active/inactiveの遷移はUISceneDelegateに移ります。移行後、UIKitはAppDelegate上のUI状態メソッドを呼ばなくなるため、そこに残った処理は静かに機能しなくなります。
  • プッシュ登録処理はそのままにする。 トークン登録とそのコールバックはAppDelegateに残します。対称性を追求して移動させないでください。
  • URLとディープリンク処理を移行する。 受信URLはsceneのメソッド経由で届くようになります。プッシュ通知が特定の画面を開く仕様であれば、ここがディープリンクを維持する要です。
  • 再ビルドしてトークン発行を確認する。 iOS 27 SDKでビルドし、起動して、APNsトークンを受け取れるか確認します。受け取れない場合はiOSエラーのトラブルシューティングガイドから確認してください。リリース前に実機ビルドで検証し、リリース後にまわさないでください。

AppDelegateはそのまま残してください。「AppDelegateはなくなる」という記述を読んで誤解するチームが多いポイントですが、なくなりません。役割がプロセスレベル・アプリレベルのイベントに縮小し、UIライフサイクルがsceneに移るだけです。プッシュ登録はアプリレベルの関心事であり、だからこそそのまま残るのです。

プッシュ通知だけに依存するのが脆弱な理由

一歩引いて考えてみましょう。チームのほとんどが開くことのないマニフェストファイル内のたった1つのキーが、次回リリースでプッシュチャネル全体を止めてしまう可能性があります。単一の配信手段にこれほどの脆弱性を負わせているのです。

しかもこれは、プッシュ通知にもともとある上限に上乗せされる話です。それはopt-inです。よく練られた許諾リクエスト戦略があっても、多くのユーザーはそもそもプッシュ通知の許可を与えません。つまり良い日でもリーチできるのはユーザーベースの一部にすぎません。今回のようなプラットフォーム側の障害は、リーチできるはずの層と実際にリーチできている層の差をさらに広げます。

こうした変化を乗り切れるチームは、単一チャネルに依存していないチームです。プッシュ通知がメール、SMS、アプリ内メッセージと並ぶ配信手段の1つであれば、1つのプラットフォームで起きた起動時の不具合も、リーチ全体をゼロにするのではなく一部を削るだけで済みます。そうすることで、Appleが今回見せたような不意打ちに対する余裕を確保できます。

👉🏻

SDK対応が進んでいるこのタイミングで、そもそも送る価値のある通知とは何かを見直すのもよいでしょう。

PushwooshでiOS 27のプッシュ設定を確認する

Pushwoosh SDKはすでにiOS 27のscene lifecycleに対応しており、マルチチャネル構成のため単一プラットフォームの不具合が通知戦略全体を巻き込むことはありません。移行途中で登録がうまくいかない場合は、iOS SDK FAQによくあるつまずきがまとまっています。プッシュ登録がこの移行を乗り越えられているか、第三者の目でチェックしたい場合は、弊社と一緒にインテグレーションを確認することも可能です。

iOS 27のプッシュ設定を確認する
iOS 27の互換性を確認する

よくある質問

自動的に動かなくなることはありません。すでにApp Storeに公開されているアプリは、iOS 27端末上でもそのまま動作します。問題が起きるのは、scene lifecycleに対応しないままiOS 27 SDKで新バージョンをビルドしたときで、そのビルドは起動しません。現在公開中のビルドは次回の申請までは安全です。

Pushwoosh Team
Content Team / Pushwoosh
シェア

関連記事

すべて見る