Skip to content

Commit b094686

Browse files
authored
fix(apple): fix app autodetection in bridgeless mode (#2464)
1 parent 9463a4d commit b094686

16 files changed

+213
-170
lines changed

common/AppRegistry.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,50 @@
33
#if __has_include(<jsi/jsi.h>)
44
#include <jsi/jsi.h>
55

6+
using facebook::jsi::Array;
67
using facebook::jsi::Runtime;
78
using facebook::jsi::String;
89

9-
std::vector<std::string> ReactTestApp::GetAppKeys(Runtime &runtime)
10+
namespace
1011
{
11-
std::vector<std::string> result;
12-
1312
constexpr char kFbBatchedBridgeId[] = "__fbBatchedBridge";
13+
constexpr char kRNAppRegistryId[] = "RN$AppRegistry";
14+
15+
Array GetRegisteredAppKeys(Runtime &runtime)
16+
{
17+
auto global = runtime.global();
18+
if (global.hasProperty(runtime, kRNAppRegistryId)) { // >= 0.73
19+
// const appKeys = RN$AppRegistry.getAppKeys();
20+
auto registry = global.getProperty(runtime, kRNAppRegistryId);
21+
if (registry.isObject()) {
22+
auto getAppKeys = std::move(registry).asObject(runtime).getPropertyAsFunction(
23+
runtime, "getAppKeys");
24+
return getAppKeys.call(runtime, nullptr, 0).asObject(runtime).asArray(runtime);
25+
}
26+
} else if (global.hasProperty(runtime, kFbBatchedBridgeId)) { // < 0.73
27+
// const appRegistry = __fbBatchedBridge.getCallableModule("AppRegistry");
28+
auto fbBatchedBridge = global.getPropertyAsObject(runtime, kFbBatchedBridgeId);
29+
auto getCallableModule =
30+
fbBatchedBridge.getPropertyAsFunction(runtime, "getCallableModule");
31+
auto appRegistry =
32+
getCallableModule.callWithThis(runtime, fbBatchedBridge, "AppRegistry")
33+
.asObject(runtime);
34+
35+
// const appKeys = appRegistry.getAppKeys();
36+
auto getAppKeys = appRegistry.getPropertyAsFunction(runtime, "getAppKeys");
37+
return getAppKeys.callWithThis(runtime, appRegistry).asObject(runtime).asArray(runtime);
38+
}
1439

15-
auto global = runtime.global();
16-
if (!global.hasProperty(runtime, kFbBatchedBridgeId)) {
17-
return result;
40+
return Array(runtime, 0);
1841
}
42+
} // namespace
1943

20-
try {
21-
// const appRegistry = __fbBatchedBridge.getCallableModule("AppRegistry");
22-
auto fbBatchedBridge = global.getPropertyAsObject(runtime, kFbBatchedBridgeId);
23-
auto getCallableModule =
24-
fbBatchedBridge.getPropertyAsFunction(runtime, "getCallableModule");
25-
auto appRegistry = getCallableModule.callWithThis(runtime, fbBatchedBridge, "AppRegistry")
26-
.asObject(runtime);
27-
28-
// const appKeys = appRegistry.getAppKeys();
29-
auto getAppKeys = appRegistry.getPropertyAsFunction(runtime, "getAppKeys");
30-
auto appKeys =
31-
getAppKeys.callWithThis(runtime, appRegistry).asObject(runtime).asArray(runtime);
44+
std::vector<std::string> ReactTestApp::GetAppKeys(Runtime &runtime)
45+
{
46+
std::vector<std::string> result;
3247

48+
try {
49+
auto appKeys = GetRegisteredAppKeys(runtime);
3350
auto length = appKeys.length(runtime);
3451
result.reserve(length);
3552

example/ios/ExampleTests/DevSupportTests.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ @implementation DevSupportTests
99

1010
- (void)testDevSupportIsLinked
1111
{
12-
XCTAssertNotNil(ReactTestAppDidInitializeNotification);
13-
XCTAssertNotNil(ReactTestAppWillInitializeReactNativeNotification);
14-
XCTAssertNotNil(ReactTestAppDidInitializeReactNativeNotification);
15-
XCTAssertNotNil(ReactTestAppSceneDidOpenURLNotification);
12+
XCTAssertNotNil(ReactAppDidFinishLaunchingNotification);
13+
XCTAssertNotNil(ReactAppWillInitializeReactNativeNotification);
14+
XCTAssertNotNil(ReactAppDidInitializeReactNativeNotification);
15+
XCTAssertNotNil(ReactAppSceneDidOpenURLNotification);
1616
}
1717

1818
@end

example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,7 +1482,7 @@ PODS:
14821482
- React-logger (= 0.78.2)
14831483
- React-perflogger (= 0.78.2)
14841484
- React-utils (= 0.78.2)
1485-
- ReactNativeHost (0.5.5):
1485+
- ReactNativeHost (0.5.8):
14861486
- DoubleConversion
14871487
- glog
14881488
- RCT-Folly (= 2024.11.18.00)
@@ -1814,7 +1814,7 @@ SPEC CHECKSUMS:
18141814
ReactAppDependencyProvider: 4893bde33952f997a323eb1a1ee87a72764018ff
18151815
ReactCodegen: a99d9f9129c83cdd5c58dea8826d1b82ec528b93
18161816
ReactCommon: 5008bd981a06fe63176ef815f092685ffee8f7eb
1817-
ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161
1817+
ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064
18181818
ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1
18191819
ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf
18201820
RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be

example/macos/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,7 +1483,7 @@ PODS:
14831483
- React-logger (= 0.78.3)
14841484
- React-perflogger (= 0.78.3)
14851485
- React-utils (= 0.78.3)
1486-
- ReactNativeHost (0.5.5):
1486+
- ReactNativeHost (0.5.8):
14871487
- DoubleConversion
14881488
- glog
14891489
- RCT-Folly (= 2024.11.18.00)
@@ -1814,7 +1814,7 @@ SPEC CHECKSUMS:
18141814
ReactAppDependencyProvider: a12262458b50521ba56afb93f4cc875732f9d643
18151815
ReactCodegen: 191e4a5cb0241651f2fcf21d79729c6465f0f905
18161816
ReactCommon: 0f22e3dd34a8215b8482778898f6e1e95572c498
1817-
ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161
1817+
ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064
18181818
ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1
18191819
ReactTestApp-Resources: 86136e1efe3aa7201759371c03dea3df77079b42
18201820
RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be

example/visionos/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,7 +1536,7 @@ PODS:
15361536
- React-logger (= 0.78.0)
15371537
- React-perflogger (= 0.78.0)
15381538
- React-utils (= 0.78.0)
1539-
- ReactNativeHost (0.5.5):
1539+
- ReactNativeHost (0.5.8):
15401540
- DoubleConversion
15411541
- glog
15421542
- RCT-Folly (= 2024.11.18.00)
@@ -1880,7 +1880,7 @@ SPEC CHECKSUMS:
18801880
ReactAppDependencyProvider: b0dbc9d44b4e45e2b2468df4a2f49fb51806224f
18811881
ReactCodegen: 4d719f75b156783b8fdf07fe4091a7f38bc52967
18821882
ReactCommon: a690d72c5df9a63d64a2444d5aad695c37554ea7
1883-
ReactNativeHost: 8bf59aebad1f1cdd377510f12172b4b9cdbb5161
1883+
ReactNativeHost: 9f5d82f9edc73c42ed09e949a19d2ef9cf5ac064
18841884
ReactTestApp-DevSupport: 2386e7c22084f8a550cfadcc0bde140c7dc328a1
18851885
ReactTestApp-Resources: 2ad57492ef72ab9b2c6f6e89ea198cc1999ca20b
18861886
RNWWebStorage: cf4c36a41d7d31734b1a3424c70cb555e86801be

ios/ReactTestApp/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3838

3939
defer {
4040
NotificationCenter.default.post(
41-
name: .ReactTestAppDidInitialize,
41+
name: .ReactAppDidFinishLaunching,
4242
object: nil
4343
)
4444
}

ios/ReactTestApp/AppRegistryModule.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
11
#import <Foundation/Foundation.h>
2-
3-
#import <React/RCTBridgeModule.h>
4-
5-
@interface RTAAppRegistryModule : NSObject <RCTBridgeModule>
6-
@end

ios/ReactTestApp/AppRegistryModule.mm

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,26 @@ @interface RCTCxxBridge : RCTBridge
1414
- (void)invokeAsync:(std::function<void()> &&)func;
1515
@end
1616

17-
@implementation RTAAppRegistryModule
18-
19-
RCT_EXPORT_MODULE();
20-
21-
+ (BOOL)requiresMainQueueSetup
17+
void RTAPostDidRegisterAppsNotification(NSValue *value)
2218
{
23-
return YES;
24-
}
19+
auto runtime = static_cast<Runtime *>([value pointerValue]);
20+
auto appKeys = ReactTestApp::GetAppKeys(*runtime);
21+
if (appKeys.empty()) {
22+
return;
23+
}
2524

26-
- (instancetype)init
27-
{
28-
if (self = [super init]) {
29-
[NSNotificationCenter.defaultCenter addObserver:self
30-
selector:@selector(javascriptDidLoadNotification:)
31-
name:RCTJavaScriptDidLoadNotification
32-
object:nil];
25+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:appKeys.size()];
26+
for (const auto &appKey : appKeys) {
27+
[array addObject:[NSString stringWithUTF8String:appKey.c_str()]];
3328
}
34-
return self;
29+
30+
[NSNotificationCenter.defaultCenter postNotificationName:ReactAppDidRegisterAppsNotification
31+
object:nil
32+
userInfo:@{@"appKeys": [array copy]}];
3533
}
3634

37-
- (void)javascriptDidLoadNotification:(NSNotification *)note
35+
void RTAPostDidRegisterAppsNotificationWithBridge(id bridge)
3836
{
39-
id bridge = note.userInfo[@"bridge"];
4037
if (![bridge isKindOfClass:[RCTCxxBridge class]] ||
4138
![bridge respondsToSelector:@selector(runtime)] ||
4239
![bridge respondsToSelector:@selector(invokeAsync:)]) {
@@ -50,21 +47,6 @@ - (void)javascriptDidLoadNotification:(NSNotification *)note
5047
return;
5148
}
5249

53-
auto appKeys = ReactTestApp::GetAppKeys(*runtime);
54-
if (appKeys.empty()) {
55-
return;
56-
}
57-
58-
NSMutableArray *array = [NSMutableArray arrayWithCapacity:appKeys.size()];
59-
for (const auto &appKey : appKeys) {
60-
[array addObject:[NSString stringWithUTF8String:appKey.c_str()]];
61-
}
62-
63-
[NSNotificationCenter.defaultCenter
64-
postNotificationName:ReactTestAppDidRegisterAppsNotification
65-
object:nil
66-
userInfo:@{@"appKeys": [array copy]}];
50+
RTAPostDidRegisterAppsNotification([NSValue valueWithPointer:runtime]);
6751
}];
6852
}
69-
70-
@end

ios/ReactTestApp/ContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ final class ContentViewController: UITableViewController {
9292
let components = manifest.components ?? []
9393
if components.isEmpty {
9494
NotificationCenter.default.addObserver(
95-
forName: .ReactTestAppDidRegisterApps,
95+
forName: .ReactAppDidRegisterApps,
9696
object: nil,
9797
queue: .main,
9898
using: { [weak self] note in

ios/ReactTestApp/Public/ReactTestApp-DevSupport.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,30 @@
22

33
NS_ASSUME_NONNULL_BEGIN
44

5-
extern NSNotificationName const ReactTestAppDidInitializeNotification;
5+
OBJC_EXTERN NSNotificationName const ReactAppDidFinishLaunchingNotification;
66

7-
extern NSNotificationName const ReactTestAppWillInitializeReactNativeNotification;
8-
extern NSNotificationName const ReactTestAppDidInitializeReactNativeNotification;
9-
extern NSNotificationName const ReactTestAppDidRegisterAppsNotification;
7+
OBJC_EXTERN NSNotificationName const ReactAppWillInitializeReactNativeNotification;
8+
OBJC_EXTERN NSNotificationName const ReactAppDidInitializeReactNativeNotification;
109

11-
extern NSNotificationName const ReactTestAppSceneDidOpenURLNotification;
10+
OBJC_EXTERN NSNotificationName const ReactAppRuntimeReady;
11+
OBJC_EXTERN NSNotificationName const ReactAppDidRegisterAppsNotification;
1212

13-
extern NSNotificationName const ReactInstanceDidLoadBundle;
13+
OBJC_EXTERN NSNotificationName const ReactAppSceneDidOpenURLNotification;
14+
15+
OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeNotification
16+
__deprecated_msg("Use 'ReactAppDidFinishLaunchingNotification' instead");
17+
OBJC_EXTERN NSNotificationName const ReactTestAppWillInitializeReactNativeNotification
18+
__deprecated_msg("Use 'ReactAppWillInitializeReactNativeNotification' instead");
19+
OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeReactNativeNotification
20+
__deprecated_msg("Use 'ReactAppDidInitializeReactNativeNotification' instead");
21+
OBJC_EXTERN NSNotificationName const ReactTestAppDidRegisterAppsNotification
22+
__deprecated_msg("Use 'ReactAppDidRegisterAppsNotification' instead");
23+
OBJC_EXTERN NSNotificationName const ReactTestAppSceneDidOpenURLNotification
24+
__deprecated_msg("Use 'ReactAppSceneDidOpenURLNotification' instead");
25+
26+
OBJC_EXTERN NSNotificationName const ReactInstanceDidLoadBundle;
27+
28+
OBJC_EXTERN void RTAPostDidRegisterAppsNotification(NSValue *runtime);
29+
OBJC_EXTERN void RTAPostDidRegisterAppsNotificationWithBridge(id bridge);
1430

1531
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)