Added support for synchronous methods in native modules on iOS

Reviewed By: javache

Differential Revision: D4947556

fbshipit-source-id: 0ef73dc5d741201e59fef1fc048809afc65c75b5
This commit is contained in:
Alex Dvornikov
2017-04-27 11:49:49 -07:00
committed by Facebook Github Bot
parent 2d3a272e0e
commit db0c22192c
9 changed files with 134 additions and 67 deletions

View File

@@ -26,6 +26,7 @@ class RCTNativeModule : public NativeModule {
private:
__weak RCTBridge *m_bridge;
RCTModuleData *m_moduleData;
MethodCallResult invokeInner(unsigned int methodId, const folly::dynamic &&params);
};
}

View File

@@ -34,7 +34,7 @@ std::vector<MethodDescriptor> RCTNativeModule::getMethods() {
for (id<RCTBridgeMethod> method in m_moduleData.methods) {
descs.emplace_back(
method.JSMethodName.UTF8String,
method.functionType == RCTFunctionTypePromise ? "promise" : "async"
RCTFunctionDescriptorFromType(method.functionType)
);
}
@@ -54,40 +54,12 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params) {
// The BatchedBridge version of this buckets all the callbacks by thread, and
// queues one block on each. This is much simpler; we'll see how it goes and
// iterate.
// There is no flow event handling here until I can understand it.
auto sparams = std::make_shared<folly::dynamic>(std::move(params));
__weak RCTBridge *bridge = m_bridge;
dispatch_block_t block = ^{
if (!bridge || !bridge.valid) {
dispatch_block_t block = [this, methodId, params=std::move(params)] {
if (!m_bridge.valid) {
return;
}
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
if (RCT_DEBUG && !method) {
RCTLogError(@"Unknown methodID: %ud for module: %@",
methodId, m_moduleData.name);
}
NSArray *objcParams = convertFollyDynamicToId(*sparams);
@try {
[method invokeWithBridge:bridge module:m_moduleData.instance arguments:objcParams];
}
@catch (NSException *exception) {
// Pass on JS exceptions
if ([exception.name hasPrefix:RCTFatalExceptionName]) {
@throw exception;
}
NSString *message = [NSString stringWithFormat:
@"Exception '%@' was thrown while invoking %@ on target %@ with params %@",
exception, method.JSMethodName, m_moduleData.name, objcParams];
RCTFatal(RCTErrorWithMessage(message));
}
invokeInner(methodId, std::move(params));
};
dispatch_queue_t queue = m_moduleData.methodQueue;
@@ -100,10 +72,35 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params) {
}
MethodCallResult RCTNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic &&params) {
RCTFatal(RCTErrorWithMessage(@"callSerializableNativeHook is not yet supported on iOS"));
return folly::none;
return invokeInner(reactMethodId, std::move(params));
}
MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly::dynamic &&params) {
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
if (RCT_DEBUG && !method) {
RCTLogError(@"Unknown methodID: %ud for module: %@",
methodId, m_moduleData.name);
}
NSArray *objcParams = convertFollyDynamicToId(params);
@try {
id result = [method invokeWithBridge:m_bridge module:m_moduleData.instance arguments:objcParams];
return convertIdToFollyDynamic(result);
}
@catch (NSException *exception) {
// Pass on JS exceptions
if ([exception.name hasPrefix:RCTFatalExceptionName]) {
@throw exception;
}
NSString *message = [NSString stringWithFormat:
@"Exception '%@' was thrown while invoking %@ on target %@ with params %@",
exception, method.JSMethodName, m_moduleData.name, objcParams];
RCTFatal(RCTErrorWithMessage(message));
}
}
}
}