Skip to content

Commit b08d8c7

Browse files
committed
fix(apple): fix app autodetection in bridgeless mode
1 parent 9463a4d commit b08d8c7

File tree

15 files changed

+205
-146
lines changed

15 files changed

+205
-146
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(ReactAppDidInitializeNotification);
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: .ReactAppDidInitialize,
4242
object: nil
4343
)
4444
}

ios/ReactTestApp/AppRegistryModule.mm

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

17+
void RTAPostDidRegisterAppsNotification(NSValue *value)
18+
{
19+
Runtime *runtime = static_cast<Runtime *>([value pointerValue]);
20+
21+
auto appKeys = ReactTestApp::GetAppKeys(*runtime);
22+
if (appKeys.empty()) {
23+
return;
24+
}
25+
26+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:appKeys.size()];
27+
for (const auto &appKey : appKeys) {
28+
[array addObject:[NSString stringWithUTF8String:appKey.c_str()]];
29+
}
30+
31+
[NSNotificationCenter.defaultCenter postNotificationName:ReactAppDidRegisterAppsNotification
32+
object:nil
33+
userInfo:@{@"appKeys": [array copy]}];
34+
}
35+
1736
@implementation RTAAppRegistryModule
1837

1938
RCT_EXPORT_MODULE();
@@ -50,20 +69,7 @@ - (void)javascriptDidLoadNotification:(NSNotification *)note
5069
return;
5170
}
5271

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]}];
72+
RTAPostDidRegisterAppsNotification([NSValue valueWithPointer:runtime]);
6773
}];
6874
}
6975

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: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@
22

33
NS_ASSUME_NONNULL_BEGIN
44

5-
extern NSNotificationName const ReactTestAppDidInitializeNotification;
5+
OBJC_EXTERN NSNotificationName const ReactAppDidInitializeNotification;
6+
OBJC_EXTERN NSNotificationName const ReactAppWillInitializeReactNativeNotification;
7+
OBJC_EXTERN NSNotificationName const ReactAppDidInitializeReactNativeNotification;
8+
OBJC_EXTERN NSNotificationName const ReactAppDidRegisterAppsNotification;
9+
OBJC_EXTERN NSNotificationName const ReactAppRuntimeReady;
10+
OBJC_EXTERN NSNotificationName const ReactAppSceneDidOpenURLNotification;
611

7-
extern NSNotificationName const ReactTestAppWillInitializeReactNativeNotification;
8-
extern NSNotificationName const ReactTestAppDidInitializeReactNativeNotification;
9-
extern NSNotificationName const ReactTestAppDidRegisterAppsNotification;
12+
OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeNotification
13+
__deprecated_msg("Use 'ReactAppDidInitializeNotification' instead");
14+
OBJC_EXTERN NSNotificationName const ReactTestAppWillInitializeReactNativeNotification
15+
__deprecated_msg("Use 'ReactAppWillInitializeReactNativeNotification' instead");
16+
OBJC_EXTERN NSNotificationName const ReactTestAppDidInitializeReactNativeNotification
17+
__deprecated_msg("Use 'ReactAppDidInitializeReactNativeNotification' instead");
18+
OBJC_EXTERN NSNotificationName const ReactTestAppDidRegisterAppsNotification
19+
__deprecated_msg("Use 'ReactAppDidRegisterAppsNotification' instead");
20+
OBJC_EXTERN NSNotificationName const ReactTestAppSceneDidOpenURLNotification
21+
__deprecated_msg("Use 'ReactAppSceneDidOpenURLNotification' instead");
1022

11-
extern NSNotificationName const ReactTestAppSceneDidOpenURLNotification;
23+
OBJC_EXTERN NSNotificationName const ReactInstanceDidLoadBundle;
1224

13-
extern NSNotificationName const ReactInstanceDidLoadBundle;
25+
OBJC_EXTERN void RTAPostDidRegisterAppsNotification(NSValue *runtime);
1426

1527
NS_ASSUME_NONNULL_END

ios/ReactTestApp/ReactInstance.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,33 @@ final class ReactInstance: NSObject, RNXHostConfig {
3737
override init() {
3838
super.init()
3939

40+
let defaultNotificationCenter = NotificationCenter.default
41+
4042
// Bridged
41-
NotificationCenter.default.addObserver(
43+
defaultNotificationCenter.addObserver(
4244
self,
4345
selector: #selector(onJavaScriptLoaded(_:)),
4446
name: .RCTJavaScriptDidLoad,
4547
object: nil
4648
)
4749

4850
// Bridgeless
49-
NotificationCenter.default.addObserver(
51+
defaultNotificationCenter.addObserver(
5052
self,
5153
selector: #selector(onJavaScriptLoaded(_:)),
5254
name: .ReactInstanceDidLoadBundle,
5355
object: nil
5456
)
5557

58+
defaultNotificationCenter.addObserver(
59+
self,
60+
selector: #selector(onRuntimeReady(_:)),
61+
name: .ReactAppRuntimeReady,
62+
object: nil
63+
)
64+
5665
#if os(iOS)
57-
NotificationCenter.default.addObserver(
66+
defaultNotificationCenter.addObserver(
5867
self,
5968
selector: #selector(onRemoteBundleURLReceived(_:)),
6069
name: .didReceiveRemoteBundleURL,
@@ -90,15 +99,15 @@ final class ReactInstance: NSObject, RNXHostConfig {
9099
self.bundleRoot = bundleRoot
91100

92101
NotificationCenter.default.post(
93-
name: .ReactTestAppWillInitializeReactNative,
102+
name: .ReactAppWillInitializeReactNative,
94103
object: nil
95104
)
96105

97106
let reactNativeHost = ReactNativeHost(self)
98107
host = reactNativeHost
99108

100109
NotificationCenter.default.post(
101-
name: .ReactTestAppDidInitializeReactNative,
110+
name: .ReactAppDidInitializeReactNative,
102111
object: reactNativeHost
103112
)
104113

@@ -220,6 +229,13 @@ final class ReactInstance: NSObject, RNXHostConfig {
220229
urlComponents.queryItems = [URLQueryItem(name: "platform", value: "ios")]
221230
remoteBundleURL = urlComponents.url
222231
}
232+
233+
@objc
234+
private func onRuntimeReady(_ notification: Notification) {
235+
if let runtime = notification.userInfo?["runtime"] as? NSValue {
236+
RTAPostDidRegisterAppsNotification(runtime)
237+
}
238+
}
223239
}
224240

225241
#if canImport(UIKit)

0 commit comments

Comments
 (0)