diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h index 4c2423772ba3..4a4eb3fa1756 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h @@ -19,8 +19,12 @@ NS_ASSUME_NONNULL_BEGIN /** - * @deprecated RCTAppDelegate is deprecated and will be removed in a future version of React Native. Use - `RCTReactNativeFactory` instead. + * @deprecated RCTAppDelegate is deprecated and will be removed in a future version of React Native. For new apps + * using the UIScene lifecycle, implement your own `SceneDelegate` with `RCTReactNativeFactory` (see integration + * docs). For AppDelegate-only apps, use `RCTReactNativeFactory` directly. + * + * Scene-based apps must keep `UIApplicationSupportsMultipleScenes` set to `false` in Info.plist. Define + * `RN_ALLOW_MULTIPLE_SCENES` on the app target to downgrade the unsupported-configuration crash to a warning. * * The RCTAppDelegate is an utility class that implements some base configurations for all the React Native apps. * It is not mandatory to use it, but it could simplify your AppDelegate code. @@ -55,19 +59,12 @@ NS_ASSUME_NONNULL_BEGIN * - (id)getModuleInstanceFromClass:(Class)moduleClass */ __attribute__((deprecated( - "RCTAppDelegate is deprecated and will be removed in a future version of React Native. Use `RCTReactNativeFactory` instead."))) + "RCTAppDelegate is deprecated and will be removed in a future version of React Native. For UIScene apps implement your own SceneDelegate with RCTReactNativeFactory; otherwise use RCTReactNativeFactory."))) @interface RCTAppDelegate : RCTDefaultReactNativeFactoryDelegate /// The window object, used to render the UViewControllers @property (nonatomic, strong, nonnull) UIWindow *window; -#if !defined(RCT_REMOVE_LEGACY_ARCH) -@property (nonatomic, nullable) RCTBridge *bridge - __attribute__((deprecated("The bridge is deprecated and will be removed when removing the legacy architecture."))); -@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter __attribute__(( - deprecated("The bridge adapter is deprecated and will be removed when removing the legacy architecture."))); -#endif - @property (nonatomic, strong, nullable) NSString *moduleName; @property (nonatomic, strong, nullable) NSDictionary *initialProps; @property (nonatomic, strong) RCTReactNativeFactory *reactNativeFactory; diff --git a/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm index e6f77aad652b..df121982cd3d 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.mm @@ -66,7 +66,7 @@ - (RCTColorSpace)defaultColorSpace - (NSURL *_Nullable)bundleURL { - [NSException raise:@"RCTAppDelegate::bundleURL not implemented" + [NSException raise:@"RCTReactNativeFactoryDelegate::bundleURL not implemented" format:@"Subclasses must implement a valid getBundleURL method"]; return nullptr; } diff --git a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h index 9665e6975eaf..617de978b185 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h +++ b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h @@ -58,6 +58,15 @@ typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable }; @interface RCTReactNativeFactory : NSObject +/** + * Bootstrap entrypoints: + * - **AppDelegate path**: `startReactNativeWithModuleName:inWindow:launchOptions:` — call from + * `application:didFinishLaunchingWithOptions:` or `RCTAppDelegate`. + * - **SceneDelegate path**: `startReactNativeWithModuleName:inWindow:connectionOptions:` — call from + * `scene:willConnectToSession:options:` in your app-owned `SceneDelegate` (subclass + * `RCTDefaultReactNativeFactoryDelegate` and conform to `UIWindowSceneDelegate`). + */ + - (instancetype)initWithDelegate:(id)delegate; - (instancetype)initWithDelegate:(id)delegate releaseLevel:(RCTReleaseLevel)releaseLevel; @@ -73,9 +82,33 @@ typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable }; initialProperties:(NSDictionary *_Nullable)initialProperties launchOptions:(NSDictionary *_Nullable)launchOptions; +/** + * SceneDelegate entrypoint to start a React Native instance with the specified module name, window, and connection + * options for linking and user activity information. Only the first item in `URLContexts` and `userActivities` is used. + * @param moduleName name of the JS module to load + * @param window the window to launch in + * @param connectionOptions the scene's connection options + */ +- (void)startReactNativeWithModuleName:(NSString *)moduleName + inWindow:(UIWindow *_Nullable)window + connectionOptions:(UISceneConnectionOptions *_Nullable)connectionOptions; + +/** + * SceneDelegate entrypoint to start a React Native instance with the specified module name, window, initial properties, + * and connection options. Only the first item in `URLContexts` and `userActivities` is used. + * @param moduleName name of the JS module to load + * @param window the window to launch in + * @param initialProperties the initial root properties + * @param connectionOptions the scene's connection options + */ +- (void)startReactNativeWithModuleName:(NSString *)moduleName + inWindow:(UIWindow *_Nullable)window + initialProperties:(NSDictionary *_Nullable)initialProperties + connectionOptions:(UISceneConnectionOptions *_Nullable)connectionOptions; + #if !defined(RCT_REMOVE_LEGACY_ARCH) -@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter __attribute__(( - deprecated("The bridgeAdapter is deprecated and will be removed when removing the legacy architecture."))); +@property (nonatomic, nullable) RCTBridge *bridge + __attribute__((deprecated("The bridge is deprecated and will be removed when removing the legacy architecture."))); #endif @property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory; diff --git a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm index 5282900de5fe..7f2a346bf849 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.mm @@ -9,7 +9,6 @@ #import #import #import -#import #import #import #import @@ -40,8 +39,36 @@ @interface RCTReactNativeFactory () < RCTHostDelegate, RCTJSRuntimeConfiguratorProtocol, RCTTurboModuleManagerDelegate> + @end +static NSDictionary *RCTConvertConnectionOptionsToLaunchOptions(UISceneConnectionOptions *connectionOptions) +{ + NSMutableDictionary *launchOptions = [NSMutableDictionary dictionary]; + + if (connectionOptions.URLContexts.count > 0) { + UIOpenURLContext *urlContext = connectionOptions.URLContexts.allObjects.firstObject; + + if (urlContext.URL != nil) { + launchOptions[UIApplicationLaunchOptionsURLKey] = urlContext.URL; + } + } + + if (connectionOptions.userActivities.count > 0) { + NSUserActivity *activity = connectionOptions.userActivities.allObjects.firstObject; + + if (activity != nil) { + NSMutableDictionary *userActivityDict = [NSMutableDictionary dictionary]; + userActivityDict[UIApplicationLaunchOptionsUserActivityTypeKey] = activity.activityType; + userActivityDict[@"UIApplicationLaunchOptionsUserActivityKey"] = activity; + + launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] = userActivityDict; + } + } + + return launchOptions; +} + @implementation RCTReactNativeFactory @synthesize bundleConfiguration = _bundleConfiguration; @@ -95,6 +122,29 @@ - (void)startReactNativeWithModuleName:(NSString *)moduleName [window makeKeyAndVisible]; } +#pragma mark - UIScene.ConnectionOptions + +- (void)startReactNativeWithModuleName:(NSString *)moduleName + inWindow:(UIWindow *_Nullable)window + connectionOptions:(UISceneConnectionOptions *_Nullable)connectionOptions +{ + [self startReactNativeWithModuleName:moduleName + inWindow:window + initialProperties:nil + launchOptions:RCTConvertConnectionOptionsToLaunchOptions(connectionOptions)]; +} + +- (void)startReactNativeWithModuleName:(NSString *)moduleName + inWindow:(UIWindow *_Nullable)window + initialProperties:(NSDictionary *_Nullable)initialProperties + connectionOptions:(UISceneConnectionOptions *_Nullable)connectionOptions +{ + [self startReactNativeWithModuleName:moduleName + inWindow:window + initialProperties:initialProperties + launchOptions:RCTConvertConnectionOptionsToLaunchOptions(connectionOptions)]; +} + #pragma mark - RCTUIConfiguratorProtocol - (RCTColorSpace)defaultColorSpace diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h index ddd3c09ebfbf..c78844c6c334 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h @@ -184,11 +184,6 @@ typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBloc */ @interface RCTRootViewFactory : NSObject -#if !defined(RCT_REMOVE_LEGACY_ARCH) -@property (nonatomic, strong, nullable) RCTBridge *bridge; -@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter; -#endif - @property (nonatomic, strong, nullable) RCTHost *reactHost; - (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration diff --git a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm index 8e12055adf38..4ca48c3b70ef 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.mm @@ -11,7 +11,6 @@ #import #import #import -#import "RCTAppDelegate.h" #import "RCTAppSetupUtils.h" #if RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h b/packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h index 9e76c5b54d82..3a97e122620e 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h +++ b/packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h @@ -20,8 +20,8 @@ NS_ASSUME_NONNULL_BEGIN /** * This method can be used to customize the rootView that is passed to React Native. - * A typical example is to override this method in the AppDelegate to change the background color. - * To achieve this, add in your `AppDelegate.mm`: + * Override on your `RCTReactNativeFactoryDelegate` (e.g. in AppDelegate, SceneDelegate, or + * `RCTAppDelegate` subclass). Example: * ``` * - (void)customizeRootView:(RCTRootView *)rootView * { diff --git a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec index c4322bc2c36b..035522d34dc8 100644 --- a/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec +++ b/packages/react-native/Libraries/AppDelegate/React-RCTAppDelegate.podspec @@ -59,6 +59,7 @@ Pod::Spec.new do |s| s.dependency "RCTTypeSafety" s.dependency "React-RCTNetwork" s.dependency "React-RCTImage" + s.dependency "React-RCTLinking" s.dependency "React-CoreModules" s.dependency "React-RCTFBReactNativeSpec" s.dependency "React-defaultsnativemodule" diff --git a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h index eff3b0c54614..9d9828e6a1bf 100644 --- a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h +++ b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h @@ -11,17 +11,42 @@ @interface RCTLinkingManager : RCTEventEmitter +/** + * Deep linking integration supports two iOS lifecycle paths: + * - **AppDelegate methods** (below): use when the app does not declare `UIApplicationSceneManifest` in Info.plist. + * - **SceneDelegate methods** (below): use when the app uses the UIScene lifecycle. Forward these from your + * app-owned `SceneDelegate`. + */ + +#pragma mark - AppDelegate methods + +/// Lifecycle method informing of a URL being opened with the app. +/// Invoke from AppDelegate for non-scene apps (no `UIApplicationSceneManifest` in Info.plist). +/// Note: this is an implementation using the iOS 9.0-26.0 API + (BOOL)application:(nonnull UIApplication *)app openURL:(nonnull NSURL *)URL options:(nonnull NSDictionary *)options; +/// Lifecycle method handling a URL being opened with the app. +/// Invoke from AppDelegate for non-scene apps. +/// Note: this is an implementation using the iOS 4.2-9.0 API + (BOOL)application:(nonnull UIApplication *)application openURL:(nonnull NSURL *)URL sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation; +/// Lifecycle method handling user activity being performed. +/// Invoke from AppDelegate for non-scene apps. + (BOOL)application:(nonnull UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> *_Nullable))restorationHandler; +#pragma mark - SceneDelegate methods + +/// Handles user activity for scene-based apps. Invoke from your SceneDelegate. ++ (void)scene:(nonnull UIScene *)scene continueUserActivity:(nonnull NSUserActivity *)userActivity; + +/// Handles URLs opened while the app is running for scene-based apps. Invoke from your SceneDelegate. ++ (void)scene:(nonnull UIScene *)scene openURLContexts:(nonnull NSSet *)URLContexts; + @end diff --git a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm index db689678d652..8191cc761817 100644 --- a/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -16,24 +16,38 @@ static NSString *const kOpenURLNotification = @"RCTOpenURLNotification"; -static void postNotificationWithURL(NSURL *URL, id sender) -{ - NSDictionary *payload = @{@"url" : URL.absoluteString}; - [[NSNotificationCenter defaultCenter] postNotificationName:kOpenURLNotification object:sender userInfo:payload]; -} - @interface RCTLinkingManager () + +/// Common logic for handling user activities originating from both AppDelegate- and SceneDelegate- lifecycle methods ++ (void)handleUserActivity:(NSUserActivity *)userActivity window:(UIWindow *)window; + +/// Common logic for handling user activities from AppDelegate-lifecycle methods. ++ (BOOL)handleAppDelegateURL:(NSURL *)URL app:(UIApplication *)app; + +/// Posts a URL notification that will be handled by the emitter to JS; this method is used to invoke instance methods +/// of RCTLinkingManager from class methods via NSNotificationCenter. +/// @param URL The URL to be emitted. ++ (void)postNotificationWithURL:(NSURL *)URL; + @end @implementation RCTLinkingManager RCT_EXPORT_MODULE() ++ (void)postNotificationWithURL:(NSURL *)URL +{ + NSDictionary *payload = @{@"url" : URL.absoluteString}; + [[NSNotificationCenter defaultCenter] postNotificationName:kOpenURLNotification object:nil userInfo:payload]; +} + - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } +#pragma mark - RCTEventEmitter methods + - (void)startObserving { [[NSNotificationCenter defaultCenter] addObserver:self @@ -52,33 +66,72 @@ - (void)stopObserving return @[ @"url" ]; } +#pragma mark - JS methods + + (BOOL)application:(UIApplication *)app openURL:(NSURL *)URL options:(NSDictionary *)options { - postNotificationWithURL(URL, self); - return YES; + return [self handleAppDelegateURL:URL app:app]; } -// Corresponding api deprecated in iOS 9 + (BOOL)application:(UIApplication *)application openURL:(NSURL *)URL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - postNotificationWithURL(URL, self); - return YES; + return [self handleAppDelegateURL:URL app:application]; } + (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> *_Nullable))restorationHandler +{ + if (RCTIsSceneDelegateApp()) { + return NO; + } + + [RCTLinkingManager handleUserActivity:userActivity window:RCTKeyWindow()]; + return YES; +} + +#pragma mark - SceneDelegate methods + ++ (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity +{ + [RCTLinkingManager handleUserActivity:userActivity window:RCTKeyWindow()]; +} + ++ (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts +{ + if (URLContexts.count == 0) { + return; + } + + NSURL *URL = URLContexts.allObjects.firstObject.URL; + if (URL == nil) { + return; + } + [RCTLinkingManager postNotificationWithURL:URL]; +} + +#pragma mark - Common logic methods + ++ (void)handleUserActivity:(NSUserActivity *)userActivity window:(UIWindow *)window { // This can be nullish when launching an App Clip. if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && userActivity.webpageURL != nil) { - NSDictionary *payload = @{@"url" : userActivity.webpageURL.absoluteString}; - [[NSNotificationCenter defaultCenter] postNotificationName:kOpenURLNotification object:self userInfo:payload]; + [RCTLinkingManager postNotificationWithURL:userActivity.webpageURL]; } +} + ++ (BOOL)handleAppDelegateURL:(NSURL *)URL app:(UIApplication *)app +{ + if (RCTIsSceneDelegateApp()) { + return NO; + } + + [RCTLinkingManager postNotificationWithURL:URL]; return YES; } diff --git a/packages/react-native/React/Base/RCTJavaScriptLoader.mm b/packages/react-native/React/Base/RCTJavaScriptLoader.mm index 5f7d6e9b5efe..f584e30c22e6 100755 --- a/packages/react-native/React/Base/RCTJavaScriptLoader.mm +++ b/packages/react-native/React/Base/RCTJavaScriptLoader.mm @@ -247,7 +247,7 @@ static void attemptAsynchronousLoadOfBundleAtURL( [@"Could not connect to development server.\n\n" "Ensure the following:\n" "- Node server is running and available on the same network - run 'npm start' from react-native root\n" - "- Node server URL is correctly set in AppDelegate\n" + "- Node server URL is correctly set in your AppDelegate or SceneDelegate factory delegate\n" "- WiFi is enabled and connected to the same network as the Node Server\n\n" "URL: " stringByAppendingString:scriptURL.absoluteString], NSLocalizedFailureReasonErrorKey : error.localizedDescription, diff --git a/packages/react-native/React/Base/RCTUtils.h b/packages/react-native/React/Base/RCTUtils.h index be9574c9167d..abc8a851a5d8 100644 --- a/packages/react-native/React/Base/RCTUtils.h +++ b/packages/react-native/React/Base/RCTUtils.h @@ -93,6 +93,9 @@ RCT_EXTERN UIApplication *__nullable RCTSharedApplication(void); // or view controller RCT_EXTERN UIWindow *__nullable RCTKeyWindow(void); +// Is this app a SceneDelegate app? +RCT_EXTERN BOOL RCTIsSceneDelegateApp(void); + // Returns the presented view controller, useful if you need // e.g. to present a modal view controller or alert over it RCT_EXTERN UIViewController *__nullable RCTPresentedViewController(void); diff --git a/packages/react-native/React/Base/RCTUtils.mm b/packages/react-native/React/Base/RCTUtils.mm index cd21d982b60f..360f80ad6ee0 100644 --- a/packages/react-native/React/Base/RCTUtils.mm +++ b/packages/react-native/React/Base/RCTUtils.mm @@ -390,7 +390,11 @@ CGSize RCTScreenSize(void) if (CGSizeEqualToSize(size, CGSizeZero)) { RCTUnsafeExecuteOnMainQueueSync(^{ - CGSize screenSize = [UIScreen mainScreen].bounds.size; + UIScreen *screen = RCTKeyWindow().screen; + if (screen == nil) { + screen = UIScreen.screens.firstObject; + } + CGSize screenSize = screen.bounds.size; size = CGSizeMake(MIN(screenSize.width, screenSize.height), MAX(screenSize.width, screenSize.height)); cachedSize.store(size, std::memory_order_relaxed); }); @@ -638,11 +642,46 @@ BOOL RCTRunningInAppExtension(void) // Calling keyWindow on a UIScene which is not a UIWindowScene can cause a crash UIWindowScene *windowScene = (UIWindowScene *)sceneToUse; if (@available(iOS 15.0, tvOS 15.0, *)) { - return windowScene.keyWindow; + UIWindow *keyWindow = windowScene.keyWindow; + if (keyWindow != nil) { + return keyWindow; + } + } + UIWindow *window = nil; + for (window in windowScene.windows) { + if (window.isKeyWindow) { + return window; + } } } - return nil; + // Fallback for apps still on the legacy UIApplicationDelegate lifecycle (no + // SceneDelegate / no UIApplicationSceneManifest, or scene migration disabled). + // Their key window is created and owned by the app delegate and is not attached + // to a foreground UIWindowScene, so the scene-based lookup above finds nothing. + // This diff moved several call sites from `delegate.window` to RCTKeyWindow(), + // so without this fallback RCTKeyWindow() returns nil for those apps and RN's + // window/screen/dimension resolution (RCTViewportSize, RCTDeviceInfo, + // RCTPresentedViewController, …) breaks — the RN UI never renders. + return RCTSharedApplication().delegate.window; +} + +BOOL RCTIsSceneDelegateApp(void) +{ + if (@available(iOS 13.0, *)) { + NSDictionary *sceneManifest = [[NSBundle mainBundle] infoDictionary][@"UIApplicationSceneManifest"]; + + if (sceneManifest != nil) { + NSDictionary *sceneConfigurations = sceneManifest[@"UIApplicationSceneConfigurations"]; + if (sceneConfigurations != nil && sceneConfigurations.count > 0) { + return YES; + } + } + + return NO; + } + + return NO; } #if !TARGET_OS_TV diff --git a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm index 1ae546d91fe7..94a22481935e 100644 --- a/packages/react-native/React/CoreModules/RCTDevLoadingView.mm +++ b/packages/react-native/React/CoreModules/RCTDevLoadingView.mm @@ -200,6 +200,9 @@ - (void)showMessage:(NSString *)message } else { self->_window = [[UIWindow alloc] init]; } + + self->_window.frame = self->_window.windowScene.coordinateSpace.bounds; + #if !TARGET_OS_TV self->_window.windowLevel = UIWindowLevelStatusBar + 1; #endif @@ -240,7 +243,6 @@ - (void)showMessage:(NSString *)message [NSLayoutConstraint activateConstraints:constraints]; [self->_window layoutIfNeeded]; - self->_window.frame = CGRectMake(0, 0, mainWindow.frame.size.width, self->_container.frame.size.height); }); } @@ -268,15 +270,15 @@ - (void)hide const NSTimeInterval MIN_PRESENTED_TIME = 0.6; NSTimeInterval presentedTime = [[NSDate date] timeIntervalSinceDate:self->_showDate]; NSTimeInterval delay = MAX(0, MIN_PRESENTED_TIME - presentedTime); - CGRect windowFrame = self->_window.frame; + CGFloat height = self->_container.bounds.size.height; [UIView animateWithDuration:0.25 delay:delay options:0 animations:^{ - self->_window.frame = CGRectOffset(windowFrame, 0, -windowFrame.size.height); + self->_container.transform = CGAffineTransformMakeTranslation(0, -height); } completion:^(__unused BOOL finished) { - self->_window.frame = windowFrame; + self->_container.transform = CGAffineTransformIdentity; self->_window.hidden = YES; self->_window = nil; self->_container = nil; diff --git a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm index 40b0adf93482..1761214fc3bd 100644 --- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm +++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm @@ -126,6 +126,12 @@ - (void)initialize name:RCTBridgeWillInvalidateModulesNotification object:nil]; + [self invalidateCachedConstants]; +} + +- (void)invalidateCachedConstants +{ + RCTAssertMainQueue(); _constants = @{ @"Dimensions" : [self _exportedDimensions], // Note: @@ -186,24 +192,27 @@ static BOOL RCTIsIPhoneNotched() static NSDictionary *RCTExportedDimensions(CGFloat fontScale) { RCTAssertMainQueue(); - UIScreen *mainScreen = UIScreen.mainScreen; - CGSize screenSize = mainScreen.bounds.size; - UIView *mainWindow = RCTKeyWindow(); + UIWindow *mainWindow = RCTKeyWindow(); + UIScreen *screen = mainWindow.screen; + if (screen == nil) { + screen = UIScreen.screens.firstObject; + } + CGSize screenSize = screen.bounds.size; // We fallback to screen size if a key window is not found. - CGSize windowSize = mainWindow ? mainWindow.bounds.size : screenSize; + CGSize windowSize = mainWindow != nil ? mainWindow.bounds.size : screenSize; NSDictionary *dimsWindow = @{ @"width" : @(windowSize.width), @"height" : @(windowSize.height), - @"scale" : @(mainScreen.scale), + @"scale" : @(screen.scale), @"fontScale" : @(fontScale) }; NSDictionary *dimsScreen = @{ @"width" : @(screenSize.width), @"height" : @(screenSize.height), - @"scale" : @(mainScreen.scale), + @"scale" : @(screen.scale), @"fontScale" : @(fontScale) }; return @{@"window" : dimsWindow, @"screen" : dimsScreen}; @@ -224,7 +233,7 @@ - (NSDictionary *)_exportedDimensions RCTAssert(_moduleRegistry, @"Failed to get exported dimensions: RCTModuleRegistry is nil"); RCTAccessibilityManager *accessibilityManager = (RCTAccessibilityManager *)[_moduleRegistry moduleForName:"AccessibilityManager"]; - // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases. + // TODO(T225745315): For some reason, accessibilityManager is nil in some cases. // We default the fontScale to 1.0 in this case. This should be okay: if we assume // that accessibilityManager will eventually become available, js will eventually // be updated with the correct fontScale. @@ -244,20 +253,24 @@ - (NSDictionary *)_exportedDimensions - (void)didReceiveNewContentSizeMultiplier { - __weak __typeof(self) weakSelf = self; + [self invalidateCachedConstants]; + NSDictionary *nextInterfaceDimensions = _constants[@"Dimensions"]; + RCTModuleRegistry *moduleRegistry = _moduleRegistry; RCTExecuteOnMainQueue(^{ // Report the event across the bridge. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [[moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"didUpdateDimensions" - body:[weakSelf _exportedDimensions]]; + body:nextInterfaceDimensions]; #pragma clang diagnostic pop }); } - (void)interfaceOrientationDidChange { + [self invalidateCachedConstants]; + #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST UIWindow *window = RCTKeyWindow(); UIInterfaceOrientation nextOrientation = window.windowScene.interfaceOrientation; @@ -279,8 +292,9 @@ - (void)interfaceOrientationDidChange if ((isOrientationChanging || isResizingOrChangingToFullscreen) && RCTIsAppActive()) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSDictionary *nextInterfaceDimensions = _constants[@"Dimensions"]; [[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"didUpdateDimensions" - body:[self _exportedDimensions]]; + body:nextInterfaceDimensions]; // We only want to track the current _currentInterfaceOrientation and _isFullscreen only // when it happens and only when it is published. _currentInterfaceOrientation = nextOrientation; @@ -300,7 +314,8 @@ - (void)interfaceFrameDidChange - (void)_interfaceFrameDidChange { - NSDictionary *nextInterfaceDimensions = [self _exportedDimensions]; + [self invalidateCachedConstants]; + NSDictionary *nextInterfaceDimensions = _constants[@"Dimensions"]; // update and publish the even only when the app is in active state if (!([nextInterfaceDimensions isEqual:_currentInterfaceDimensions]) && RCTIsAppActive()) { diff --git a/packages/react-native/React/CoreModules/RCTLogBoxView.mm b/packages/react-native/React/CoreModules/RCTLogBoxView.mm index ca9d39d9e5fa..fe3840816c02 100644 --- a/packages/react-native/React/CoreModules/RCTLogBoxView.mm +++ b/packages/react-native/React/CoreModules/RCTLogBoxView.mm @@ -53,10 +53,6 @@ - (void)layoutSubviews [super layoutSubviews]; } -- (void)dealloc -{ -} - - (void)show { [self becomeFirstResponder]; diff --git a/packages/react-native/React/Profiler/RCTProfile.m b/packages/react-native/React/Profiler/RCTProfile.m index 32ed153edbf4..47e2c86ac6f3 100644 --- a/packages/react-native/React/Profiler/RCTProfile.m +++ b/packages/react-native/React/Profiler/RCTProfile.m @@ -407,9 +407,7 @@ + (void)toggle:(UIButton *)target }; RCTProfileControlsWindow.hidden = YES; dispatch_async(dispatch_get_main_queue(), ^{ - [[[[RCTSharedApplication() delegate] window] rootViewController] presentViewController:activityViewController - animated:YES - completion:nil]; + [[RCTKeyWindow() rootViewController] presentViewController:activityViewController animated:YES completion:nil]; }); #else RCTProfileControlsWindow.hidden = NO; diff --git a/packages/rn-tester/RCTTest/RCTTestRunner.m b/packages/rn-tester/RCTTest/RCTTestRunner.m index f95fb9874507..0f85e8674caa 100644 --- a/packages/rn-tester/RCTTest/RCTTestRunner.m +++ b/packages/rn-tester/RCTTest/RCTTestRunner.m @@ -183,7 +183,7 @@ - (void)runTest:(SEL)test } batchedBridge = [bridge batchedBridge]; - UIViewController *vc = RCTSharedApplication().delegate.window.rootViewController; + UIViewController *vc = RCTKeyWindow().rootViewController; vc.view = [UIView new]; RCTTestModule *testModule = [bridge moduleForClass:[RCTTestModule class]]; diff --git a/packages/rn-tester/RNTester/AppDelegate.h b/packages/rn-tester/RNTester/AppDelegate.h index a4a5daca71ea..05d66d95f5c6 100644 --- a/packages/rn-tester/RNTester/AppDelegate.h +++ b/packages/rn-tester/RNTester/AppDelegate.h @@ -5,22 +5,8 @@ * LICENSE file in the root directory of this source tree. */ -// ZERO-I: bare angle includes have no framework spelling, so the SPM zero-I -// build uses the form. rn-tester also builds via CocoaPods, where -// only the bare form resolves — hence the dual. Single-mode consumers write -// just the form matching their setup. -#if __has_include() -#import -#import -#else -#import -#import -#endif #import -@interface AppDelegate : RCTDefaultReactNativeFactoryDelegate - -@property (nonatomic, strong, nonnull) UIWindow *window; -@property (nonatomic, strong, nonnull) RCTReactNativeFactory *reactNativeFactory; +@interface AppDelegate : UIResponder @end diff --git a/packages/rn-tester/RNTester/AppDelegate.mm b/packages/rn-tester/RNTester/AppDelegate.mm index 3f1ea7209bac..8f885bc96699 100644 --- a/packages/rn-tester/RNTester/AppDelegate.mm +++ b/packages/rn-tester/RNTester/AppDelegate.mm @@ -7,112 +7,26 @@ #import "AppDelegate.h" -#if !TARGET_OS_TV -#import -#endif - -#import -#import -#import -#import -#import - #if !TARGET_OS_TV #import +#import #endif -#import -#ifndef RN_DISABLE_OSS_PLUGIN_HEADER -#import -#endif - -#if __has_include() -#define USE_OSS_CODEGEN 1 -#import -#else -#define USE_OSS_CODEGEN 0 -#endif - -#if RCT_DEV_MENU -#import -#endif - -static NSString *kBundlePath = @"js/RNTesterApp.ios"; - #if !TARGET_OS_TV @interface AppDelegate () @end -#else -@interface AppDelegate () -@end #endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate:self]; -#if USE_OSS_CODEGEN - self.dependencyProvider = [RCTAppDependencyProvider new]; -#endif - -#if RCT_DEV_MENU - - RCTDevMenuConfiguration *devMenuConfiguration = [[RCTDevMenuConfiguration alloc] initWithDevMenuEnabled:true - shakeGestureEnabled:true - keyboardShortcutsEnabled:true]; - [self.reactNativeFactory setDevMenuConfiguration:devMenuConfiguration]; - -#endif - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - - [self.reactNativeFactory startReactNativeWithModuleName:@"RNTesterApp" - inWindow:self.window - initialProperties:[self prepareInitialProps] - launchOptions:launchOptions]; - #if !TARGET_OS_TV [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self]; #endif - return YES; } -- (NSDictionary *)prepareInitialProps -{ - NSMutableDictionary *initProps = [NSMutableDictionary new]; - - NSString *_routeUri = [[NSUserDefaults standardUserDefaults] stringForKey:@"route"]; - if (_routeUri) { - initProps[@"exampleFromAppetizeParams"] = [NSString stringWithFormat:@"rntester://example/%@Example", _routeUri]; - } - - return initProps; -} - -- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge -{ - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:kBundlePath]; -} - -- (BOOL)application:(UIApplication *)app - openURL:(NSURL *)url - options:(NSDictionary *)options -{ - return [RCTLinkingManager application:app openURL:url options:options]; -} - -- (std::shared_ptr)getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker -{ - if (name == facebook::react::NativeCxxModuleExample::kModuleName) { - return std::make_shared(jsInvoker); - } - - return [super getTurboModule:name jsInvoker:jsInvoker]; -} - #if !TARGET_OS_TV // Required for the remoteNotificationsRegistered event. - (void)application:(__unused UIApplication *)application @@ -159,25 +73,4 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center } #endif -#pragma mark - RCTComponentViewFactoryComponentProvider - -#ifndef RN_DISABLE_OSS_PLUGIN_HEADER -- (nonnull NSDictionary> *)thirdPartyFabricComponents -{ - NSMutableDictionary *dict = [super thirdPartyFabricComponents].mutableCopy; - if (!dict[@"RNTMyNativeView"]) { - dict[@"RNTMyNativeView"] = NSClassFromString(@"RNTMyNativeViewComponentView"); - } - if (!dict[@"SampleNativeComponent"]) { - dict[@"SampleNativeComponent"] = NSClassFromString(@"RCTSampleNativeComponentComponentView"); - } - return dict; -} -#endif - -- (NSURL *)bundleURL -{ - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:kBundlePath]; -} - @end diff --git a/packages/rn-tester/RNTester/Info.plist b/packages/rn-tester/RNTester/Info.plist index b785e4857907..359e0f1be536 100644 --- a/packages/rn-tester/RNTester/Info.plist +++ b/packages/rn-tester/RNTester/Info.plist @@ -48,6 +48,23 @@ You need to add NSPhotoLibraryUsageDescription key in Info.plist to enable photo library usage, otherwise it is going to *fail silently*! RCTNewArchEnabled + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + + + + RCTUseAssetCatalog UILaunchStoryboardName diff --git a/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.h b/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.h index d798f17738a6..2607ff32f56e 100644 --- a/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.h +++ b/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.h @@ -8,6 +8,15 @@ #import #import +#import + +@class RCTRootViewFactory; + +@interface FlexibleSizeExampleViewManager : RCTViewManager + +- (instancetype)initWithRootViewFactory:(RCTRootViewFactory *)rootViewFactory; + +@end @interface FlexibleSizeExampleView : RCTView diff --git a/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm b/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm index d08dd63be1f0..05980c38d729 100644 --- a/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm +++ b/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm @@ -7,29 +7,35 @@ #import "FlexibleSizeExampleView.h" +#import #import #import #import -#import -#import "AppDelegate.h" +@interface FlexibleSizeExampleView () -@interface FlexibleSizeExampleViewManager : RCTViewManager +- (instancetype)initWithFrame:(CGRect)frame rootViewFactory:(RCTRootViewFactory *)rootViewFactory; @end -@implementation FlexibleSizeExampleViewManager +@implementation FlexibleSizeExampleViewManager { + RCTRootViewFactory *_rootViewFactory; +} RCT_EXPORT_MODULE(); -- (UIView *)view +- (instancetype)initWithRootViewFactory:(RCTRootViewFactory *)rootViewFactory { - return [FlexibleSizeExampleView new]; + if ((self = [super init]) != nil) { + _rootViewFactory = rootViewFactory; + } + return self; } -@end - -@interface FlexibleSizeExampleView () +- (UIView *)view +{ + return [[FlexibleSizeExampleView alloc] initWithFrame:CGRectZero rootViewFactory:_rootViewFactory]; +} @end @@ -40,14 +46,16 @@ @implementation FlexibleSizeExampleView { } - (instancetype)initWithFrame:(CGRect)frame +{ + return [self initWithFrame:frame rootViewFactory:nil]; +} + +- (instancetype)initWithFrame:(CGRect)frame rootViewFactory:(RCTRootViewFactory *)rootViewFactory { if ((self = [super initWithFrame:frame])) { _sizeUpdated = NO; - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; - - _resizableRootView = (RCTRootView *)[appDelegate.reactNativeFactory.rootViewFactory - viewWithModuleName:@"RootViewSizeFlexibilityExampleApp"]; + _resizableRootView = (RCTRootView *)[rootViewFactory viewWithModuleName:@"RootViewSizeFlexibilityExampleApp"]; [_resizableRootView setSizeFlexibility:RCTRootViewSizeFlexibilityHeight]; diff --git a/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.h b/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.h index fcf18370072b..17ca049b2beb 100644 --- a/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.h +++ b/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.h @@ -8,6 +8,15 @@ #import #import +#import + +@class RCTRootViewFactory; + +@interface UpdatePropertiesExampleViewManager : RCTViewManager + +- (instancetype)initWithRootViewFactory:(RCTRootViewFactory *)rootViewFactory; + +@end @interface UpdatePropertiesExampleView : RCTView diff --git a/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm b/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm index 6cf4a1a03f19..e0207ad0b4de 100644 --- a/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm +++ b/packages/rn-tester/RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm @@ -7,22 +7,32 @@ #import "UpdatePropertiesExampleView.h" +#import #import -#import -#import "AppDelegate.h" +@interface UpdatePropertiesExampleView () -@interface UpdatePropertiesExampleViewManager : RCTViewManager +- (instancetype)initWithFrame:(CGRect)frame rootViewFactory:(RCTRootViewFactory *)rootViewFactory; @end -@implementation UpdatePropertiesExampleViewManager +@implementation UpdatePropertiesExampleViewManager { + RCTRootViewFactory *_rootViewFactory; +} RCT_EXPORT_MODULE(); +- (instancetype)initWithRootViewFactory:(RCTRootViewFactory *)rootViewFactory +{ + if ((self = [super init]) != nil) { + _rootViewFactory = rootViewFactory; + } + return self; +} + - (UIView *)view { - return [UpdatePropertiesExampleView new]; + return [[UpdatePropertiesExampleView alloc] initWithFrame:CGRectZero rootViewFactory:_rootViewFactory]; } @end @@ -34,16 +44,18 @@ @implementation UpdatePropertiesExampleView { } - (instancetype)initWithFrame:(CGRect)frame +{ + return [self initWithFrame:frame rootViewFactory:nil]; +} + +- (instancetype)initWithFrame:(CGRect)frame rootViewFactory:(RCTRootViewFactory *)rootViewFactory { self = [super initWithFrame:frame]; if (self) { _beige = YES; - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; - - _rootView = - (RCTRootView *)[appDelegate.reactNativeFactory.rootViewFactory viewWithModuleName:@"SetPropertiesExampleApp" - initialProperties:@{@"color" : @"beige"}]; + _rootView = (RCTRootView *)[rootViewFactory viewWithModuleName:@"SetPropertiesExampleApp" + initialProperties:@{@"color" : @"beige"}]; _button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [_button setTitle:@"Native Button" forState:UIControlStateNormal]; diff --git a/packages/rn-tester/RNTester/SceneDelegate.h b/packages/rn-tester/RNTester/SceneDelegate.h new file mode 100644 index 000000000000..e61b45ecd7b9 --- /dev/null +++ b/packages/rn-tester/RNTester/SceneDelegate.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import +#import + +@interface SceneDelegate : RCTDefaultReactNativeFactoryDelegate + +@property (nonatomic, strong, nullable) UIWindow *window; +@property (nonatomic, strong, nullable) RCTReactNativeFactory *reactNativeFactory; + +- (NSDictionary *)prepareInitialProps; + +@end diff --git a/packages/rn-tester/RNTester/SceneDelegate.mm b/packages/rn-tester/RNTester/SceneDelegate.mm new file mode 100644 index 000000000000..83a8ba324f27 --- /dev/null +++ b/packages/rn-tester/RNTester/SceneDelegate.mm @@ -0,0 +1,129 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "SceneDelegate.h" + +#import "NativeExampleViews/FlexibleSizeExampleView.h" +#import "NativeExampleViews/UpdatePropertiesExampleView.h" + +#import +#import +#import +#import +#import + +#import +#ifndef RN_DISABLE_OSS_PLUGIN_HEADER +#import +#endif + +#if __has_include() +#import +#endif + +#if RCT_DEV_MENU +#import +#endif + +static NSString *const kBundlePath = @"js/RNTesterApp.ios"; + +@implementation SceneDelegate + +- (NSDictionary *)prepareInitialProps +{ + NSMutableDictionary *initProps = [NSMutableDictionary dictionary]; + NSString *routeUri = [[NSUserDefaults standardUserDefaults] stringForKey:@"route"]; + if (routeUri != nil) { + NSString *example = [NSString stringWithFormat:@"rntester://example/%@Example", routeUri]; + initProps[@"exampleFromAppetizeParams"] = example; + } + return [initProps copy]; +} + +- (void)scene:(UIScene *)scene + willConnectToSession:(UISceneSession *)session + options:(UISceneConnectionOptions *)connectionOptions +{ + if (![scene isKindOfClass:[UIWindowScene class]]) { + return; + } + +#if __has_include() + self.dependencyProvider = [[RCTAppDependencyProvider alloc] init]; +#endif + + self.reactNativeFactory = [[RCTReactNativeFactory alloc] initWithDelegate:self]; + + auto *windowScene = (UIWindowScene *)scene; + self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; + + [self.reactNativeFactory startReactNativeWithModuleName:@"RNTesterApp" + inWindow:self.window + initialProperties:[self prepareInitialProps] + connectionOptions:connectionOptions]; + +#if RCT_DEV_MENU + RCTDevMenuConfiguration *devMenuConfiguration = [[RCTDevMenuConfiguration alloc] initWithDevMenuEnabled:true + shakeGestureEnabled:true + keyboardShortcutsEnabled:true]; + [self.reactNativeFactory setDevMenuConfiguration:devMenuConfiguration]; +#endif +} + +- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts +{ + [RCTLinkingManager scene:scene openURLContexts:URLContexts]; +} + +- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity +{ + [RCTLinkingManager scene:scene continueUserActivity:userActivity]; +} + +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge +{ + return [self bundleURL]; +} + +- (NSURL *)bundleURL +{ + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:kBundlePath]; +} + +- (std::shared_ptr)getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker +{ + if (name == facebook::react::NativeCxxModuleExample::kModuleName) { + return std::make_shared(jsInvoker); + } + + return [super getTurboModule:name jsInvoker:jsInvoker]; +} + +- (NSArray> *)extraModulesForBridge:(__unused RCTBridge *)bridge +{ + return @[ + [[FlexibleSizeExampleViewManager alloc] initWithRootViewFactory:self.reactNativeFactory.rootViewFactory], + [[UpdatePropertiesExampleViewManager alloc] initWithRootViewFactory:self.reactNativeFactory.rootViewFactory], + ]; +} + +#ifndef RN_DISABLE_OSS_PLUGIN_HEADER +- (nonnull NSDictionary> *)thirdPartyFabricComponents +{ + NSMutableDictionary *dict = [super thirdPartyFabricComponents].mutableCopy; + if (!dict[@"RNTMyNativeView"]) { + dict[@"RNTMyNativeView"] = NSClassFromString(@"RNTMyNativeViewComponentView"); + } + if (!dict[@"SampleNativeComponent"]) { + dict[@"SampleNativeComponent"] = NSClassFromString(@"RCTSampleNativeComponentComponentView"); + } + return dict; +} +#endif + +@end diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 2f6e9c5ea8d2..8248d57b2b2a 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 3F4D148C63BBF774A25488A6 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */; }; 46C0FD761B0B9B1E8662B759 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B312B0EEE90BA411618B015 /* libPods-RNTesterUnitTests.a */; }; 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; + 79B29C2E2E607A99007612A5 /* SceneDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 79B29C2D2E607A99007612A5 /* SceneDelegate.mm */; }; 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; 832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; }; A975CA6C2C05EADF0043F72A /* RCTNetworkTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A975CA6B2C05EADE0043F72A /* RCTNetworkTaskTests.m */; }; @@ -92,6 +93,8 @@ 4C706D402EE4AF9BE838CBA9 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 51BC9297B6C3163C14532020 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; + 79B29C2C2E607A99007612A5 /* SceneDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SceneDelegate.h; path = RNTester/SceneDelegate.h; sourceTree = ""; }; + 79B29C2D2E607A99007612A5 /* SceneDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = SceneDelegate.mm; path = RNTester/SceneDelegate.mm; sourceTree = ""; }; 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = ""; }; 93A243F0D4D5C54911E811C4 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -208,6 +211,8 @@ E771AEEA22B44E3100EA1189 /* Info.plist */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 5C60EB1B226440DB0018C04F /* AppDelegate.mm */, + 79B29C2C2E607A99007612A5 /* SceneDelegate.h */, + 79B29C2D2E607A99007612A5 /* SceneDelegate.mm */, 13B07FB71A68108700A75B9A /* main.m */, 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */, 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */, @@ -729,6 +734,7 @@ buildActionMask = 2147483647; files = ( E62F11842A5C6584000BF1C8 /* UpdatePropertiesExampleView.mm in Sources */, + 79B29C2E2E607A99007612A5 /* SceneDelegate.mm in Sources */, E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */, 832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */, 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */, diff --git a/private/helloworld/Gemfile.lock b/private/helloworld/Gemfile.lock index 18811995a299..e32aa146390f 100644 --- a/private/helloworld/Gemfile.lock +++ b/private/helloworld/Gemfile.lock @@ -98,6 +98,7 @@ PLATFORMS DEPENDENCIES activesupport (>= 6.1.7.5, < 7.1.0) + base64 benchmark bigdecimal cocoapods (~> 1.13, != 1.15.1, != 1.15.0) @@ -105,6 +106,7 @@ DEPENDENCIES ffi (>= 1.17.2) logger mutex_m + nkf rexml (>= 3.3.9) xcodeproj (< 1.26.0) diff --git a/private/helloworld/ios/HelloWorld.xcodeproj/project.pbxproj b/private/helloworld/ios/HelloWorld.xcodeproj/project.pbxproj index b36116e685e8..e3cd20e1f572 100644 --- a/private/helloworld/ios/HelloWorld.xcodeproj/project.pbxproj +++ b/private/helloworld/ios/HelloWorld.xcodeproj/project.pbxproj @@ -11,9 +11,10 @@ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 6EA01F72FAC10D00AECACF94 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 0EC7AB76F90EED035707BA4E /* PrivacyInfo.xcprivacy */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + C5E681697D864CB241D83EFA /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A8E5ECDA77F0C61C263AE4C /* libPods-HelloWorld-HelloWorldTests.a */; }; CDA0ED1A2D0B2D810079F561 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDA0ED192D0B2D810079F561 /* AppDelegate.swift */; }; - D462E9F4436EDF91C8A1FA0A /* Pods_HelloWorld.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3F2101C8317E5C933C1BD4C /* Pods_HelloWorld.framework */; }; - D693EA25CB545D6C1C7F8538 /* Pods_HelloWorld_HelloWorldTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A97924660E462ECF2425C3A /* Pods_HelloWorld_HelloWorldTests.framework */; }; + CDA0ED1B2D0B2D810079F562 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDA0ED1C2D0B2D810079F562 /* SceneDelegate.swift */; }; + F139D3B2B0DB3E81C6EC8497 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4454510AD252A40B7E239F /* libPods-HelloWorld.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -36,13 +37,14 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HelloWorld/Info.plist; sourceTree = ""; }; 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = HelloWorld/PrivacyInfo.xcprivacy; sourceTree = ""; }; 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; }; + 3E4454510AD252A40B7E239F /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; }; 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; sourceTree = ""; }; - 7A97924660E462ECF2425C3A /* Pods_HelloWorld_HelloWorldTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HelloWorld_HelloWorldTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7A8E5ECDA77F0C61C263AE4C /* libPods-HelloWorld-HelloWorldTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld-HelloWorldTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = HelloWorld/LaunchScreen.storyboard; sourceTree = ""; }; 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.release.xcconfig"; sourceTree = ""; }; - B3F2101C8317E5C933C1BD4C /* Pods_HelloWorld.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HelloWorld.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CDA0ED192D0B2D810079F561 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HelloWorld/AppDelegate.swift; sourceTree = ""; }; + CDA0ED1C2D0B2D810079F562 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SceneDelegate.swift; path = HelloWorld/SceneDelegate.swift; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -51,7 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D693EA25CB545D6C1C7F8538 /* Pods_HelloWorld_HelloWorldTests.framework in Frameworks */, + C5E681697D864CB241D83EFA /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +61,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D462E9F4436EDF91C8A1FA0A /* Pods_HelloWorld.framework in Frameworks */, + F139D3B2B0DB3E81C6EC8497 /* libPods-HelloWorld.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +94,7 @@ 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */, 0EC7AB76F90EED035707BA4E /* PrivacyInfo.xcprivacy */, CDA0ED192D0B2D810079F561 /* AppDelegate.swift */, + CDA0ED1C2D0B2D810079F562 /* SceneDelegate.swift */, ); name = HelloWorld; sourceTree = ""; @@ -100,8 +103,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - B3F2101C8317E5C933C1BD4C /* Pods_HelloWorld.framework */, - 7A97924660E462ECF2425C3A /* Pods_HelloWorld_HelloWorldTests.framework */, + 3E4454510AD252A40B7E239F /* libPods-HelloWorld.a */, + 7A8E5ECDA77F0C61C263AE4C /* libPods-HelloWorld-HelloWorldTests.a */, ); name = Frameworks; sourceTree = ""; @@ -395,6 +398,7 @@ buildActionMask = 2147483647; files = ( CDA0ED1A2D0B2D810079F561 /* AppDelegate.swift in Sources */, + CDA0ED1B2D0B2D810079F562 /* SceneDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -588,6 +592,10 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -595,9 +603,14 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); - OTHER_LDFLAGS = "$(inherited) "; - REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native"; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); + PODFILE_DIR = "$(SRCROOT)"; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../packages/react-native"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; USE_HERMES = true; @@ -668,6 +681,10 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -675,9 +692,14 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); - OTHER_LDFLAGS = "$(inherited) "; - REACT_NATIVE_PATH = "${PODS_ROOT}/../../../react-native"; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); + PODFILE_DIR = "$(SRCROOT)"; + REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../packages/react-native"; SDKROOT = iphoneos; USE_HERMES = true; VALIDATE_PRODUCT = YES; diff --git a/private/helloworld/ios/HelloWorld/AppDelegate.swift b/private/helloworld/ios/HelloWorld/AppDelegate.swift index b9ddfff35a27..1ed6ab1c9733 100644 --- a/private/helloworld/ios/HelloWorld/AppDelegate.swift +++ b/private/helloworld/ios/HelloWorld/AppDelegate.swift @@ -5,56 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React -import ReactAppDependencyProvider -import React_RCTAppDelegate import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - - var reactNativeDelegate: ReactNativeDelegate? - var reactNativeFactory: RCTReactNativeFactory? - func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil ) -> Bool { - let delegate = ReactNativeDelegate() - let factory = RCTReactNativeFactory(delegate: delegate) - delegate.dependencyProvider = RCTAppDependencyProvider() - - reactNativeDelegate = delegate - reactNativeFactory = factory - - #if DEBUG - let devMenuConfiguration = RCTDevMenuConfiguration( - devMenuEnabled: true, - shakeGestureEnabled: true, - keyboardShortcutsEnabled: true - ) - reactNativeFactory?.devMenuConfiguration = devMenuConfiguration - #endif - - window = UIWindow(frame: UIScreen.main.bounds) - - factory.startReactNative( - withModuleName: "HelloWorld", - in: window, - launchOptions: launchOptions - ) - - return true - } -} - -class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate { - override func bundleURL() -> URL? { - #if DEBUG - RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") - #else - Bundle.main.url(forResource: "main", withExtension: "jsbundle") - #endif + true } } diff --git a/private/helloworld/ios/HelloWorld/Info.plist b/private/helloworld/ios/HelloWorld/Info.plist index a766cc2814e5..2dda775f5afd 100644 --- a/private/helloworld/ios/HelloWorld/Info.plist +++ b/private/helloworld/ios/HelloWorld/Info.plist @@ -34,6 +34,21 @@ NSLocationWhenInUseUsageDescription + UIApplicationSceneManifest + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + RCTUseAssetCatalog UILaunchStoryboardName diff --git a/private/helloworld/ios/HelloWorld/SceneDelegate.swift b/private/helloworld/ios/HelloWorld/SceneDelegate.swift new file mode 100644 index 000000000000..d210beb37d59 --- /dev/null +++ b/private/helloworld/ios/HelloWorld/SceneDelegate.swift @@ -0,0 +1,53 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React +import ReactAppDependencyProvider +import React_RCTAppDelegate +import UIKit + +class SceneDelegate: RCTDefaultReactNativeFactoryDelegate, UIWindowSceneDelegate { + var window: UIWindow? + var reactNativeFactory: RCTReactNativeFactory? + + func scene( + _ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions + ) { + guard let windowScene = scene as? UIWindowScene else { + return + } + + dependencyProvider = RCTAppDependencyProvider() + reactNativeFactory = RCTReactNativeFactory(delegate: self) + window = UIWindow(windowScene: windowScene) + + reactNativeFactory?.startReactNative( + withModuleName: "HelloWorld", + in: window, + connectionOptions: connectionOptions + ) + + } + + func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + RCTLinkingManager.scene(scene, openURLContexts: URLContexts) + } + + func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { + RCTLinkingManager.scene(scene, continue: userActivity) + } + + override func bundleURL() -> URL? { + #if DEBUG + RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") + #else + Bundle.main.url(forResource: "main", withExtension: "jsbundle") + #endif + } +} diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 6e4ab04a9d24..404b21ab3071 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -642,8 +642,6 @@ interface RCTAnimatedNode : public NSObject { interface RCTAppDelegate : public RCTDefaultReactNativeFactoryDelegate { public @property (assign) BOOL automaticallyLoadReactNativeWindow; - public @property (assign) RCTBridge* bridge; - public @property (assign) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public @property (strong) NSDictionary* initialProps; public @property (strong) NSString* moduleName; public @property (strong) RCTReactNativeFactory* reactNativeFactory; @@ -1369,6 +1367,8 @@ interface RCTLinkingManager : public RCTEventEmitter { public virtual static BOOL application:continueUserActivity:restorationHandler:(_Nonnull UIApplication* application, _Nonnull NSUserActivity* userActivity, _Nonnull void(^)(NSArray>* _Nullable) restorationHandler); public virtual static BOOL application:openURL:options:(_Nonnull UIApplication* app, _Nonnull NSURL* URL, _Nonnull NSDictionary* options); public virtual static BOOL application:openURL:sourceApplication:annotation:(_Nonnull UIApplication* application, _Nonnull NSURL* URL, _Nullable NSString* sourceApplication, _Nonnull id annotation); + public virtual static void scene:continueUserActivity:(_Nonnull UIScene* scene, _Nonnull NSUserActivity* userActivity); + public virtual static void scene:openURLContexts:(_Nonnull UIScene* scene, _Nonnull NSSet* URLContexts); } interface RCTLoadingProgress : public NSObject { @@ -1593,14 +1593,16 @@ interface RCTRadialGradient : public NSObject { } interface RCTReactNativeFactory : public NSObject { + public @property (assign) RCTBridge* bridge; public @property (assign) RCTDevMenuConfiguration* devMenuConfiguration; - public @property (assign) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public @property (strong) RCTBundleConfiguration* bundleConfiguration; public @property (strong) RCTRootViewFactory* rootViewFactory; public @property (weak) id delegate; public virtual instancetype initWithDelegate:(id delegate); public virtual instancetype initWithDelegate:releaseLevel:(id delegate, RCTReleaseLevel releaseLevel); public virtual void startReactNativeWithModuleName:inWindow:(NSString* moduleName, UIWindow* _Nullable window); + public virtual void startReactNativeWithModuleName:inWindow:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, UISceneConnectionOptions* _Nullable connectionOptions); + public virtual void startReactNativeWithModuleName:inWindow:initialProperties:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, UISceneConnectionOptions* _Nullable connectionOptions); public virtual void startReactNativeWithModuleName:inWindow:initialProperties:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, NSDictionary* _Nullable launchOptions); public virtual void startReactNativeWithModuleName:inWindow:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable launchOptions); } @@ -1665,9 +1667,7 @@ interface RCTRootView : public UIView { } interface RCTRootViewFactory : public NSObject { - public @property (strong) RCTBridge* bridge; public @property (strong) RCTHost* reactHost; - public @property (strong) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public virtual RCTHost* createReactHost:(NSDictionary* _Nullable launchOptions); public virtual RCTHost* createReactHost:bundleConfiguration:devMenuConfiguration:(NSDictionary* _Nullable launchOptions, RCTBundleConfiguration* bundleConfiguration, RCTDevMenuConfiguration* devMenuConfiguration); public virtual UIView* _Nonnull viewWithModuleName:(NSString* moduleName); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 02957e06c0f6..117b16a8e16f 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -1367,6 +1367,8 @@ interface RCTLinkingManager : public RCTEventEmitter { public virtual static BOOL application:continueUserActivity:restorationHandler:(_Nonnull UIApplication* application, _Nonnull NSUserActivity* userActivity, _Nonnull void(^)(NSArray>* _Nullable) restorationHandler); public virtual static BOOL application:openURL:options:(_Nonnull UIApplication* app, _Nonnull NSURL* URL, _Nonnull NSDictionary* options); public virtual static BOOL application:openURL:sourceApplication:annotation:(_Nonnull UIApplication* application, _Nonnull NSURL* URL, _Nullable NSString* sourceApplication, _Nonnull id annotation); + public virtual static void scene:continueUserActivity:(_Nonnull UIScene* scene, _Nonnull NSUserActivity* userActivity); + public virtual static void scene:openURLContexts:(_Nonnull UIScene* scene, _Nonnull NSSet* URLContexts); } interface RCTLoadingProgress : public NSObject { @@ -1598,6 +1600,8 @@ interface RCTReactNativeFactory : public NSObject { public virtual instancetype initWithDelegate:(id delegate); public virtual instancetype initWithDelegate:releaseLevel:(id delegate, RCTReleaseLevel releaseLevel); public virtual void startReactNativeWithModuleName:inWindow:(NSString* moduleName, UIWindow* _Nullable window); + public virtual void startReactNativeWithModuleName:inWindow:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, UISceneConnectionOptions* _Nullable connectionOptions); + public virtual void startReactNativeWithModuleName:inWindow:initialProperties:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, UISceneConnectionOptions* _Nullable connectionOptions); public virtual void startReactNativeWithModuleName:inWindow:initialProperties:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, NSDictionary* _Nullable launchOptions); public virtual void startReactNativeWithModuleName:inWindow:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable launchOptions); } diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 94953681427d..bc7504c73713 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -642,8 +642,6 @@ interface RCTAnimatedNode : public NSObject { interface RCTAppDelegate : public RCTDefaultReactNativeFactoryDelegate { public @property (assign) BOOL automaticallyLoadReactNativeWindow; - public @property (assign) RCTBridge* bridge; - public @property (assign) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public @property (strong) NSDictionary* initialProps; public @property (strong) NSString* moduleName; public @property (strong) RCTReactNativeFactory* reactNativeFactory; @@ -1369,6 +1367,8 @@ interface RCTLinkingManager : public RCTEventEmitter { public virtual static BOOL application:continueUserActivity:restorationHandler:(_Nonnull UIApplication* application, _Nonnull NSUserActivity* userActivity, _Nonnull void(^)(NSArray>* _Nullable) restorationHandler); public virtual static BOOL application:openURL:options:(_Nonnull UIApplication* app, _Nonnull NSURL* URL, _Nonnull NSDictionary* options); public virtual static BOOL application:openURL:sourceApplication:annotation:(_Nonnull UIApplication* application, _Nonnull NSURL* URL, _Nullable NSString* sourceApplication, _Nonnull id annotation); + public virtual static void scene:continueUserActivity:(_Nonnull UIScene* scene, _Nonnull NSUserActivity* userActivity); + public virtual static void scene:openURLContexts:(_Nonnull UIScene* scene, _Nonnull NSSet* URLContexts); } interface RCTLoadingProgress : public NSObject { @@ -1593,14 +1593,16 @@ interface RCTRadialGradient : public NSObject { } interface RCTReactNativeFactory : public NSObject { + public @property (assign) RCTBridge* bridge; public @property (assign) RCTDevMenuConfiguration* devMenuConfiguration; - public @property (assign) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public @property (strong) RCTBundleConfiguration* bundleConfiguration; public @property (strong) RCTRootViewFactory* rootViewFactory; public @property (weak) id delegate; public virtual instancetype initWithDelegate:(id delegate); public virtual instancetype initWithDelegate:releaseLevel:(id delegate, RCTReleaseLevel releaseLevel); public virtual void startReactNativeWithModuleName:inWindow:(NSString* moduleName, UIWindow* _Nullable window); + public virtual void startReactNativeWithModuleName:inWindow:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, UISceneConnectionOptions* _Nullable connectionOptions); + public virtual void startReactNativeWithModuleName:inWindow:initialProperties:connectionOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, UISceneConnectionOptions* _Nullable connectionOptions); public virtual void startReactNativeWithModuleName:inWindow:initialProperties:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable initialProperties, NSDictionary* _Nullable launchOptions); public virtual void startReactNativeWithModuleName:inWindow:launchOptions:(NSString* moduleName, UIWindow* _Nullable window, NSDictionary* _Nullable launchOptions); } @@ -1665,9 +1667,7 @@ interface RCTRootView : public UIView { } interface RCTRootViewFactory : public NSObject { - public @property (strong) RCTBridge* bridge; public @property (strong) RCTHost* reactHost; - public @property (strong) RCTSurfacePresenterBridgeAdapter* bridgeAdapter; public virtual RCTHost* createReactHost:(NSDictionary* _Nullable launchOptions); public virtual RCTHost* createReactHost:bundleConfiguration:devMenuConfiguration:(NSDictionary* _Nullable launchOptions, RCTBundleConfiguration* bundleConfiguration, RCTDevMenuConfiguration* devMenuConfiguration); public virtual UIView* _Nonnull viewWithModuleName:(NSString* moduleName);