Skip to content

Commit

Permalink
Support the new React Native C++ bridge (#1065)
Browse files Browse the repository at this point in the history
* Support the new React Native C++ bridge

Fixes #1049

* address code review comments

* handle the case when the websocket executor does not exist
  • Loading branch information
fealebenpae authored Jun 14, 2017
1 parent af72770 commit 237e1ba
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 17 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
vNext Release notes (TBD)
=============================================================
### Breaking changes
* None

### Enhancements
* None

### Bug fixes
* Fix crash when used with the React Native C++ bridge

1.3.1 Release notes (2017-5-18)
=============================================================
### Breaking changes
Expand Down
62 changes: 45 additions & 17 deletions react-native/ios/RealmReact/RealmReact.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ - (instancetype)initWithJSContext:(JSContext *)context onThread:(NSThread *)thre
- (JSContext *)context;
@end

// the part of the RCTCxxBridge private class we care about
@interface RCTBridge (RCTCxxBridge)
- (JSGlobalContextRef)jsContextRef;
- (void)executeBlockOnJavaScriptThread:(dispatch_block_t)block;
@end

extern "C" JSGlobalContextRef RealmReactGetJSGlobalContextForExecutor(id executor, bool create) {
Ivar contextIvar = class_getInstanceVariable([executor class], "_context");
if (!contextIvar) {
Expand Down Expand Up @@ -265,23 +271,54 @@ - (void)dealloc {
[self performSelectorOnMainThread:@selector(invalidate) withObject:nil waitUntilDone:YES];
}

typedef JSGlobalContextRef (^JSContextRefExtractor)();

void _initializeOnJSThread(JSContextRefExtractor jsContextExtractor) {
// Make sure the previous JS thread is completely finished before continuing.
static __weak NSThread *s_currentJSThread;
while (s_currentJSThread && !s_currentJSThread.finished) {
[NSThread sleepForTimeInterval:0.1];
}
s_currentJSThread = [NSThread currentThread];

// Close all cached Realms from the previous JS thread.
realm::_impl::RealmCoordinator::clear_all_caches();

RJSInitializeInContext(jsContextExtractor());
}

- (void)setBridge:(RCTBridge *)bridge {
_bridge = bridge;

static __weak RealmReact *s_currentModule = nil;
[s_currentModule invalidate];
s_currentModule = self;

id<RCTJavaScriptExecutor> executor = [bridge valueForKey:@"javaScriptExecutor"];

if ([executor isKindOfClass:NSClassFromString(@"RCTWebSocketExecutor")]) {
if (objc_lookUpClass("RCTWebSocketExecutor") && [bridge executorClass] == objc_lookUpClass("RCTWebSocketExecutor")) {
#if DEBUG
[self startRPC];
#else
@throw [NSException exceptionWithName:@"Invalid Executor" reason:@"Chrome debug mode not supported in Release builds" userInfo:nil];
#endif
}
else {
} else if ([bridge isKindOfClass:objc_lookUpClass("RCTCxxBridge")]) {
// probe for the new C++ bridge in React Native 0.45+

__weak __typeof__(self) weakSelf = self;
__weak __typeof__(bridge) weakBridge = bridge;
[bridge executeBlockOnJavaScriptThread:^{
__typeof__(self) self = weakSelf;
__typeof__(bridge) bridge = weakBridge;
if (!self || !bridge) {
return;
}

_initializeOnJSThread(^{
return [bridge jsContextRef];
});
}];
return;
} else { // React Native 0.44 and older
id<RCTJavaScriptExecutor> executor = [bridge valueForKey:@"javaScriptExecutor"];
__weak __typeof__(self) weakSelf = self;
__weak __typeof__(executor) weakExecutor = executor;

Expand All @@ -292,18 +329,9 @@ - (void)setBridge:(RCTBridge *)bridge {
return;
}

// Make sure the previous JS thread is completely finished before continuing.
static __weak NSThread *s_currentJSThread;
while (s_currentJSThread && !s_currentJSThread.finished) {
[NSThread sleepForTimeInterval:0.1];
}
s_currentJSThread = [NSThread currentThread];

// Close all cached Realms from the previous JS thread.
realm::_impl::RealmCoordinator::clear_all_caches();

JSGlobalContextRef ctx = RealmReactGetJSGlobalContextForExecutor(executor, true);
RJSInitializeInContext(ctx);
_initializeOnJSThread(^ {
return RealmReactGetJSGlobalContextForExecutor(executor, true);
});
}];
}
}
Expand Down

0 comments on commit 237e1ba

Please sign in to comment.