From b08d8c7ee3b1ea7e58ecd65acd167a7b2457ae58 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 6 May 2025 09:40:03 +0200 Subject: [PATCH 1/4] fix(apple): fix app autodetection in bridgeless mode --- common/AppRegistry.cpp | 53 ++++-- example/ios/ExampleTests/DevSupportTests.m | 8 +- example/ios/Podfile.lock | 4 +- example/macos/Podfile.lock | 4 +- example/visionos/Podfile.lock | 4 +- ios/ReactTestApp/AppDelegate.swift | 2 +- ios/ReactTestApp/AppRegistryModule.mm | 34 ++-- ios/ReactTestApp/ContentView.swift | 2 +- .../Public/ReactTestApp-DevSupport.h | 24 ++- ios/ReactTestApp/ReactInstance.swift | 26 ++- ios/ReactTestApp/ReactTestApp-DevSupport.m | 22 ++- ios/ReactTestApp/SceneDelegate.swift | 2 +- macos/ReactTestApp/AppDelegate.swift | 4 +- package.json | 2 +- yarn.lock | 160 +++++++++--------- 15 files changed, 205 insertions(+), 146 deletions(-) diff --git a/common/AppRegistry.cpp b/common/AppRegistry.cpp index ab36391b9..37b75fe25 100644 --- a/common/AppRegistry.cpp +++ b/common/AppRegistry.cpp @@ -3,33 +3,50 @@ #if __has_include() #include +using facebook::jsi::Array; using facebook::jsi::Runtime; using facebook::jsi::String; -std::vector ReactTestApp::GetAppKeys(Runtime &runtime) +namespace { - std::vector result; - constexpr char kFbBatchedBridgeId[] = "__fbBatchedBridge"; + constexpr char kRNAppRegistryId[] = "RN$AppRegistry"; + + Array GetRegisteredAppKeys(Runtime &runtime) + { + auto global = runtime.global(); + if (global.hasProperty(runtime, kRNAppRegistryId)) { // >= 0.73 + // const appKeys = RN$AppRegistry.getAppKeys(); + auto registry = global.getProperty(runtime, kRNAppRegistryId); + if (registry.isObject()) { + auto getAppKeys = std::move(registry).asObject(runtime).getPropertyAsFunction( + runtime, "getAppKeys"); + return getAppKeys.call(runtime, nullptr, 0).asObject(runtime).asArray(runtime); + } + } else if (global.hasProperty(runtime, kFbBatchedBridgeId)) { // < 0.73 + // const appRegistry = __fbBatchedBridge.getCallableModule("AppRegistry"); + auto fbBatchedBridge = global.getPropertyAsObject(runtime, kFbBatchedBridgeId); + auto getCallableModule = + fbBatchedBridge.getPropertyAsFunction(runtime, "getCallableModule"); + auto appRegistry = + getCallableModule.callWithThis(runtime, fbBatchedBridge, "AppRegistry") + .asObject(runtime); + + // const appKeys = appRegistry.getAppKeys(); + auto getAppKeys = appRegistry.getPropertyAsFunction(runtime, "getAppKeys"); + return getAppKeys.callWithThis(runtime, appRegistry).asObject(runtime).asArray(runtime); + } - auto global = runtime.global(); - if (!global.hasProperty(runtime, kFbBatchedBridgeId)) { - return result; + return Array(runtime, 0); } +} // namespace - try { - // const appRegistry = __fbBatchedBridge.getCallableModule("AppRegistry"); - auto fbBatchedBridge = global.getPropertyAsObject(runtime, kFbBatchedBridgeId); - auto getCallableModule = - fbBatchedBridge.getPropertyAsFunction(runtime, "getCallableModule"); - auto appRegistry = getCallableModule.callWithThis(runtime, fbBatchedBridge, "AppRegistry") - .asObject(runtime); - - // const appKeys = appRegistry.getAppKeys(); - auto getAppKeys = appRegistry.getPropertyAsFunction(runtime, "getAppKeys"); - auto appKeys = - getAppKeys.callWithThis(runtime, appRegistry).asObject(runtime).asArray(runtime); +std::vector ReactTestApp::GetAppKeys(Runtime &runtime) +{ + std::vector result; + try { + auto appKeys = GetRegisteredAppKeys(runtime); auto length = appKeys.length(runtime); result.reserve(length); diff --git a/example/ios/ExampleTests/DevSupportTests.m b/example/ios/ExampleTests/DevSupportTests.m index 02d9d472a..a53f34aac 100644 --- a/example/ios/ExampleTests/DevSupportTests.m +++ b/example/ios/ExampleTests/DevSupportTests.m @@ -9,10 +9,10 @@ @implementation DevSupportTests - (void)testDevSupportIsLinked { - XCTAssertNotNil(ReactTestAppDidInitializeNotification); - XCTAssertNotNil(ReactTestAppWillInitializeReactNativeNotification); - XCTAssertNotNil(ReactTestAppDidInitializeReactNativeNotification); - XCTAssertNotNil(ReactTestAppSceneDidOpenURLNotification); + XCTAssertNotNil(ReactAppDidInitializeNotification); + XCTAssertNotNil(ReactAppWillInitializeReactNativeNotification); + XCTAssertNotNil(ReactAppDidInitializeReactNativeNotification); + XCTAssertNotNil(ReactAppSceneDidOpenURLNotification); } @end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 08066e804..a34d03659 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1482,7 +1482,7 @@ PODS: - React-logger (= 0.78.2) - React-perflogger (= 0.78.2) - React-utils (= 0.78.2) - - ReactNativeHost (0.5.5): + - ReactNativeHost (0.5.8): - DoubleConversion - glog - RCT-Folly (= 2024.11.18.00) @@ -1814,7 +1814,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: 4893bde33952f997a323eb1a1ee87a72764018ff ReactCodegen: a99d9f9129c83cdd5c58dea8826d1b82ec528b93 ReactCommon: 5008bd981a06fe63176ef815f092685ffee8f7eb - ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161 + ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064 ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1 ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 032fc3076..34ff7e332 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -1483,7 +1483,7 @@ PODS: - React-logger (= 0.78.3) - React-perflogger (= 0.78.3) - React-utils (= 0.78.3) - - ReactNativeHost (0.5.5): + - ReactNativeHost (0.5.8): - DoubleConversion - glog - RCT-Folly (= 2024.11.18.00) @@ -1814,7 +1814,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: a12262458b50521ba56afb93f4cc875732f9d643 ReactCodegen: 191e4a5cb0241651f2fcf21d79729c6465f0f905 ReactCommon: 0f22e3dd34a8215b8482778898f6e1e95572c498 - ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161 + ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064 ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1 ReactTestApp-Resources: 86136e1efe3aa7201759371c03dea3df77079b42 RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be diff --git a/example/visionos/Podfile.lock b/example/visionos/Podfile.lock index 8653307f6..4a5cd9e05 100644 --- a/example/visionos/Podfile.lock +++ b/example/visionos/Podfile.lock @@ -1536,7 +1536,7 @@ PODS: - React-logger (= 0.78.0) - React-perflogger (= 0.78.0) - React-utils (= 0.78.0) - - ReactNativeHost (0.5.5): + - ReactNativeHost (0.5.8): - DoubleConversion - glog - RCT-Folly (= 2024.11.18.00) @@ -1880,7 +1880,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: b0dbc9d44b4e45e2b2468df4a2f49fb51806224f ReactCodegen: 4d719f75b156783b8fdf07fe4091a7f38bc52967 ReactCommon: a690d72c5df9a63d64a2444d5aad695c37554ea7 - ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161 + ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064 ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1 ReactTestApp-Resources: 2ad57492ef72ab9b2c6f6e89ea198cc1999ca20b RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be diff --git a/ios/ReactTestApp/AppDelegate.swift b/ios/ReactTestApp/AppDelegate.swift index 07ae80149..d010c3c2b 100644 --- a/ios/ReactTestApp/AppDelegate.swift +++ b/ios/ReactTestApp/AppDelegate.swift @@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { defer { NotificationCenter.default.post( - name: .ReactTestAppDidInitialize, + name: .ReactAppDidInitialize, object: nil ) } diff --git a/ios/ReactTestApp/AppRegistryModule.mm b/ios/ReactTestApp/AppRegistryModule.mm index ba86ec553..9ac84f86e 100644 --- a/ios/ReactTestApp/AppRegistryModule.mm +++ b/ios/ReactTestApp/AppRegistryModule.mm @@ -14,6 +14,25 @@ @interface RCTCxxBridge : RCTBridge - (void)invokeAsync:(std::function &&)func; @end +void RTAPostDidRegisterAppsNotification(NSValue *value) +{ + Runtime *runtime = static_cast([value pointerValue]); + + auto appKeys = ReactTestApp::GetAppKeys(*runtime); + if (appKeys.empty()) { + return; + } + + NSMutableArray *array = [NSMutableArray arrayWithCapacity:appKeys.size()]; + for (const auto &appKey : appKeys) { + [array addObject:[NSString stringWithUTF8String:appKey.c_str()]]; + } + + [NSNotificationCenter.defaultCenter postNotificationName:ReactAppDidRegisterAppsNotification + object:nil + userInfo:@{@"appKeys": [array copy]}]; +} + @implementation RTAAppRegistryModule RCT_EXPORT_MODULE(); @@ -50,20 +69,7 @@ - (void)javascriptDidLoadNotification:(NSNotification *)note return; } - auto appKeys = ReactTestApp::GetAppKeys(*runtime); - if (appKeys.empty()) { - return; - } - - NSMutableArray *array = [NSMutableArray arrayWithCapacity:appKeys.size()]; - for (const auto &appKey : appKeys) { - [array addObject:[NSString stringWithUTF8String:appKey.c_str()]]; - } - - [NSNotificationCenter.defaultCenter - postNotificationName:ReactTestAppDidRegisterAppsNotification - object:nil - userInfo:@{@"appKeys": [array copy]}]; + RTAPostDidRegisterAppsNotification([NSValue valueWithPointer:runtime]); }]; } diff --git a/ios/ReactTestApp/ContentView.swift b/ios/ReactTestApp/ContentView.swift index de747394d..0673fb730 100644 --- a/ios/ReactTestApp/ContentView.swift +++ b/ios/ReactTestApp/ContentView.swift @@ -92,7 +92,7 @@ final class ContentViewController: UITableViewController { let components = manifest.components ?? [] if components.isEmpty { NotificationCenter.default.addObserver( - forName: .ReactTestAppDidRegisterApps, + forName: .ReactAppDidRegisterApps, object: nil, queue: .main, using: { [weak self] note in diff --git a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h index 10a4faab3..f080a7830 100644 --- a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h +++ b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h @@ -2,14 +2,26 @@ NS_ASSUME_NONNULL_BEGIN -extern NSNotificationName const ReactTestAppDidInitializeNotification; +OBJC_EXTERN NSNotificationName const ReactAppDidInitializeNotification; +OBJC_EXTERN NSNotificationName const ReactAppWillInitializeReactNativeNotification; +OBJC_EXTERN NSNotificationName const ReactAppDidInitializeReactNativeNotification; +OBJC_EXTERN NSNotificationName const ReactAppDidRegisterAppsNotification; +OBJC_EXTERN NSNotificationName const ReactAppRuntimeReady; +OBJC_EXTERN NSNotificationName const ReactAppSceneDidOpenURLNotification; -extern NSNotificationName const ReactTestAppWillInitializeReactNativeNotification; -extern NSNotificationName const ReactTestAppDidInitializeReactNativeNotification; -extern NSNotificationName const ReactTestAppDidRegisterAppsNotification; +OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeNotification + __deprecated_msg("Use 'ReactAppDidInitializeNotification' instead"); +OBJC_EXTERN NSNotificationName const ReactTestAppWillInitializeReactNativeNotification + __deprecated_msg("Use 'ReactAppWillInitializeReactNativeNotification' instead"); +OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeReactNativeNotification + __deprecated_msg("Use 'ReactAppDidInitializeReactNativeNotification' instead"); +OBJC_EXTERN NSNotificationName const ReactTestAppDidRegisterAppsNotification + __deprecated_msg("Use 'ReactAppDidRegisterAppsNotification' instead"); +OBJC_EXTERN NSNotificationName const ReactTestAppSceneDidOpenURLNotification + __deprecated_msg("Use 'ReactAppSceneDidOpenURLNotification' instead"); -extern NSNotificationName const ReactTestAppSceneDidOpenURLNotification; +OBJC_EXTERN NSNotificationName const ReactInstanceDidLoadBundle; -extern NSNotificationName const ReactInstanceDidLoadBundle; +OBJC_EXTERN void RTAPostDidRegisterAppsNotification(NSValue *runtime); NS_ASSUME_NONNULL_END diff --git a/ios/ReactTestApp/ReactInstance.swift b/ios/ReactTestApp/ReactInstance.swift index 79eea48e0..0b824d25e 100644 --- a/ios/ReactTestApp/ReactInstance.swift +++ b/ios/ReactTestApp/ReactInstance.swift @@ -37,8 +37,10 @@ final class ReactInstance: NSObject, RNXHostConfig { override init() { super.init() + let defaultNotificationCenter = NotificationCenter.default + // Bridged - NotificationCenter.default.addObserver( + defaultNotificationCenter.addObserver( self, selector: #selector(onJavaScriptLoaded(_:)), name: .RCTJavaScriptDidLoad, @@ -46,15 +48,22 @@ final class ReactInstance: NSObject, RNXHostConfig { ) // Bridgeless - NotificationCenter.default.addObserver( + defaultNotificationCenter.addObserver( self, selector: #selector(onJavaScriptLoaded(_:)), name: .ReactInstanceDidLoadBundle, object: nil ) + defaultNotificationCenter.addObserver( + self, + selector: #selector(onRuntimeReady(_:)), + name: .ReactAppRuntimeReady, + object: nil + ) + #if os(iOS) - NotificationCenter.default.addObserver( + defaultNotificationCenter.addObserver( self, selector: #selector(onRemoteBundleURLReceived(_:)), name: .didReceiveRemoteBundleURL, @@ -90,7 +99,7 @@ final class ReactInstance: NSObject, RNXHostConfig { self.bundleRoot = bundleRoot NotificationCenter.default.post( - name: .ReactTestAppWillInitializeReactNative, + name: .ReactAppWillInitializeReactNative, object: nil ) @@ -98,7 +107,7 @@ final class ReactInstance: NSObject, RNXHostConfig { host = reactNativeHost NotificationCenter.default.post( - name: .ReactTestAppDidInitializeReactNative, + name: .ReactAppDidInitializeReactNative, object: reactNativeHost ) @@ -220,6 +229,13 @@ final class ReactInstance: NSObject, RNXHostConfig { urlComponents.queryItems = [URLQueryItem(name: "platform", value: "ios")] remoteBundleURL = urlComponents.url } + + @objc + private func onRuntimeReady(_ notification: Notification) { + if let runtime = notification.userInfo?["runtime"] as? NSValue { + RTAPostDidRegisterAppsNotification(runtime) + } + } } #if canImport(UIKit) diff --git a/ios/ReactTestApp/ReactTestApp-DevSupport.m b/ios/ReactTestApp/ReactTestApp-DevSupport.m index 9e3c8d2d9..b672f4fe6 100644 --- a/ios/ReactTestApp/ReactTestApp-DevSupport.m +++ b/ios/ReactTestApp/ReactTestApp-DevSupport.m @@ -1,17 +1,25 @@ #import -NSNotificationName const ReactTestAppDidInitializeNotification = - @"ReactTestAppDidInitializeNotification"; +NSNotificationName const ReactAppDidInitializeNotification = @"ReactAppDidInitializeNotification"; +NSNotificationName const ReactAppWillInitializeReactNativeNotification = + @"ReactAppWillInitializeReactNativeNotification"; +NSNotificationName const ReactAppDidInitializeReactNativeNotification = + @"ReactAppDidInitializeReactNativeNotification"; +NSNotificationName const ReactAppDidRegisterAppsNotification = + @"ReactAppDidRegisterAppsNotification"; +NSNotificationName const ReactAppRuntimeReady = @"ReactAppRuntimeReady"; +NSNotificationName const ReactAppSceneDidOpenURLNotification = + @"ReactAppSceneDidOpenURLNotification"; +NSNotificationName const ReactTestAppDidInitializeNotification = ReactAppDidInitializeNotification; NSNotificationName const ReactTestAppWillInitializeReactNativeNotification = - @"ReactTestAppWillInitializeReactNativeNotification"; + ReactAppWillInitializeReactNativeNotification; NSNotificationName const ReactTestAppDidInitializeReactNativeNotification = - @"ReactTestAppDidInitializeReactNativeNotification"; + ReactAppDidInitializeReactNativeNotification; NSNotificationName const ReactTestAppDidRegisterAppsNotification = - @"ReactTestAppDidRegisterAppsNotification"; - + ReactAppDidRegisterAppsNotification; NSNotificationName const ReactTestAppSceneDidOpenURLNotification = - @"ReactTestAppSceneDidOpenURLNotification"; + ReactAppSceneDidOpenURLNotification; // https://github.com/facebook/react-native/blob/v0.73.4/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm#L448 NSNotificationName const ReactInstanceDidLoadBundle = @"RCTInstanceDidLoadBundle"; diff --git a/ios/ReactTestApp/SceneDelegate.swift b/ios/ReactTestApp/SceneDelegate.swift index 52ca3eb31..a68f7d8e1 100644 --- a/ios/ReactTestApp/SceneDelegate.swift +++ b/ios/ReactTestApp/SceneDelegate.swift @@ -50,7 +50,7 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate { } NotificationCenter.default.post( - name: .ReactTestAppSceneDidOpenURL, + name: .ReactAppSceneDidOpenURL, object: [ "scene": scene, "URLContexts": URLContexts, diff --git a/macos/ReactTestApp/AppDelegate.swift b/macos/ReactTestApp/AppDelegate.swift index cbf015d84..e1a265bca 100644 --- a/macos/ReactTestApp/AppDelegate.swift +++ b/macos/ReactTestApp/AppDelegate.swift @@ -23,7 +23,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_: Notification) { NotificationCenter.default.post( - name: .ReactTestAppDidInitialize, + name: .ReactAppDidInitialize, object: nil ) @@ -106,7 +106,7 @@ extension AppDelegate { let components = manifest.components ?? [] if components.isEmpty { NotificationCenter.default.addObserver( - forName: .ReactTestAppDidRegisterApps, + forName: .ReactAppDidRegisterApps, object: nil, queue: .main, using: { [weak self] note in diff --git a/package.json b/package.json index 804a71c0e..3229bcf50 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "test:rb": "bundle exec ruby -Ilib:test -e \"Dir.glob('./test/test_*.rb').each { |file| require(file) }\"" }, "dependencies": { - "@rnx-kit/react-native-host": "^0.5.7", + "@rnx-kit/react-native-host": "^0.5.8", "@rnx-kit/tools-react-native": "^2.1.0", "ajv": "^8.0.0", "cliui": "^8.0.0", diff --git a/yarn.lock b/yarn.lock index 54df55cec..7179ef395 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1894,14 +1894,14 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.5.0": - version: 4.6.1 - resolution: "@eslint-community/eslint-utils@npm:4.6.1" +"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.5.0, @eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" dependencies: eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/cdeb6f8fc33a83726357d7f736075cdbd6e79dc7ac4b00b15680f1111d0f33bda583e7fafa5937245a058cc66302dc47568bba57b251302dc74964d8e87f56d7 + checksum: 10c0/c0f4f2bd73b7b7a9de74b716a664873d08ab71ab439e51befe77d61915af41a81ecec93b408778b3a7856185244c34c2c8ee28912072ec14def84ba2dec70adf languageName: node linkType: hard @@ -3576,12 +3576,12 @@ __metadata: languageName: node linkType: hard -"@rnx-kit/react-native-host@npm:^0.5.7": - version: 0.5.7 - resolution: "@rnx-kit/react-native-host@npm:0.5.7" +"@rnx-kit/react-native-host@npm:^0.5.8": + version: 0.5.8 + resolution: "@rnx-kit/react-native-host@npm:0.5.8" peerDependencies: react-native: ">=0.66" - checksum: 10c0/7c0736a1e5fbda4d0bd48f58304b22528cdb0f8b3fd77fa4e58b625077f201c689ed07712b6f3e10994b6223f49bf35925754a659154b3b1da780d27462242b6 + checksum: 10c0/7c8accf892cc78155e7748e121bfd5a670ebdd5816e679e9c19b4de86c7372277d47bbb438e57e80bd70c83da5e15fcea19d25f1ed7136e457cec7ac4301cb77 languageName: node linkType: hard @@ -4134,115 +4134,115 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.19.0" +"@typescript-eslint/eslint-plugin@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.32.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.19.0" - "@typescript-eslint/type-utils": "npm:8.19.0" - "@typescript-eslint/utils": "npm:8.19.0" - "@typescript-eslint/visitor-keys": "npm:8.19.0" + "@typescript-eslint/scope-manager": "npm:8.32.0" + "@typescript-eslint/type-utils": "npm:8.32.0" + "@typescript-eslint/utils": "npm:8.32.0" + "@typescript-eslint/visitor-keys": "npm:8.32.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^1.3.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/ceaa5063b68684b5608950b5e69f0caf1eadfc356cba82625240d6aae55f769faff599c38d35252dcb77a40d92e6fbf6d6264bc0c577d5c549da25061c3bd796 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/db3d151386d7f086a2289ff21c12bff6d2c9e1e1fab7e20be627927604621618cfcfbe3289a1acf7ed7c0e465b64a696f02f3a95eac0aaafd1fe9d5431efe7b5 languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/parser@npm:8.19.0" +"@typescript-eslint/parser@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/parser@npm:8.32.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.19.0" - "@typescript-eslint/types": "npm:8.19.0" - "@typescript-eslint/typescript-estree": "npm:8.19.0" - "@typescript-eslint/visitor-keys": "npm:8.19.0" + "@typescript-eslint/scope-manager": "npm:8.32.0" + "@typescript-eslint/types": "npm:8.32.0" + "@typescript-eslint/typescript-estree": "npm:8.32.0" + "@typescript-eslint/visitor-keys": "npm:8.32.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/064b0997963060490fc3f92c90cebc7c694f47a7657f7882ce9eb314786e0cf3e917bfccfad614d23038439d84e69a978bdc7054515b23201001dd427e524e64 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/357a30a853102b1d09a064451f0e66610d41b86f0f4f7bf8b3ce96180e8c58acb0ed24b9f5bba970f7d8d5e94e98c583f2a821135002e3037b0dbce249563926 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/scope-manager@npm:8.19.0" +"@typescript-eslint/scope-manager@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/scope-manager@npm:8.32.0" dependencies: - "@typescript-eslint/types": "npm:8.19.0" - "@typescript-eslint/visitor-keys": "npm:8.19.0" - checksum: 10c0/5052863d00db7ae939de27e91dc6c92df3c37a877e1ff44015ae9aa754d419b44d97d98b25fbb30a80dc58cf92606dad599e27f32b86d20c13b77ac12b4f2abc + "@typescript-eslint/types": "npm:8.32.0" + "@typescript-eslint/visitor-keys": "npm:8.32.0" + checksum: 10c0/9149d4eebfc7f096a3401a4865e0e552231c91cee362fe3a59c31cf2f0b6b325619f534aed41688c3702867cf86b12454e00055d09e7f229c92083e28e97baac languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/type-utils@npm:8.19.0" +"@typescript-eslint/type-utils@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/type-utils@npm:8.32.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.19.0" - "@typescript-eslint/utils": "npm:8.19.0" + "@typescript-eslint/typescript-estree": "npm:8.32.0" + "@typescript-eslint/utils": "npm:8.32.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.3.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/5a460b4d26fd68ded3567390cbac310500e94e9c69583fda3fb9930877663719e6831699bb6d85de6b940bcb7951a51ab1ef67c5fea8b76a13ea3a3783bbae28 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/3aec7fbe77d8dae698f75d55d6bed537e7dfa3ed069fbcae456dcf5580c16746ef3e7020522223ca560a75842183fbb8e7ff309e872035d14bf98eb8fae454b4 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/types@npm:8.19.0" - checksum: 10c0/0062e7dce5f374e293c97f1f50fe450187f6b0eaf4971c818e18ef2f6baf4e9aa4e8605fba8d8fc464a504ee1130527b71ecb39d31687c31825942b9f569d902 +"@typescript-eslint/types@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/types@npm:8.32.0" + checksum: 10c0/86cc1e365bc12b8baf539e8e2d280b068a7d4a4220f5834fe4de182827a971200408a1ad20f9679af4c4bcdafea03dd66319fe7f1d060ce4b5abbf2962ea3062 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.19.0" +"@typescript-eslint/typescript-estree@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.32.0" dependencies: - "@typescript-eslint/types": "npm:8.19.0" - "@typescript-eslint/visitor-keys": "npm:8.19.0" + "@typescript-eslint/types": "npm:8.32.0" + "@typescript-eslint/visitor-keys": "npm:8.32.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/ff47004588e8ff585af740b3e0bda07dc52310dbfeb2317eb4a723935740cf0c1953fc9ba57f14cf192bcfe373c46be833ba29d3303df8b501181bb852c7b822 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/c366a457b544c52cb26ffe3e07ed9d3c6eea9fa8a181c2fdba9a0d2076e5d3198dedfb8510038b0791bd338773d8c8d2af048b7c69999d3fd8540ef790dbc720 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/utils@npm:8.19.0" +"@typescript-eslint/utils@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/utils@npm:8.32.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.19.0" - "@typescript-eslint/types": "npm:8.19.0" - "@typescript-eslint/typescript-estree": "npm:8.19.0" + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.32.0" + "@typescript-eslint/types": "npm:8.32.0" + "@typescript-eslint/typescript-estree": "npm:8.32.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/7731f7fb66d54491769ca68fd04728138ceb6b785778ad491f8e9b2147802fa0ff480e520f6ea5fb73c8484d13a2ed3e35d44635f5bf4cfbdb04c313154097a9 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/b5b65555b98c8fc92ec016ce2329f644b4d09def28c36422ce77aad9eda1b4dae009bf97b684357e97dd15de66dddba7d8d86e426e11123dae80f7ca2b4f9bd4 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.19.0": - version: 8.19.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.19.0" +"@typescript-eslint/visitor-keys@npm:8.32.0": + version: 8.32.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.32.0" dependencies: - "@typescript-eslint/types": "npm:8.19.0" + "@typescript-eslint/types": "npm:8.32.0" eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/a293def05018bb2259506e23cd8f14349f4386d0e51231893fbddf96ef73c219d5f9fe17b82e3c104f5c23956dbd9b87af3cff5e84b887af243139a3b4bbbe0d + checksum: 10c0/f2e5254d9b1d00cd6360e27240ad72fbab7bcbaed46944943ff077e12fe4883790571f3734f8cb12c3e278bfd7bc4f8f7192ed899f341c282269a9dd16f0cba0 languageName: node linkType: hard @@ -12186,7 +12186,7 @@ __metadata: "@react-native-community/cli": "npm:^15.0.1" "@react-native-community/template": "npm:^0.78.0" "@rnx-kit/eslint-plugin": "npm:^0.8.0" - "@rnx-kit/react-native-host": "npm:^0.5.7" + "@rnx-kit/react-native-host": "npm:^0.5.8" "@rnx-kit/tools-react-native": "npm:^2.1.0" "@rnx-kit/tsconfig": "npm:^2.0.0" "@types/js-yaml": "npm:^4.0.5" @@ -14188,12 +14188,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" peerDependencies: - typescript: ">=4.2.0" - checksum: 10c0/f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c + typescript: ">=4.8.4" + checksum: 10c0/9806a38adea2db0f6aa217ccc6bc9c391ddba338a9fe3080676d0d50ed806d305bb90e8cef0276e793d28c8a929f400abb184ddd7ff83a416959c0f4d2ce754f languageName: node linkType: hard @@ -14344,16 +14344,16 @@ __metadata: linkType: hard "typescript-eslint@npm:^8.0.0": - version: 8.19.0 - resolution: "typescript-eslint@npm:8.19.0" + version: 8.32.0 + resolution: "typescript-eslint@npm:8.32.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.19.0" - "@typescript-eslint/parser": "npm:8.19.0" - "@typescript-eslint/utils": "npm:8.19.0" + "@typescript-eslint/eslint-plugin": "npm:8.32.0" + "@typescript-eslint/parser": "npm:8.32.0" + "@typescript-eslint/utils": "npm:8.32.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/87da630f50025b3ae943eac521809fef41ba4013b5c4206865c115b728684caa7b4c36ee561dd95af7eb4dc18ec1265b165b49d2db54e3d8fba0152bcb6c82f8 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/f74c2a3defec95f5f6d0887a9c57ad4f38d62fabe4e4a5a83bf6e198832efb6d706d08c89002f7765c3438e41f4c71d4a4694918056aa3a50b7b786569298fe4 languageName: node linkType: hard From bf25d3972bbe2184d0ca7696801503baf6a1212b Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 6 May 2025 15:43:29 +0200 Subject: [PATCH 2/4] fixup! fix(apple): fix app autodetection in bridgeless mode --- ios/ReactTestApp/AppRegistryModule.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/ReactTestApp/AppRegistryModule.mm b/ios/ReactTestApp/AppRegistryModule.mm index 9ac84f86e..02046b600 100644 --- a/ios/ReactTestApp/AppRegistryModule.mm +++ b/ios/ReactTestApp/AppRegistryModule.mm @@ -16,8 +16,7 @@ - (void)invokeAsync:(std::function &&)func; void RTAPostDidRegisterAppsNotification(NSValue *value) { - Runtime *runtime = static_cast([value pointerValue]); - + auto runtime = static_cast([value pointerValue]); auto appKeys = ReactTestApp::GetAppKeys(*runtime); if (appKeys.empty()) { return; From d50dcf793516b1eb57fcd767de596adaa5824d49 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 6 May 2025 16:03:48 +0200 Subject: [PATCH 3/4] remove legacy native module --- ios/ReactTestApp/AppRegistryModule.h | 5 ---- ios/ReactTestApp/AppRegistryModule.mm | 25 +------------------ .../Public/ReactTestApp-DevSupport.h | 1 + ios/ReactTestApp/ReactInstance.swift | 4 +++ 4 files changed, 6 insertions(+), 29 deletions(-) diff --git a/ios/ReactTestApp/AppRegistryModule.h b/ios/ReactTestApp/AppRegistryModule.h index c2499ebf5..0b8c4b8fb 100644 --- a/ios/ReactTestApp/AppRegistryModule.h +++ b/ios/ReactTestApp/AppRegistryModule.h @@ -1,6 +1 @@ #import - -#import - -@interface RTAAppRegistryModule : NSObject -@end diff --git a/ios/ReactTestApp/AppRegistryModule.mm b/ios/ReactTestApp/AppRegistryModule.mm index 02046b600..35cb52edf 100644 --- a/ios/ReactTestApp/AppRegistryModule.mm +++ b/ios/ReactTestApp/AppRegistryModule.mm @@ -32,29 +32,8 @@ void RTAPostDidRegisterAppsNotification(NSValue *value) userInfo:@{@"appKeys": [array copy]}]; } -@implementation RTAAppRegistryModule - -RCT_EXPORT_MODULE(); - -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -- (instancetype)init +void RTAPostDidRegisterAppsNotificationWithBridge(id bridge) { - if (self = [super init]) { - [NSNotificationCenter.defaultCenter addObserver:self - selector:@selector(javascriptDidLoadNotification:) - name:RCTJavaScriptDidLoadNotification - object:nil]; - } - return self; -} - -- (void)javascriptDidLoadNotification:(NSNotification *)note -{ - id bridge = note.userInfo[@"bridge"]; if (![bridge isKindOfClass:[RCTCxxBridge class]] || ![bridge respondsToSelector:@selector(runtime)] || ![bridge respondsToSelector:@selector(invokeAsync:)]) { @@ -71,5 +50,3 @@ - (void)javascriptDidLoadNotification:(NSNotification *)note RTAPostDidRegisterAppsNotification([NSValue valueWithPointer:runtime]); }]; } - -@end diff --git a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h index f080a7830..7213ac5a2 100644 --- a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h +++ b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h @@ -23,5 +23,6 @@ OBJC_EXTERN NSNotificationName const ReactTestAppSceneDidOpenURLNotification OBJC_EXTERN NSNotificationName const ReactInstanceDidLoadBundle; OBJC_EXTERN void RTAPostDidRegisterAppsNotification(NSValue *runtime); +OBJC_EXTERN void RTAPostDidRegisterAppsNotificationWithBridge(id bridge); NS_ASSUME_NONNULL_END diff --git a/ios/ReactTestApp/ReactInstance.swift b/ios/ReactTestApp/ReactInstance.swift index 0b824d25e..ddbe75101 100644 --- a/ios/ReactTestApp/ReactInstance.swift +++ b/ios/ReactTestApp/ReactInstance.swift @@ -218,6 +218,10 @@ final class ReactInstance: NSObject, RNXHostConfig { }) #endif } + + if let bridge = notification.userInfo?["bridge"] { + RTAPostDidRegisterAppsNotificationWithBridge(bridge) + } } @objc From a63bf21cc444983e39728bf6bbd07875530916da Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 6 May 2025 17:22:25 +0200 Subject: [PATCH 4/4] `.ReactAppDidInitialize` -> `.ReactAppDidFinishLaunching` --- example/ios/ExampleTests/DevSupportTests.m | 2 +- ios/ReactTestApp/AppDelegate.swift | 2 +- ios/ReactTestApp/Public/ReactTestApp-DevSupport.h | 9 ++++++--- ios/ReactTestApp/ReactTestApp-DevSupport.m | 11 ++++++++--- macos/ReactTestApp/AppDelegate.swift | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/example/ios/ExampleTests/DevSupportTests.m b/example/ios/ExampleTests/DevSupportTests.m index a53f34aac..0ab9b7110 100644 --- a/example/ios/ExampleTests/DevSupportTests.m +++ b/example/ios/ExampleTests/DevSupportTests.m @@ -9,7 +9,7 @@ @implementation DevSupportTests - (void)testDevSupportIsLinked { - XCTAssertNotNil(ReactAppDidInitializeNotification); + XCTAssertNotNil(ReactAppDidFinishLaunchingNotification); XCTAssertNotNil(ReactAppWillInitializeReactNativeNotification); XCTAssertNotNil(ReactAppDidInitializeReactNativeNotification); XCTAssertNotNil(ReactAppSceneDidOpenURLNotification); diff --git a/ios/ReactTestApp/AppDelegate.swift b/ios/ReactTestApp/AppDelegate.swift index d010c3c2b..c64406e1f 100644 --- a/ios/ReactTestApp/AppDelegate.swift +++ b/ios/ReactTestApp/AppDelegate.swift @@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { defer { NotificationCenter.default.post( - name: .ReactAppDidInitialize, + name: .ReactAppDidFinishLaunching, object: nil ) } diff --git a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h index 7213ac5a2..8983dfdcf 100644 --- a/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h +++ b/ios/ReactTestApp/Public/ReactTestApp-DevSupport.h @@ -2,15 +2,18 @@ NS_ASSUME_NONNULL_BEGIN -OBJC_EXTERN NSNotificationName const ReactAppDidInitializeNotification; +OBJC_EXTERN NSNotificationName const ReactAppDidFinishLaunchingNotification; + OBJC_EXTERN NSNotificationName const ReactAppWillInitializeReactNativeNotification; OBJC_EXTERN NSNotificationName const ReactAppDidInitializeReactNativeNotification; -OBJC_EXTERN NSNotificationName const ReactAppDidRegisterAppsNotification; + OBJC_EXTERN NSNotificationName const ReactAppRuntimeReady; +OBJC_EXTERN NSNotificationName const ReactAppDidRegisterAppsNotification; + OBJC_EXTERN NSNotificationName const ReactAppSceneDidOpenURLNotification; OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeNotification - __deprecated_msg("Use 'ReactAppDidInitializeNotification' instead"); + __deprecated_msg("Use 'ReactAppDidFinishLaunchingNotification' instead"); OBJC_EXTERN NSNotificationName const ReactTestAppWillInitializeReactNativeNotification __deprecated_msg("Use 'ReactAppWillInitializeReactNativeNotification' instead"); OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeReactNativeNotification diff --git a/ios/ReactTestApp/ReactTestApp-DevSupport.m b/ios/ReactTestApp/ReactTestApp-DevSupport.m index b672f4fe6..028d5cb75 100644 --- a/ios/ReactTestApp/ReactTestApp-DevSupport.m +++ b/ios/ReactTestApp/ReactTestApp-DevSupport.m @@ -1,17 +1,22 @@ #import -NSNotificationName const ReactAppDidInitializeNotification = @"ReactAppDidInitializeNotification"; +NSNotificationName const ReactAppDidFinishLaunchingNotification = + @"ReactAppDidFinishLaunchNotification"; + NSNotificationName const ReactAppWillInitializeReactNativeNotification = @"ReactAppWillInitializeReactNativeNotification"; NSNotificationName const ReactAppDidInitializeReactNativeNotification = @"ReactAppDidInitializeReactNativeNotification"; + +NSNotificationName const ReactAppRuntimeReady = @"ReactAppRuntimeReady"; NSNotificationName const ReactAppDidRegisterAppsNotification = @"ReactAppDidRegisterAppsNotification"; -NSNotificationName const ReactAppRuntimeReady = @"ReactAppRuntimeReady"; + NSNotificationName const ReactAppSceneDidOpenURLNotification = @"ReactAppSceneDidOpenURLNotification"; -NSNotificationName const ReactTestAppDidInitializeNotification = ReactAppDidInitializeNotification; +NSNotificationName const ReactTestAppDidInitializeNotification = + ReactAppDidFinishLaunchingNotification; NSNotificationName const ReactTestAppWillInitializeReactNativeNotification = ReactAppWillInitializeReactNativeNotification; NSNotificationName const ReactTestAppDidInitializeReactNativeNotification = diff --git a/macos/ReactTestApp/AppDelegate.swift b/macos/ReactTestApp/AppDelegate.swift index e1a265bca..f15938601 100644 --- a/macos/ReactTestApp/AppDelegate.swift +++ b/macos/ReactTestApp/AppDelegate.swift @@ -23,7 +23,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_: Notification) { NotificationCenter.default.post( - name: .ReactAppDidInitialize, + name: .ReactAppDidFinishLaunching, object: nil )