iOS 27 Will Crash Apps That Still Skip UISceneDelegate
Apps that skip this migration will compile and install without issue but crash immediately on launch when built with the iOS 27 SDK. Deep links, push notifications, and OAuth flows will silently break if their callbacks aren't moved to SceneDelegate, making regression testing the bulk of the work.
Apple is turning a long-standing recommendation into a hard requirement. Apps built with the iOS 27 SDK must adopt the UISceneDelegate model for UI lifecycle management, or they will fail to start. The AppDelegate isn't going away—it still handles process-level events—but window management, deep links, and state restoration now belong exclusively to SceneDelegate. Projects missing a UIApplicationSceneManifest in Info.plist or lacking scene configuration in the AppDelegate are guaranteed to break. For Flutter apps, Flutter 3.41 automates much of the migration, but any custom AppDelegate code that registers plugins will need manual adjustment to move that logic into didInitializeImplicitFlutterEngine. UIKit developers face a three-step migration: declare the scene manifest, relocate lifecycle callbacks like applicationDidBecomeActive to their scene equivalents, and stop using UIApplication.shared.keyWindow in favor of UIWindowScene APIs. The real risk is silent failure—code compiles and installs fine, but deep links, Universal Links, and Handoff stop working because their entry points shifted to SceneDelegate without obvious errors.
Apple's enforcement pattern follows a familiar cadence: a feature introduced years earlier (iOS 13) is first optional, then warned against, and finally made mandatory with a hard crash—giving developers a long runway that many ignore until the last moment.
The distinction between AppDelegate and SceneDelegate reflects a genuine architectural split between process lifecycle and UI lifecycle, but the forced migration will surface years of accumulated technical debt in projects that never adopted the newer pattern.
Flutter's automatic migration in version 3.41 is a rare case of a cross-platform framework proactively absorbing a platform-level breaking change, though the escape hatch for custom native code means enterprise apps with heavy platform-channel usage still face manual work.