From 6f9469d445d2a3c09cfc416df15921888769c4e4 Mon Sep 17 00:00:00 2001 From: Denis Sheikherev Date: Fri, 2 Oct 2026 15:28:09 +0700 Subject: [PATCH 1/2] fix(example): adopt the UIScene lifecycle so the app launches on iOS 27 From iOS 27 UIKit stops an app that has not adopted the UIScene lifecycle at launch (EXC_BREAKPOINT in _UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption). BareExample, from the React Native template, declared no scene and trapped before its JS ran on the iOS 27 simulators. Info.plist now declares one window scene, and SceneDelegate creates the window from it and starts React Native there. The factory stays in AppDelegate, which keeps the window too, for code that reads the app delegate's window. launch e2e passes on an iOS 27.0 simulator, where the app trapped before, and on iOS 26.5. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../bare/ios/BareExample/AppDelegate.swift | 32 ++++++++++++++++--- examples/bare/ios/BareExample/Info.plist | 17 ++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/examples/bare/ios/BareExample/AppDelegate.swift b/examples/bare/ios/BareExample/AppDelegate.swift index 80abc7d9..fe563e7f 100644 --- a/examples/bare/ios/BareExample/AppDelegate.swift +++ b/examples/bare/ios/BareExample/AppDelegate.swift @@ -5,11 +5,17 @@ import ReactAppDependencyProvider @main class AppDelegate: UIResponder, UIApplicationDelegate { + /// The scene's window, kept here too for code that still reads + /// `UIApplication.shared.delegate?.window`. var window: UIWindow? var reactNativeDelegate: ReactNativeDelegate? var reactNativeFactory: RCTReactNativeFactory? + /// React Native starts in the window `SceneDelegate` creates: since iOS 27 + /// an app that has not adopted the UIScene lifecycle is stopped at launch + /// (`_UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption`), and + /// `Info.plist` declares the one scene this app has. func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil @@ -23,15 +29,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate { reactNativeDelegate = delegate reactNativeFactory = factory - window = UIWindow(frame: UIScreen.main.bounds) + return true + } +} + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? - factory.startReactNative( + func scene( + _ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions + ) { + guard let windowScene = scene as? UIWindowScene, + let appDelegate = UIApplication.shared.delegate as? AppDelegate else { + return + } + let window = UIWindow(windowScene: windowScene) + self.window = window + appDelegate.window = window + + appDelegate.reactNativeFactory?.startReactNative( withModuleName: "BareExample", in: window, - launchOptions: launchOptions + launchOptions: nil ) - - return true } } diff --git a/examples/bare/ios/BareExample/Info.plist b/examples/bare/ios/BareExample/Info.plist index 56f52a92..fc18ce1e 100644 --- a/examples/bare/ios/BareExample/Info.plist +++ b/examples/bare/ios/BareExample/Info.plist @@ -37,6 +37,23 @@ RCTNewArchEnabled + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities From e0dd777629d990fa2f0561858fa6168ae83f05ac Mon Sep 17 00:00:00 2001 From: Denis Sheikherev Date: Fri, 2 Oct 2026 15:58:55 +0700 Subject: [PATCH 2/2] docs(example): say why SceneDelegate forwards no URLs to React Native SceneDelegate starts React Native with no launch options and implements no scene(_:openURLContexts:), so Linking sees no URL on iOS. That is deliberate: the app registers no URL scheme, and the e2e steers its iOS launches through launch arguments. The comment says so, and names RCTLinkingManager for an app that does open URLs. Co-Authored-By: Claude Opus 5.5 (1M context) --- examples/bare/ios/BareExample/AppDelegate.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/bare/ios/BareExample/AppDelegate.swift b/examples/bare/ios/BareExample/AppDelegate.swift index fe563e7f..aae32a3a 100644 --- a/examples/bare/ios/BareExample/AppDelegate.swift +++ b/examples/bare/ios/BareExample/AppDelegate.swift @@ -33,6 +33,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } +/// Creates the app's one window and starts React Native in it. +/// +/// It forwards no URLs to React Native: neither `connectionOptions.urlContexts` +/// at launch nor `scene(_:openURLContexts:)` later, so `Linking` sees none on +/// iOS. This app registers no URL scheme; the e2e steers its iOS launches +/// through launch arguments (`e2e/scenario.ts`). An app that opens URLs hands +/// both to `RCTLinkingManager`. class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow?