Summary: as discussed in https://github.com/facebook/flipper/issues/976#issuecomment-634917766, this solves the issue that FlipperKit is accidentally included in production builds ones react-native-flipper is installed, due to it's dependency on Flipper kit This change is safe because the bindings did already have a check to verify that the Flipper bindings are available at all, and silenty skips their absence in production builds: https://www.internalfb.com/intern/diffusion/FBS/browse/master/xplat/sonar/react-native/react-native-flipper/index.js?commit=b7dd7e05b177&lines=128 Reviewed By: passy Differential Revision: D21749213 fbshipit-source-id: 2c4435c7a375fbc24f89159855d3e0297f3aa9a4
154 lines
4.7 KiB
Objective-C
154 lines
4.7 KiB
Objective-C
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
|
|
#import "FlipperReactNativeJavaScriptPluginManager.h"
|
|
#import <FlipperKit/FlipperClient.h>
|
|
#import <FlipperKit/FlipperPlugin.h>
|
|
#import <React/RCTUtils.h>
|
|
#import "FlipperModule.h"
|
|
#import "FlipperReactNativeJavaScriptPlugin.h"
|
|
|
|
static uint32_t FlipperResponderKeyGenerator = 0;
|
|
|
|
@implementation FlipperReactNativeJavaScriptPluginManager {
|
|
__weak FlipperClient* _flipperClient;
|
|
NSMutableDictionary<NSString*, id<FlipperResponder>>* _responders;
|
|
}
|
|
|
|
+ (instancetype)sharedInstance {
|
|
static FlipperReactNativeJavaScriptPluginManager* sharedInstance = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
sharedInstance = [self new];
|
|
});
|
|
return sharedInstance;
|
|
}
|
|
|
|
- (instancetype)init {
|
|
if (self = [super init]) {
|
|
_flipperClient = [FlipperClient sharedClient];
|
|
_responders = [NSMutableDictionary new];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)registerPluginWithModule:(FlipperModule*)module
|
|
pluginId:(NSString*)pluginId
|
|
inBackground:(BOOL)inBackground
|
|
statusCallback:(RCTResponseSenderBlock)statusCallback {
|
|
if (_flipperClient == nil) {
|
|
// Flipper is not available in this build
|
|
statusCallback(@[ @"noflipper" ]);
|
|
return;
|
|
}
|
|
|
|
FlipperReactNativeJavaScriptPlugin* existingPlugin =
|
|
[self jsPluginWithIdentifier:pluginId];
|
|
if (existingPlugin != nil) {
|
|
existingPlugin.module = module;
|
|
|
|
if (existingPlugin.isConnected) {
|
|
[existingPlugin fireOnConnect];
|
|
}
|
|
|
|
statusCallback(@[ @"ok" ]);
|
|
return;
|
|
}
|
|
|
|
FlipperReactNativeJavaScriptPlugin* newPlugin =
|
|
[[FlipperReactNativeJavaScriptPlugin alloc]
|
|
initWithFlipperModule:module
|
|
pluginId:pluginId
|
|
inBackground:inBackground];
|
|
[_flipperClient addPlugin:newPlugin];
|
|
statusCallback(@[ @"ok" ]);
|
|
}
|
|
|
|
- (void)sendWithPluginId:(NSString*)pluginId
|
|
method:(NSString*)method
|
|
data:(NSString*)data {
|
|
[[self jsPluginWithIdentifier:pluginId].connection
|
|
send:method
|
|
withParams:RCTJSONParse(data, NULL)];
|
|
}
|
|
|
|
- (void)reportErrorWithMetadata:(NSString*)reason
|
|
stackTrace:(NSString*)stackTrace
|
|
pluginId:(NSString*)pluginId {
|
|
[[self jsPluginWithIdentifier:pluginId].connection
|
|
errorWithMessage:reason
|
|
stackTrace:stackTrace];
|
|
}
|
|
|
|
- (void)reportError:(NSString*)error pluginId:(NSString*)pluginId {
|
|
// Stacktrace
|
|
NSMutableArray<NSString*>* callstack = NSThread.callStackSymbols.mutableCopy;
|
|
NSMutableString* callstackString = callstack.firstObject.mutableCopy;
|
|
[callstack removeObject:callstack.firstObject];
|
|
for (NSString* stack in callstack) {
|
|
[callstackString appendFormat:@"\n %@", stack];
|
|
}
|
|
|
|
[[self jsPluginWithIdentifier:pluginId].connection
|
|
errorWithMessage:error
|
|
stackTrace:callstackString];
|
|
}
|
|
|
|
- (void)subscribeWithModule:(FlipperModule*)module
|
|
pluginId:(NSString*)pluginId
|
|
method:(NSString*)method {
|
|
__weak __typeof(self) weakSelf = self;
|
|
[[self jsPluginWithIdentifier:pluginId].connection
|
|
receive:method
|
|
withBlock:^(NSDictionary* params, id<FlipperResponder> responder) {
|
|
__typeof(self) strongSelf = weakSelf;
|
|
|
|
NSMutableDictionary* body =
|
|
[NSMutableDictionary dictionaryWithDictionary:@{
|
|
@"plugin" : pluginId,
|
|
@"method" : method,
|
|
@"params" : RCTJSONStringify(params, NULL),
|
|
}];
|
|
|
|
if (responder != nil) {
|
|
NSString* responderId =
|
|
[NSString stringWithFormat:@"%d", FlipperResponderKeyGenerator++];
|
|
strongSelf->_responders[responderId] = responder;
|
|
body[@"responderId"] = responderId;
|
|
}
|
|
|
|
[module sendEventWithName:@"react-native-flipper-receive-event"
|
|
body:body];
|
|
}];
|
|
}
|
|
|
|
- (void)respondSuccessWithResponderId:(NSString*)responderId
|
|
data:(NSString*)data {
|
|
id<FlipperResponder> responder = _responders[responderId];
|
|
[responder success:RCTJSONParse(data, NULL)];
|
|
[_responders removeObjectForKey:responderId];
|
|
}
|
|
|
|
- (void)respondErrorWithResponderId:(NSString*)responderId
|
|
data:(NSString*)data {
|
|
id<FlipperResponder> responder = _responders[responderId];
|
|
[responder error:RCTJSONParse(data, NULL)];
|
|
[_responders removeObjectForKey:responderId];
|
|
}
|
|
|
|
- (FlipperReactNativeJavaScriptPlugin*)jsPluginWithIdentifier:
|
|
(NSString*)pluginId {
|
|
return (FlipperReactNativeJavaScriptPlugin*)[_flipperClient
|
|
pluginWithIdentifier:pluginId];
|
|
}
|
|
|
|
@end
|
|
|
|
#endif
|