If you build your app against the iOS 27 SDK without adopting the UIScene lifecycle, it will not launch. And an app that does not launch never registers for push, so your notifications go silent with no crash report pointing at push as the cause. The failure looks like a delivery problem. It is actually a launch problem.
This one catches teams off guard because the two things feel unrelated. Push and app startup live in different corners of your codebase, and different corners of your head. iOS 27 ties them together. This guide covers what breaks, the exact chain that silences your notifications, who is in the blast radius, and the migration checklist to fix it. Pushwoosh is a customer engagement platform, and its iOS SDK already handles this transition, but the fix below applies whether you use us or not.
Part of our iOS 27 release guide. While the SDK work is open, it is also worth a moment to check your device reach.
What actually breaks
Apple announced at WWDC25 that the release after iOS 26 would require the UIScene lifecycle for any UIKit app built with the latest SDK. iOS 27 is that release. The requirement is now enforced.
The trigger matters, and most panicked threads get it wrong: enforcement happens when you build against the iOS 27 SDK in Xcode 27, not simply when a user runs your existing app on iOS 27. Your currently shipped build keeps working on updated phones. The break arrives with your next release compiled on the new SDK. That distinction buys you time, but only until your next submission.
Here is what does not change, because this is where the scare pieces overreach: the APNs flow itself is untouched. You still request authorization, still call registerForRemoteNotifications(), and still receive the device token in didRegisterForRemoteNotificationsWithDeviceToken. That callback stays in your AppDelegate, and on iOS 27 there is currently no scene-based equivalent to move it to. Push mechanics are fine. Startup is what Apple changed.
The chain that silences your push
When an app without a scene manifest is built against the iOS 27 SDK, the failure runs in order:
- UIKit asserts scene adoption at launch and finds no
UIApplicationSceneManifestin your Info.plist. - The app terminates before any AppDelegate method runs.
- Because
application(_:didFinishLaunchingWithOptions:)never executes,registerForRemoteNotifications()never fires. - No registration means
didRegisterForRemoteNotificationsWithDeviceTokennever gets called, so the app never receives an APNs token. - No token, no delivery. And since the app crashed at startup, your logs blame the launch, not the notification pipeline.
The reason this wastes so much debugging time is that the symptom and the cause sit far apart. You see missing deliveries and start auditing your push provider, your payloads, your certificates. The real fault is 3 layers upstream, in a manifest file that has nothing to do with notifications.
Who is in the blast radius
The requirement hits UIKit apps, but how it reaches you depends on your stack.
| Stack | Exposure |
|---|---|
| Native UIKit | Direct. If you own the AppDelegate lifecycle, you own the migration. |
| SwiftUI | Lower risk if you use the App protocol and WindowGroup, which are already scene-based. Apps still leaning on a UIApplicationDelegateAdaptor with custom window logic need a look. |
| Flutter | Framework auto-migrates apps with an unmodified AppDelegate on recent versions, but any custom native logic must be migrated by hand. |
| React Native | Depends on your native modules and any third-party SDK wrappers that hook the AppDelegate. |
App protocol and WindowGroup, which are already scene-based. Apps still leaning on a UIApplicationDelegateAdaptor with custom window logic need a look.The sharp edge for cross-platform teams is not the framework, it is the SDKs layered on top of it. Any push or analytics SDK that installs itself by wrapping your AppDelegate can block the scene migration until that vendor ships scene support. If a dependency owns your @main entry point, you are waiting on their release, not just your own. We’ve seen a migration stall for 2 weeks over exactly this, on one uncooperative dependency, while everything the team actually controlled was already done. Check your notification SDK’s scene compatibility before you assume the migration is a same-day job. If you are on our Flutter plugin, the known migration issues page is the first thing to read.
The migration checklist
The fix has not changed since scenes were introduced in 2019. What changed is that it stopped being optional.
- Add a scene manifest. Put a
UIApplicationSceneManifestin your Info.plist, or configure scenes through the UIApplicationDelegate and UISceneDelegate methods in code. - Create a SceneDelegate. If you do not have one, add it and make sure it actually compiles into your target. A SceneDelegate that exists in the project but was never added to the build sources is a common trap.
- Move window creation. Window ownership moves out of AppDelegate. Replace
UIWindow(frame:)withUIWindow(windowScene:)and host your root view from the scene. - Move UI lifecycle handling. Foreground, background, and active/inactive transitions move to UISceneDelegate. After migration, UIKit stops calling the UI-state methods on your AppDelegate, so anything left there quietly goes dead.
- Leave push registration where it is. Token registration and the token callbacks stay in AppDelegate. Do not move them chasing symmetry.
- Migrate URL and deep-link handling. Incoming URLs now arrive through scene methods. If push notifications open specific screens, this is the part that keeps your deep links working.
- Rebuild and verify token issuance. Build on the iOS 27 SDK, launch, and confirm the app receives an APNs token. If it does not, the iOS error troubleshooting guide is where to start. Verify on a real build before release, not after.
Keep the AppDelegate. This is the point teams miss when they read “AppDelegate is going away.” It is not going away. Its role narrows to process and app-level events while UI lifecycle moves to the scene. Push registration is an app-level concern, which is exactly why it stays put.
Why push alone is a fragile plan
Step back from the fix for a second. A single manifest key, in a file most of the team never opens, can take your entire push channel offline on the next release. That is a lot of fragility riding on one delivery method.
And this is on top of a ceiling push already has: opt-in. Even with a healthy prompt strategy, a large share of your users never grant push permission in the first place, so push reaches a fraction of your base on a good day. Platform breaks like this one just widen the gap between who you can reach and who you actually do.
The teams that ride out changes like this are the ones that do not depend on a single channel. When push is one delivery method next to email, SMS, and in-app, a launch-time regression on one platform dents your reach instead of erasing it. You buy yourself margin for exactly the kind of surprise Apple just shipped.
While the SDK work is open, it is a good moment to revisit what makes a notification worth sending.
Get your iOS 27 push setup checked with Pushwoosh
Pushwoosh SDK already supports the iOS 27 scene lifecycle, and its multichannel setup means a single-platform break never takes your whole notification strategy down with it. If you are mid-migration and something is not registering, the iOS SDK FAQ covers the common snags. And if you want a second pair of eyes on whether your push registration survives the move, we can walk your integration with you.
FAQ
didRegisterForRemoteNotificationsWithDeviceToken callback stay in your AppDelegate. On iOS 27 there is no scene-based equivalent to move them to, and trying to relocate them is a mistake. Only the UI lifecycle moves to the scene.
Related articles
View all