Skip to content

Commit ac17b82

Browse files
committed
fix(apple): fix app autodetection in bridgeless mode
1 parent 337b6be commit ac17b82

File tree

8 files changed

+113
-53
lines changed

8 files changed

+113
-53
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

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+
extern NSNotificationName const ReactAppDidInitializeNotification;
6+
extern NSNotificationName const ReactAppWillInitializeReactNativeNotification;
7+
extern NSNotificationName const ReactAppDidInitializeReactNativeNotification;
8+
extern NSNotificationName const ReactAppDidRegisterAppsNotification;
9+
extern NSNotificationName const ReactAppRuntimeReady;
10+
extern NSNotificationName const ReactAppSceneDidOpenURLNotification;
611

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

1323
extern NSNotificationName const ReactInstanceDidLoadBundle;
1424

25+
OBJC_EXTERN void RTAPostDidRegisterAppsNotification(NSValue *runtime);
26+
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 notificationCenter = NotificationCenter.default;
41+
4042
// Bridged
41-
NotificationCenter.default.addObserver(
43+
notificationCenter.addObserver(
4244
self,
4345
selector: #selector(onJavaScriptLoaded(_:)),
4446
name: .RCTJavaScriptDidLoad,
4547
object: nil
4648
)
4749

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

58+
notificationCenter.addObserver(
59+
self,
60+
selector: #selector(onRuntimeReady(_:)),
61+
name: .ReactAppRuntimeReady,
62+
object: nil
63+
)
64+
5665
#if os(iOS)
57-
NotificationCenter.default.addObserver(
66+
notificationCenter.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)
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
#import <Foundation/Foundation.h>
22

3-
NSNotificationName const ReactTestAppDidInitializeNotification =
4-
@"ReactTestAppDidInitializeNotification";
3+
NSNotificationName const ReactAppDidInitializeNotification = @"ReactAppDidInitializeNotification";
4+
NSNotificationName const ReactAppWillInitializeReactNativeNotification =
5+
@"ReactAppWillInitializeReactNativeNotification";
6+
NSNotificationName const ReactAppDidInitializeReactNativeNotification =
7+
@"ReactAppDidInitializeReactNativeNotification";
8+
NSNotificationName const ReactAppDidRegisterAppsNotification =
9+
@"ReactAppDidRegisterAppsNotification";
10+
NSNotificationName const ReactAppRuntimeReady = @"ReactAppRuntimeReady";
11+
NSNotificationName const ReactAppSceneDidOpenURLNotification =
12+
@"ReactAppSceneDidOpenURLNotification";
513

14+
NSNotificationName const ReactTestAppDidInitializeNotification =
15+
@"ReactAppDidInitializeNotification";
616
NSNotificationName const ReactTestAppWillInitializeReactNativeNotification =
7-
@"ReactTestAppWillInitializeReactNativeNotification";
17+
@"ReactAppWillInitializeReactNativeNotification";
818
NSNotificationName const ReactTestAppDidInitializeReactNativeNotification =
9-
@"ReactTestAppDidInitializeReactNativeNotification";
19+
@"ReactAppDidInitializeReactNativeNotification";
1020
NSNotificationName const ReactTestAppDidRegisterAppsNotification =
11-
@"ReactTestAppDidRegisterAppsNotification";
12-
21+
@"ReactAppDidRegisterAppsNotification";
1322
NSNotificationName const ReactTestAppSceneDidOpenURLNotification =
14-
@"ReactTestAppSceneDidOpenURLNotification";
23+
@"ReactAppSceneDidOpenURLNotification";
1524

1625
// https://github.com/facebook/react-native/blob/v0.73.4/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm#L448
1726
NSNotificationName const ReactInstanceDidLoadBundle = @"RCTInstanceDidLoadBundle";

ios/ReactTestApp/SceneDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
5050
}
5151

5252
NotificationCenter.default.post(
53-
name: .ReactTestAppSceneDidOpenURL,
53+
name: .ReactAppSceneDidOpenURL,
5454
object: [
5555
"scene": scene,
5656
"URLContexts": URLContexts,

0 commit comments

Comments
 (0)