[React Native] RCT_EXPORT lvl.2

This commit is contained in:
Alex Akers
2015-04-08 08:52:48 -07:00
parent 341d1a12bf
commit 8a57c4e980
29 changed files with 370 additions and 326 deletions

View File

@@ -72,7 +72,8 @@
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "YES"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable> <BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A" BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
@@ -90,7 +91,8 @@
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
buildConfiguration = "Release" buildConfiguration = "Release"
debugDocumentVersioning = "YES"> debugDocumentVersioning = "YES">
<BuildableProductRunnable> <BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A" BlueprintIdentifier = "13B07F861A680F5B00A75B9A"

View File

@@ -11,7 +11,7 @@
#import "RCTLog.h" #import "RCTLog.h"
@interface RCTActionSheetManager() <UIActionSheetDelegate> @interface RCTActionSheetManager () <UIActionSheetDelegate>
@end @end
@@ -30,12 +30,10 @@ RCT_EXPORT_MODULE()
return self; return self;
} }
- (void)showActionSheetWithOptions:(NSDictionary *)options RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
failureCallback:(RCTResponseSenderBlock)failureCallback failureCallback:(RCTResponseSenderBlock)failureCallback
successCallback:(RCTResponseSenderBlock)successCallback successCallback:(RCTResponseSenderBlock)successCallback)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
UIActionSheet *actionSheet = [[UIActionSheet alloc] init]; UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
@@ -65,12 +63,10 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)showShareActionSheetWithOptions:(NSDictionary *)options RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
failureCallback:(RCTResponseSenderBlock)failureCallback failureCallback:(RCTResponseSenderBlock)failureCallback
successCallback:(RCTResponseSenderBlock)successCallback successCallback:(RCTResponseSenderBlock)successCallback)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *items = [NSMutableArray array]; NSMutableArray *items = [NSMutableArray array];
id message = options[@"message"]; id message = options[@"message"];
@@ -137,7 +133,7 @@ RCT_EXPORT_MODULE()
#pragma mark Private #pragma mark Private
static NSString *keyForInstance(id instance) NS_INLINE NSString *keyForInstance(id instance)
{ {
return [NSString stringWithFormat:@"%p", instance]; return [NSString stringWithFormat:@"%p", instance];
} }

View File

@@ -13,10 +13,9 @@
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (void)getAdvertisingId:(RCTResponseSenderBlock)callback withErrorCallback:(RCTResponseSenderBlock)errorCallback RCT_EXPORT_METHOD(getAdvertisingId:(RCTResponseSenderBlock)callback
withErrorCallback:(RCTResponseSenderBlock)errorCallback)
{ {
RCT_EXPORT();
if ([ASIdentifierManager class]) { if ([ASIdentifierManager class]) {
callback(@[[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]]); callback(@[[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]]);
} else { } else {
@@ -24,12 +23,11 @@ RCT_EXPORT_MODULE()
} }
} }
- (void)getAdvertisingTrackingEnabled:(RCTResponseSenderBlock)callback withErrorCallback:(RCTResponseSenderBlock)errorCallback RCT_EXPORT_METHOD(getAdvertisingTrackingEnabled:(RCTResponseSenderBlock)callback
withErrorCallback:(RCTResponseSenderBlock)errorCallback)
{ {
RCT_EXPORT();
if ([ASIdentifierManager class]) { if ([ASIdentifierManager class]) {
bool hasTracking = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]; BOOL hasTracking = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
callback(@[@(hasTracking)]); callback(@[@(hasTracking)]);
} else { } else {
return errorCallback(@[@"as_identifier_unavailable"]); return errorCallback(@[@"as_identifier_unavailable"]);

View File

@@ -63,10 +63,13 @@ RCT_EXPORT_MODULE()
}; };
} }
- (void)startAnimationForTag:(NSNumber *)reactTag animationTag:(NSNumber *)animationTag duration:(double)duration delay:(double)delay easingSample:(NSArray *)easingSample properties:(NSDictionary *)properties RCT_EXPORT_METHOD(startAnimationForTag:(NSNumber *)reactTag
animationTag:(NSNumber *)animationTag
duration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
easingSample:(NSArray *)easingSample
properties:(NSDictionary *)properties)
{ {
RCT_EXPORT(startAnimation);
__weak RCTAnimationExperimentalManager *weakSelf = self; __weak RCTAnimationExperimentalManager *weakSelf = self;
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTAnimationExperimentalManager *strongSelf = weakSelf; RCTAnimationExperimentalManager *strongSelf = weakSelf;
@@ -165,8 +168,8 @@ RCT_EXPORT_MODULE()
} }
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:key]; CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:key];
animation.beginTime = CACurrentMediaTime() + delay / 1000.0; animation.beginTime = CACurrentMediaTime() + delay;
animation.duration = duration / 1000.0; animation.duration = duration;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.values = sampledValues; animation.values = sampledValues;
@@ -180,10 +183,8 @@ RCT_EXPORT_MODULE()
}]; }];
} }
- (void)stopAnimation:(NSNumber *)animationTag RCT_EXPORT_METHOD(stopAnimation:(NSNumber *)animationTag)
{ {
RCT_EXPORT(stopAnimation);
__weak RCTAnimationExperimentalManager *weakSelf = self; __weak RCTAnimationExperimentalManager *weakSelf = self;
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTAnimationExperimentalManager *strongSelf = weakSelf; RCTAnimationExperimentalManager *strongSelf = weakSelf;

View File

@@ -153,10 +153,8 @@ RCT_EXPORT_MODULE()
#pragma mark - Public API #pragma mark - Public API
- (void)startObserving:(NSDictionary *)optionsJSON RCT_EXPORT_METHOD(startObserving:(NSDictionary *)optionsJSON)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
// Select best options // Select best options
@@ -172,10 +170,8 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)stopObserving RCT_EXPORT_METHOD(stopObserving)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
// Stop observing // Stop observing
@@ -189,12 +185,10 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)getCurrentPosition:(NSDictionary *)optionsJSON RCT_EXPORT_METHOD(getCurrentPosition:(NSDictionary *)optionsJSON
withSuccessCallback:(RCTResponseSenderBlock)successBlock withSuccessCallback:(RCTResponseSenderBlock)successBlock
errorCallback:(RCTResponseSenderBlock)errorBlock errorCallback:(RCTResponseSenderBlock)errorBlock)
{ {
RCT_EXPORT();
if (!successBlock) { if (!successBlock) {
RCTLogError(@"%@.getCurrentPosition called with nil success parameter.", [self class]); RCTLogError(@"%@.getCurrentPosition called with nil success parameter.", [self class]);
return; return;

View File

@@ -14,17 +14,17 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "RCTImageLoader.h" #import "RCTImageLoader.h"
#import "RCTLog.h" #import "RCTLog.h"
@implementation RCTCameraRollManager @implementation RCTCameraRollManager
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (void)saveImageWithTag:(NSString *)imageTag successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseSenderBlock)errorCallback RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
successCallback:(RCTResponseSenderBlock)successCallback
errorCallback:(RCTResponseSenderBlock)errorCallback)
{ {
RCT_EXPORT();
[RCTImageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) { [RCTImageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) {
if (loadError) { if (loadError) {
errorCallback(@[[loadError localizedDescription]]); errorCallback(@[[loadError localizedDescription]]);
@@ -61,10 +61,10 @@ RCT_EXPORT_MODULE()
}]); }]);
} }
- (void)getPhotos:(NSDictionary *)params callback:(RCTResponseSenderBlock)callback errorCallback:(RCTResponseSenderBlock)errorCallback RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
callback:(RCTResponseSenderBlock)callback
errorCallback:(RCTResponseSenderBlock)errorCallback)
{ {
RCT_EXPORT();
NSUInteger first = [params[@"first"] integerValue]; NSUInteger first = [params[@"first"] integerValue];
NSString *afterCursor = params[@"after"]; NSString *afterCursor = params[@"after"];
NSString *groupTypesStr = params[@"groupTypes"]; NSString *groupTypesStr = params[@"groupTypes"];

View File

@@ -16,10 +16,10 @@ NSString *const RCTOpenURLNotification = @"RCTOpenURLNotification";
@implementation RCTLinkingManager @implementation RCTLinkingManager
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
- (instancetype)init - (instancetype)init
{ {
if ((self = [super init])) { if ((self = [super init])) {
@@ -54,19 +54,15 @@ RCT_EXPORT_MODULE()
body:[notification userInfo]]; body:[notification userInfo]];
} }
- (void)openURL:(NSString *)url RCT_EXPORT_METHOD(openURL:(NSURL *)url)
{ {
RCT_EXPORT(); [[UIApplication sharedApplication] openURL:url];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
} }
- (void)canOpenURL:(NSString *)url RCT_EXPORT_METHOD(canOpenURL:(NSURL *)url
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT(); BOOL supported = [[UIApplication sharedApplication] canOpenURL:url];
BOOL supported = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]];
callback(@[@(supported)]); callback(@[@(supported)]);
} }

View File

@@ -21,13 +21,11 @@ RCT_EXPORT_MODULE()
* Executes a network request. * Executes a network request.
* The responseSender block won't be called on same thread as called. * The responseSender block won't be called on same thread as called.
*/ */
- (void)executeQuery:(NSString *)queryType RCT_EXPORT_METHOD(queryData:(NSString *)queryType
query:(id)query withQuery:(id)query
queryHash:(__unused NSString *)queryHash queryHash:(__unused NSString *)queryHash
responseSender:(RCTResponseSenderBlock)responseSender responseSender:(RCTResponseSenderBlock)responseSender)
{ {
RCT_EXPORT(queryData);
if ([queryType isEqualToString:@"http"]) { if ([queryType isEqualToString:@"http"]) {
// Parse query // Parse query

View File

@@ -23,8 +23,6 @@ static NSString *const RCTReachabilityStateCell = @"cell";
NSString *_status; NSString *_status;
} }
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info) static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
@@ -55,6 +53,8 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
} }
} }
RCT_EXPORT_MODULE()
#pragma mark - Lifecycle #pragma mark - Lifecycle
- (instancetype)initWithHost:(NSString *)host - (instancetype)initWithHost:(NSString *)host
@@ -83,11 +83,9 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
#pragma mark - Public API #pragma mark - Public API
// TODO: remove error callback - not needed except by Subscribable interface // TODO: remove error callback - not needed except by Subscribable interface
- (void)getCurrentReachability:(RCTResponseSenderBlock)getSuccess RCT_EXPORT_METHOD(getCurrentReachability:(RCTResponseSenderBlock)getSuccess
withErrorCallback:(__unused RCTResponseSenderBlock)getError withErrorCallback:(__unused RCTResponseSenderBlock)getError)
{ {
RCT_EXPORT();
getSuccess(@[@{@"network_reachability": _status}]); getSuccess(@[@{@"network_reachability": _status}]);
} }

View File

@@ -68,29 +68,23 @@ RCT_EXPORT_MODULE()
/** /**
* Update the application icon badge number on the home screen * Update the application icon badge number on the home screen
*/ */
+ (void)setApplicationIconBadgeNumber:(NSInteger)number RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(NSInteger)number)
{ {
RCT_EXPORT();
[UIApplication sharedApplication].applicationIconBadgeNumber = number; [UIApplication sharedApplication].applicationIconBadgeNumber = number;
} }
/** /**
* Get the current application icon badge number on the home screen * Get the current application icon badge number on the home screen
*/ */
+ (void)getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
callback(@[ callback(@[
@([UIApplication sharedApplication].applicationIconBadgeNumber) @([UIApplication sharedApplication].applicationIconBadgeNumber)
]); ]);
} }
+ (void)requestPermissions RCT_EXPORT_METHOD(requestPermissions)
{ {
RCT_EXPORT();
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0 #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
// if we are targeting iOS 7, *and* the new UIUserNotificationSettings // if we are targeting iOS 7, *and* the new UIUserNotificationSettings
@@ -106,13 +100,10 @@ RCT_EXPORT_MODULE()
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert; UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
} }
+ (void)checkPermissions:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init]; NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init];
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types]; UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];

View File

@@ -32,10 +32,8 @@ RCT_EXPORT_MODULE()
return self; return self;
} }
- (void)verifySnapshot:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
if (!_snapshotController) { if (!_snapshotController) {
RCTLogWarn(@"No snapshot controller configured."); RCTLogWarn(@"No snapshot controller configured.");
callback(@[]); callback(@[]);
@@ -55,10 +53,8 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)markTestCompleted RCT_EXPORT_METHOD(markTestCompleted)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
_done = YES; _done = YES;
}); });

View File

@@ -15,9 +15,8 @@
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (void)vibrate RCT_EXPORT_METHOD(vibrate)
{ {
RCT_EXPORT();
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
} }

View File

@@ -213,11 +213,18 @@ static NSArray *RCTBridgeModuleClassesByModuleID(void)
static Class _globalExecutorClass; static Class _globalExecutorClass;
NS_INLINE NSString *RCTStringUpToFirstArgument(NSString *methodName) {
NSRange colonRange = [methodName rangeOfString:@":"];
if (colonRange.length) {
methodName = [methodName substringToIndex:colonRange.location];
}
return methodName;
}
- (instancetype)initWithMethodName:(NSString *)methodName - (instancetype)initWithMethodName:(NSString *)methodName
JSMethodName:(NSString *)JSMethodName JSMethodName:(NSString *)JSMethodName
{ {
if ((self = [super init])) { if ((self = [super init])) {
_methodName = methodName; _methodName = methodName;
NSArray *parts = [[methodName substringWithRange:(NSRange){2, methodName.length - 3}] componentsSeparatedByString:@" "]; NSArray *parts = [[methodName substringWithRange:(NSRange){2, methodName.length - 3}] componentsSeparatedByString:@" "];
@@ -228,14 +235,39 @@ static Class _globalExecutorClass;
_moduleClassName = [_moduleClassName substringToIndex:categoryRange.location]; _moduleClassName = [_moduleClassName substringToIndex:categoryRange.location];
} }
NSArray *argumentNames = nil;
if ([parts[1] hasPrefix:@"__rct_export__"]) {
// New format
NSString *selectorString = [parts[1] substringFromIndex:14];
_selector = NSSelectorFromString(selectorString);
_JSMethodName = RCTStringUpToFirstArgument(selectorString);
static NSRegularExpression *regExp;
if (!regExp) {
NSString *unusedPattern = @"(?:(?:__unused|__attribute__\\(\\(unused\\)\\)))";
NSString *constPattern = @"(?:const)";
NSString *constUnusedPattern = [NSString stringWithFormat:@"(?:(?:%@|%@)\\s*)", unusedPattern, constPattern];
NSString *pattern = [NSString stringWithFormat:@"\\(%1$@?(\\w+?)(?:\\s*\\*)?%1$@?\\)", constUnusedPattern];
regExp = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:NULL];
}
argumentNames = [NSMutableArray array];
[regExp enumerateMatchesInString:JSMethodName options:0 range:NSMakeRange(0, JSMethodName.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSString *argumentName = [JSMethodName substringWithRange:[result rangeAtIndex:1]];
[(NSMutableArray *)argumentNames addObject:argumentName];
}];
} else {
// Old format
NSString *selectorString = parts[1];
_selector = NSSelectorFromString(selectorString);
_JSMethodName = JSMethodName ?: RCTStringUpToFirstArgument(selectorString);
}
// Extract class and method details // Extract class and method details
_isClassMethod = [methodName characterAtIndex:0] == '+'; _isClassMethod = [methodName characterAtIndex:0] == '+';
_moduleClass = NSClassFromString(_moduleClassName); _moduleClass = NSClassFromString(_moduleClassName);
_selector = NSSelectorFromString(parts[1]);
_JSMethodName = JSMethodName ?: [NSStringFromSelector(_selector) componentsSeparatedByString:@":"][0];
#if DEBUG #if DEBUG
// Sanity check // Sanity check
RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], RCTAssert([_moduleClass conformsToProtocol:@protocol(RCTBridgeModule)],
@"You are attempting to export the method %@, but %@ does not \ @"You are attempting to export the method %@, but %@ does not \
@@ -250,15 +282,87 @@ static Class _globalExecutorClass;
// Process arguments // Process arguments
NSUInteger numberOfArguments = _methodSignature.numberOfArguments; NSUInteger numberOfArguments = _methodSignature.numberOfArguments;
NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2]; NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
for (NSUInteger i = 2; i < numberOfArguments; i++) {
const char *argumentType = [_methodSignature getArgumentTypeAtIndex:i];
switch (argumentType[0]) {
#define RCT_ARG_BLOCK(_logic) \ #define RCT_ARG_BLOCK(_logic) \
[argumentBlocks addObject:^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \ [argumentBlocks addObject:^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
_logic \ _logic \
[invocation setArgument:&value atIndex:index]; \ [invocation setArgument:&value atIndex:index]; \
}]; \ }]; \
void (^addBlockArgument)(void) = ^{
RCT_ARG_BLOCK(
if (json && ![json isKindOfClass:[NSNumber class]]) {
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
return;
}
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
__autoreleasing id value = (json ? ^(NSArray *args) {
[bridge _invokeAndProcessModule:@"BatchedBridge"
method:@"invokeCallbackAndReturnFlushedQueue"
arguments:@[json, args]];
} : ^(NSArray *unused) {});
)
};
void (^defaultCase)(const char *) = ^(const char *argumentType) {
static const char *blockType = @encode(typeof(^{}));
if (!strcmp(argumentType, blockType)) {
addBlockArgument();
} else {
RCT_ARG_BLOCK( id value = json; )
}
};
for (NSUInteger i = 2; i < numberOfArguments; i++) {
const char *argumentType = [_methodSignature getArgumentTypeAtIndex:i];
BOOL useFallback = YES;
if (argumentNames) {
NSString *argumentName = argumentNames[i - 2];
SEL selector = NSSelectorFromString([argumentName stringByAppendingString:@":"]);
if ([RCTConvert respondsToSelector:selector]) {
useFallback = NO;
switch (argumentType[0]) {
#define RCT_CONVERT_CASE(_value, _type) \
case _value: { \
_type (*convert)(id, SEL, id) = (typeof(convert))[RCTConvert methodForSelector:selector]; \
RCT_ARG_BLOCK( _type value = convert([RCTConvert class], selector, json); ) \
break; \
}
RCT_CONVERT_CASE(':', SEL)
RCT_CONVERT_CASE('*', const char *)
RCT_CONVERT_CASE('c', char)
RCT_CONVERT_CASE('C', unsigned char)
RCT_CONVERT_CASE('s', short)
RCT_CONVERT_CASE('S', unsigned short)
RCT_CONVERT_CASE('i', int)
RCT_CONVERT_CASE('I', unsigned int)
RCT_CONVERT_CASE('l', long)
RCT_CONVERT_CASE('L', unsigned long)
RCT_CONVERT_CASE('q', long long)
RCT_CONVERT_CASE('Q', unsigned long long)
RCT_CONVERT_CASE('f', float)
RCT_CONVERT_CASE('d', double)
RCT_CONVERT_CASE('B', BOOL)
RCT_CONVERT_CASE('@', id)
RCT_CONVERT_CASE('^', void *)
default:
defaultCase(argumentType);
break;
}
} else if ([argumentName isEqualToString:@"RCTResponseSenderBlock"]) {
addBlockArgument();
useFallback = NO;
}
}
if (useFallback) {
switch (argumentType[0]) {
#define RCT_CASE(_value, _class, _logic) \ #define RCT_CASE(_value, _class, _logic) \
case _value: { \ case _value: { \
@@ -273,61 +377,46 @@ static Class _globalExecutorClass;
break; \ break; \
} }
RCT_CASE(':', NSString, SEL value = NSSelectorFromString(json); ); RCT_CASE(':', NSString, SEL value = NSSelectorFromString(json); )
RCT_CASE('*', NSString, const char *value = [json UTF8String]; ); RCT_CASE('*', NSString, const char *value = [json UTF8String]; )
#define RCT_SIMPLE_CASE(_value, _type, _selector) \ #define RCT_SIMPLE_CASE(_value, _type, _selector) \
case _value: { \ case _value: { \
RCT_ARG_BLOCK( \ RCT_ARG_BLOCK( \
if (json && ![json respondsToSelector:@selector(_selector)]) { \ if (json && ![json respondsToSelector:@selector(_selector)]) { \
RCTLogError(@"Argument %tu (%@) of %@.%@ does not respond to selector: %@", \ RCTLogError(@"Argument %tu (%@) of %@.%@ does not respond to selector: %@", \
index, json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, @#_selector); \ index, json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, @#_selector); \
return; \ return; \
} \ } \
_type value = [json _selector]; \ _type value = [json _selector]; \
) \ ) \
break; \ break; \
}
RCT_SIMPLE_CASE('c', char, charValue)
RCT_SIMPLE_CASE('C', unsigned char, unsignedCharValue)
RCT_SIMPLE_CASE('s', short, shortValue)
RCT_SIMPLE_CASE('S', unsigned short, unsignedShortValue)
RCT_SIMPLE_CASE('i', int, intValue)
RCT_SIMPLE_CASE('I', unsigned int, unsignedIntValue)
RCT_SIMPLE_CASE('l', long, longValue)
RCT_SIMPLE_CASE('L', unsigned long, unsignedLongValue)
RCT_SIMPLE_CASE('q', long long, longLongValue)
RCT_SIMPLE_CASE('Q', unsigned long long, unsignedLongLongValue)
RCT_SIMPLE_CASE('f', float, floatValue)
RCT_SIMPLE_CASE('d', double, doubleValue)
RCT_SIMPLE_CASE('B', BOOL, boolValue)
default: {
static const char *blockType = @encode(typeof(^{}));
if (!strcmp(argumentType, blockType)) {
RCT_ARG_BLOCK(
if (json && ![json isKindOfClass:[NSNumber class]]) {
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
return;
}
// Marked as autoreleasing, because NSInvocation doesn't retain arguments
__autoreleasing id value = (json ? ^(NSArray *args) {
[bridge _invokeAndProcessModule:@"BatchedBridge"
method:@"invokeCallbackAndReturnFlushedQueue"
arguments:@[json, args]];
} : ^(NSArray *unused) {});
)
} else {
RCT_ARG_BLOCK( id value = json; )
} }
break;
RCT_SIMPLE_CASE('c', char, charValue)
RCT_SIMPLE_CASE('C', unsigned char, unsignedCharValue)
RCT_SIMPLE_CASE('s', short, shortValue)
RCT_SIMPLE_CASE('S', unsigned short, unsignedShortValue)
RCT_SIMPLE_CASE('i', int, intValue)
RCT_SIMPLE_CASE('I', unsigned int, unsignedIntValue)
RCT_SIMPLE_CASE('l', long, longValue)
RCT_SIMPLE_CASE('L', unsigned long, unsignedLongValue)
RCT_SIMPLE_CASE('q', long long, longLongValue)
RCT_SIMPLE_CASE('Q', unsigned long long, unsignedLongLongValue)
RCT_SIMPLE_CASE('f', float, floatValue)
RCT_SIMPLE_CASE('d', double, doubleValue)
RCT_SIMPLE_CASE('B', BOOL, boolValue)
default:
defaultCase(argumentType);
break;
} }
} }
} }
_argumentBlocks = [argumentBlocks copy]; _argumentBlocks = [argumentBlocks copy];
} }
return self; return self;
} }
@@ -337,7 +426,6 @@ static Class _globalExecutorClass;
{ {
#if DEBUG #if DEBUG
// Sanity check // Sanity check
RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \ RCTAssert([module class] == _moduleClass, @"Attempted to invoke method \
%@ on a module of class %@", _methodName, [module class]); %@ on a module of class %@", _methodName, [module class]);
@@ -354,6 +442,7 @@ static Class _globalExecutorClass;
// Create invocation (we can't re-use this as it wouldn't be thread-safe) // Create invocation (we can't re-use this as it wouldn't be thread-safe)
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_methodSignature];
[invocation setArgument:&_selector atIndex:1]; [invocation setArgument:&_selector atIndex:1];
[invocation retainArguments];
// Set arguments // Set arguments
NSUInteger index = 0; NSUInteger index = 0;
@@ -361,7 +450,7 @@ static Class _globalExecutorClass;
id arg = (json == [NSNull null]) ? nil : json; id arg = (json == [NSNull null]) ? nil : json;
void (^block)(RCTBridge *, NSInvocation *, NSUInteger, id) = _argumentBlocks[index]; void (^block)(RCTBridge *, NSInvocation *, NSUInteger, id) = _argumentBlocks[index];
block(bridge, invocation, index + 2, arg); block(bridge, invocation, index + 2, arg);
index ++; index++;
} }
// Invoke method // Invoke method
@@ -768,6 +857,11 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
[_javaScriptExecutor invalidate]; [_javaScriptExecutor invalidate];
_javaScriptExecutor = nil; _javaScriptExecutor = nil;
// Wait for queued methods to finish
dispatch_sync(self.shadowQueue, ^{
// Make sure all dispatchers have been executed before continuing
});
// Invalidate modules // Invalidate modules
for (id target in _modulesByID.allObjects) { for (id target in _modulesByID.allObjects) {
if ([target respondsToSelector:@selector(invalidate)]) { if ([target respondsToSelector:@selector(invalidate)]) {

View File

@@ -48,8 +48,37 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
* If omitted, the JS method name will match the first part of the Objective-C * If omitted, the JS method name will match the first part of the Objective-C
* method selector name (up to the first colon). * method selector name (up to the first colon).
*/ */
#define RCT_EXPORT(js_name) __attribute__((used, section("__DATA,RCTExport" \ #define RCT_EXPORT(js_name) \
))) static const char *__rct_export_entry__[] = { __func__, #js_name } _Pragma("message(\"RCT_EXPORT is deprecated. Use RCT_EXPORT_METHOD instead.\")") \
__attribute__((used, section("__DATA,RCTExport"))) \
static const char *__rct_export_entry__[] = { __func__, #js_name }
/**
* Wrap the parameter line of your method implementation with this macro to
* expose it to JS. Unlike the deprecated RCT_EXPORT, this macro does not take
* a js_name argument and the exposed method will match the first part of the
* Objective-C method selector name (up to the first colon).
*
* For example, in MyClass.m:
*
* - (void)doSomething:(NSString *)aString withA:(NSInteger)a andB:(NSInteger)b
* {}
*
* becomes
*
* RCT_EXPORT_METHOD(doSomething:(NSString *)aString
* withA:(NSInteger)a
* andB:(NSInteger)b)
* {}
*
* and is exposed to JavaScript as `NativeModules.ModuleName.doSomething`.
*/
#define RCT_EXPORT_METHOD(method) \
- (void)__rct_export__##method { \
__attribute__((used, section("__DATA,RCTExport"))) \
static const char *__rct_export_entry__[] = { __func__, #method }; \
} \
- (void)method
/** /**
* Injects constants into JS. These constants are made accessible via * Injects constants into JS. These constants are made accessible via
@@ -67,3 +96,11 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);
- (void)batchDidComplete; - (void)batchDidComplete;
@end @end
#ifdef __cplusplus
extern "C" {
#endif
void RCTBridgeModuleRegisterClass(Class cls, NSString *moduleName);
#ifdef __cplusplus
}
#endif

View File

@@ -82,14 +82,26 @@
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family + (UIFont *)UIFont:(UIFont *)font withFamily:(id)family
size:(id)size weight:(id)weight style:(id)style; size:(id)size weight:(id)weight style:(id)style;
+ (NSArray *)NSStringArray:(id)json; typedef NSArray NSStringArray;
+ (NSArray *)NSDictionaryArray:(id)json; + (NSStringArray *)NSStringArray:(id)json;
+ (NSArray *)NSURLArray:(id)json;
+ (NSArray *)NSNumberArray:(id)json;
+ (NSArray *)UIColorArray:(id)json;
+ (NSArray *)CGColorArray:(id)json;
+ (BOOL)css_overflow:(id)json; typedef NSArray NSDictionaryArray;
+ (NSDictionaryArray *)NSDictionaryArray:(id)json;
typedef NSArray NSURLArray;
+ (NSURLArray *)NSURLArray:(id)json;
typedef NSArray NSNumberArray;
+ (NSNumberArray *)NSNumberArray:(id)json;
typedef NSArray UIColorArray;
+ (UIColorArray *)UIColorArray:(id)json;
typedef NSArray CGColorArray;
+ (CGColorArray *)CGColorArray:(id)json;
typedef BOOL css_overflow;
+ (css_overflow)css_overflow:(id)json;
+ (css_flex_direction_t)css_flex_direction_t:(id)json; + (css_flex_direction_t)css_flex_direction_t:(id)json;
+ (css_justify_t)css_justify_t:(id)json; + (css_justify_t)css_justify_t:(id)json;
+ (css_align_t)css_align_t:(id)json; + (css_align_t)css_align_t:(id)json;
@@ -195,7 +207,7 @@ RCT_CUSTOM_CONVERTER(type, type, [[self NSNumber:json] getter])
* This macro is used for creating converter functions for typed arrays. * This macro is used for creating converter functions for typed arrays.
*/ */
#define RCT_ARRAY_CONVERTER(type) \ #define RCT_ARRAY_CONVERTER(type) \
+ (NSArray *)type##Array:(id)json \ + (type##Array *)type##Array:(id)json \
{ \ { \
NSMutableArray *values = [[NSMutableArray alloc] init]; \ NSMutableArray *values = [[NSMutableArray alloc] init]; \
for (id jsonValue in [self NSArray:json]) { \ for (id jsonValue in [self NSArray:json]) { \

View File

@@ -742,8 +742,6 @@ RCT_ARRAY_CONVERTER(UIColor)
return colors; return colors;
} }
typedef BOOL css_overflow;
RCT_ENUM_CONVERTER(css_overflow, (@{ RCT_ENUM_CONVERTER(css_overflow, (@{
@"hidden": @NO, @"hidden": @NO,
@"visible": @YES @"visible": @YES

View File

@@ -49,10 +49,9 @@ RCT_EXPORT_MODULE()
* Buttons are displayed in the order they are specified. If "cancel" is used as * Buttons are displayed in the order they are specified. If "cancel" is used as
* the button key, it will be differently highlighted, according to iOS UI conventions. * the button key, it will be differently highlighted, according to iOS UI conventions.
*/ */
- (void)alertWithArgs:(NSDictionary *)args callback:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args
callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
NSString *title = args[@"title"]; NSString *title = args[@"title"];
NSString *message = args[@"message"]; NSString *message = args[@"message"];
NSArray *buttons = args[@"buttons"]; NSArray *buttons = args[@"buttons"];

View File

@@ -33,10 +33,10 @@ static NSString *RCTCurrentAppBackgroundState()
NSString *_lastKnownState; NSString *_lastKnownState;
} }
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
#pragma mark - Lifecycle #pragma mark - Lifecycle
- (instancetype)init - (instancetype)init
@@ -81,11 +81,9 @@ RCT_EXPORT_MODULE()
/** /**
* Get the current background/foreground state of the app * Get the current background/foreground state of the app
*/ */
- (void)getCurrentAppState:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(getCurrentAppState:(RCTResponseSenderBlock)callback
error:(__unused RCTResponseSenderBlock)error error:(__unused RCTResponseSenderBlock)error)
{ {
RCT_EXPORT();
callback(@[@{@"app_state": _lastKnownState}]); callback(@[@{@"app_state": _lastKnownState}]);
} }

View File

@@ -188,10 +188,9 @@ RCT_EXPORT_MODULE()
#pragma mark - Exported JS Functions #pragma mark - Exported JS Functions
- (void)multiGet:(NSArray *)keys callback:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(multiGet:(NSArray *)keys
callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
if (!callback) { if (!callback) {
RCTLogError(@"Called getItem without a callback."); RCTLogError(@"Called getItem without a callback.");
return; return;
@@ -214,10 +213,9 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)multiSet:(NSArray *)kvPairs callback:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(multiSet:(NSArray *)kvPairs
callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
dispatch_async(RCTFileQueue(), ^{ dispatch_async(RCTFileQueue(), ^{
id errorOut = [self _ensureSetup]; id errorOut = [self _ensureSetup];
if (errorOut) { if (errorOut) {
@@ -236,10 +234,9 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)multiRemove:(NSArray *)keys callback:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys
callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
dispatch_async(RCTFileQueue(), ^{ dispatch_async(RCTFileQueue(), ^{
id errorOut = [self _ensureSetup]; id errorOut = [self _ensureSetup];
if (errorOut) { if (errorOut) {
@@ -263,10 +260,8 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)clear:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(clear:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
dispatch_async(RCTFileQueue(), ^{ dispatch_async(RCTFileQueue(), ^{
id errorOut = [self _ensureSetup]; id errorOut = [self _ensureSetup];
if (!errorOut) { if (!errorOut) {
@@ -284,10 +279,8 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)getAllKeys:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
dispatch_async(RCTFileQueue(), ^{ dispatch_async(RCTFileQueue(), ^{
id errorOut = [self _ensureSetup]; id errorOut = [self _ensureSetup];
if (errorOut) { if (errorOut) {

View File

@@ -31,10 +31,9 @@ RCT_EXPORT_MODULE()
return [self initWithDelegate:nil]; return [self initWithDelegate:nil];
} }
- (void)reportUnhandledExceptionWithMessage:(NSString *)message stack:(NSArray *)stack RCT_EXPORT_METHOD(reportUnhandledExceptionWithMessage:(NSString *)message
stack:(NSArray *)stack)
{ {
RCT_EXPORT(reportUnhandledException);
if (_delegate) { if (_delegate) {
[_delegate unhandledJSExceptionWithMessage:message stack:stack]; [_delegate unhandledJSExceptionWithMessage:message stack:stack];
} else { } else {
@@ -42,10 +41,9 @@ RCT_EXPORT_MODULE()
} }
} }
- (void)updateExceptionMessage:(NSString *)message stack:(NSArray *)stack RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
stack:(NSArray *)stack)
{ {
RCT_EXPORT(updateExceptionMessage);
[[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack]; [[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack];
} }

View File

@@ -16,9 +16,9 @@
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (void)getScriptText:(RCTResponseSenderBlock)successCallback failureCallback:(RCTResponseSenderBlock)failureCallback RCT_EXPORT_METHOD(getScriptText:(RCTResponseSenderBlock)successCallback
failureCallback:(RCTResponseSenderBlock)failureCallback)
{ {
RCT_EXPORT();
if (self.scriptText && self.scriptURL) { if (self.scriptText && self.scriptURL) {
successCallback(@[@{@"text": self.scriptText, @"url":[self.scriptURL absoluteString]}]); successCallback(@[@{@"text": self.scriptText, @"url":[self.scriptURL absoluteString]}]);
} else { } else {

View File

@@ -26,10 +26,9 @@ static BOOL RCTViewControllerBasedStatusBarAppearance()
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
- (void)setStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated RCT_EXPORT_METHOD(setStyle:(UIStatusBarStyle)statusBarStyle
animated:(BOOL)animated)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (RCTViewControllerBasedStatusBarAppearance()) { if (RCTViewControllerBasedStatusBarAppearance()) {
@@ -42,10 +41,9 @@ RCT_EXPORT_MODULE()
}); });
} }
- (void)setHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation RCT_EXPORT_METHOD(setHidden:(BOOL)hidden
withAnimation:(UIStatusBarAnimation)animation)
{ {
RCT_EXPORT();
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (RCTViewControllerBasedStatusBarAppearance()) { if (RCTViewControllerBasedStatusBarAppearance()) {

View File

@@ -61,10 +61,10 @@
id _updateTimer; id _updateTimer;
} }
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
RCT_IMPORT_METHOD(RCTJSTimers, callTimers) RCT_IMPORT_METHOD(RCTJSTimers, callTimers)
- (instancetype)init - (instancetype)init
@@ -165,34 +165,29 @@ RCT_IMPORT_METHOD(RCTJSTimers, callTimers)
* calculating the timer's target time. We calculate this by passing in * calculating the timer's target time. We calculate this by passing in
* Date.now() from JS and then subtracting that from the current time here. * Date.now() from JS and then subtracting that from the current time here.
*/ */
- (void)createTimer:(NSNumber *)callbackID RCT_EXPORT_METHOD(createTimer:(NSNumber *)callbackID
duration:(double)jsDuration duration:(NSTimeInterval)jsDuration
jsSchedulingTime:(double)jsSchedulingTime jsSchedulingTime:(NSDate *)jsSchedulingTime
repeats:(BOOL)repeats repeats:(BOOL)repeats)
{ {
RCT_EXPORT();
if (jsDuration == 0 && repeats == NO) { if (jsDuration == 0 && repeats == NO) {
// For super fast, one-off timers, just enqueue them immediately rather than waiting a frame. // For super fast, one-off timers, just enqueue them immediately rather than waiting a frame.
[_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[@[callbackID]]]; [_bridge enqueueJSCall:@"RCTJSTimers.callTimers" args:@[@[callbackID]]];
return; return;
} }
NSTimeInterval interval = jsDuration / 1000; NSTimeInterval jsSchedulingOverhead = -jsSchedulingTime.timeIntervalSinceNow;
NSTimeInterval jsCreationTimeSinceUnixEpoch = jsSchedulingTime / 1000;
NSTimeInterval currentTimeSinceUnixEpoch = [[NSDate date] timeIntervalSince1970];
NSTimeInterval jsSchedulingOverhead = currentTimeSinceUnixEpoch - jsCreationTimeSinceUnixEpoch;
if (jsSchedulingOverhead < 0) { if (jsSchedulingOverhead < 0) {
RCTLogWarn(@"jsSchedulingOverhead (%ims) should be positive", (int)(jsSchedulingOverhead * 1000)); RCTLogWarn(@"jsSchedulingOverhead (%ims) should be positive", (int)(jsSchedulingOverhead * 1000));
} }
NSTimeInterval targetTime = interval - jsSchedulingOverhead; NSTimeInterval targetTime = jsDuration - jsSchedulingOverhead;
if (interval < 0.018) { // Make sure short intervals run each frame if (jsDuration < 0.018) { // Make sure short intervals run each frame
interval = 0; jsDuration = 0;
} }
RCTTimer *timer = [[RCTTimer alloc] initWithCallbackID:callbackID RCTTimer *timer = [[RCTTimer alloc] initWithCallbackID:callbackID
interval:interval interval:jsDuration
targetTime:targetTime targetTime:targetTime
repeats:repeats]; repeats:repeats];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
@@ -201,10 +196,8 @@ RCT_IMPORT_METHOD(RCTJSTimers, callTimers)
}); });
} }
- (void)deleteTimer:(NSNumber *)timerID RCT_EXPORT_METHOD(deleteTimer:(NSNumber *)timerID)
{ {
RCT_EXPORT();
if (timerID) { if (timerID) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
_timers[timerID] = nil; _timers[timerID] = nil;

View File

@@ -195,10 +195,10 @@ static UIViewAnimationCurve UIViewAnimationCurveFromRCTAnimationType(RCTAnimatio
NSUInteger _rootTag; NSUInteger _rootTag;
} }
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
/** /**
* Declared in RCTBridge. * Declared in RCTBridge.
*/ */
@@ -514,10 +514,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
* A method to be called from JS, which takes a container ID and then releases * A method to be called from JS, which takes a container ID and then releases
* all subviews for that container upon receipt. * all subviews for that container upon receipt.
*/ */
- (void)removeSubviewsFromContainerWithID:(NSNumber *)containerID RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(NSNumber *)containerID)
{ {
RCT_EXPORT();
id<RCTViewNodeProtocol> container = _shadowViewRegistry[containerID]; id<RCTViewNodeProtocol> container = _shadowViewRegistry[containerID];
RCTAssert(container != nil, @"container view (for ID %@) not found", containerID); RCTAssert(container != nil, @"container view (for ID %@) not found", containerID);
@@ -571,10 +569,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
} }
} }
- (void)removeRootView:(NSNumber *)rootReactTag RCT_EXPORT_METHOD(removeRootView:(NSNumber *)rootReactTag)
{ {
RCT_EXPORT();
RCTShadowView *rootShadowView = _shadowViewRegistry[rootReactTag]; RCTShadowView *rootShadowView = _shadowViewRegistry[rootReactTag];
RCTAssert(rootShadowView.superview == nil, @"root view cannot have superview (ID %@)", rootReactTag); RCTAssert(rootShadowView.superview == nil, @"root view cannot have superview (ID %@)", rootReactTag);
[self _purgeChildren:rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry]; [self _purgeChildren:rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry];
@@ -589,10 +585,8 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
}]; }];
} }
- (void)replaceExistingNonRootView:(NSNumber *)reactTag withView:(NSNumber *)newReactTag RCT_EXPORT_METHOD(replaceExistingNonRootView:(NSNumber *)reactTag withView:(NSNumber *)newReactTag)
{ {
RCT_EXPORT();
RCTShadowView *shadowView = _shadowViewRegistry[reactTag]; RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
RCTAssert(shadowView != nil, @"shadowView (for ID %@) not found", reactTag); RCTAssert(shadowView != nil, @"shadowView (for ID %@) not found", reactTag);
@@ -611,15 +605,13 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
removeAtIndices:removeAtIndices]; removeAtIndices:removeAtIndices];
} }
- (void)manageChildren:(NSNumber *)containerReactTag RCT_EXPORT_METHOD(manageChildren:(NSNumber *)containerReactTag
moveFromIndices:(NSArray *)moveFromIndices moveFromIndices:(NSArray *)moveFromIndices
moveToIndices:(NSArray *)moveToIndices moveToIndices:(NSArray *)moveToIndices
addChildReactTags:(NSArray *)addChildReactTags addChildReactTags:(NSArray *)addChildReactTags
addAtIndices:(NSArray *)addAtIndices addAtIndices:(NSArray *)addAtIndices
removeAtIndices:(NSArray *)removeAtIndices removeAtIndices:(NSArray *)removeAtIndices)
{ {
RCT_EXPORT();
[self _manageChildren:containerReactTag [self _manageChildren:containerReactTag
moveFromIndices:moveFromIndices moveFromIndices:moveFromIndices
moveToIndices:moveToIndices moveToIndices:moveToIndices
@@ -629,7 +621,6 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
registry:_shadowViewRegistry]; registry:_shadowViewRegistry];
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
[uiManager _manageChildren:containerReactTag [uiManager _manageChildren:containerReactTag
moveFromIndices:moveFromIndices moveFromIndices:moveFromIndices
moveToIndices:moveToIndices moveToIndices:moveToIndices
@@ -738,12 +729,10 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
[shadowView updateLayout]; [shadowView updateLayout];
} }
- (void)createAndRegisterViewWithReactTag:(NSNumber *)reactTag RCT_EXPORT_METHOD(createView:(NSNumber *)reactTag
viewName:(NSString *)viewName viewName:(NSString *)viewName
props:(NSDictionary *)props props:(NSDictionary *)props)
{ {
RCT_EXPORT(createView);
RCTViewManager *manager = _viewManagers[viewName]; RCTViewManager *manager = _viewManagers[viewName];
if (manager == nil) { if (manager == nil) {
RCTLogWarn(@"No manager class found for view with module name \"%@\"", viewName); RCTLogWarn(@"No manager class found for view with module name \"%@\"", viewName);
@@ -795,10 +784,10 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
}]; }];
} }
// TODO: remove viewName param as it isn't needed // TODO: remove viewName param as it isn't needed
- (void)updateView:(NSNumber *)reactTag viewName:(__unused NSString *)_ props:(NSDictionary *)props RCT_EXPORT_METHOD(updateView:(NSNumber *)reactTag
viewName:(__unused NSString *)_
props:(NSDictionary *)props)
{ {
RCT_EXPORT();
RCTViewManager *viewManager = _viewManagerRegistry[reactTag]; RCTViewManager *viewManager = _viewManagerRegistry[reactTag];
NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([viewManager class])); NSString *viewName = RCTViewNameForModuleName(RCTBridgeModuleNameForClass([viewManager class]));
@@ -811,10 +800,8 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
}]; }];
} }
- (void)becomeResponder:(NSNumber *)reactTag RCT_EXPORT_METHOD(focus:(NSNumber *)reactTag)
{ {
RCT_EXPORT(focus);
if (!reactTag) return; if (!reactTag) return;
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
UIView *newResponder = viewRegistry[reactTag]; UIView *newResponder = viewRegistry[reactTag];
@@ -824,10 +811,8 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
}]; }];
} }
- (void)resignResponder:(NSNumber *)reactTag RCT_EXPORT_METHOD(blur:(NSNumber *)reactTag)
{ {
RCT_EXPORT(blur);
if (!reactTag) return; if (!reactTag) return;
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *currentResponder = viewRegistry[reactTag]; UIView *currentResponder = viewRegistry[reactTag];
@@ -892,10 +877,9 @@ static void RCTSetShadowViewProps(NSDictionary *props, RCTShadowView *shadowView
}); });
} }
- (void)measure:(NSNumber *)reactTag callback:(RCTResponseSenderBlock)callback RCT_EXPORT_METHOD(measure:(NSNumber *)reactTag
callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
if (!callback) { if (!callback) {
RCTLogError(@"Called measure with no callback"); RCTLogError(@"Called measure with no callback");
return; return;
@@ -968,13 +952,11 @@ static void RCTMeasureLayout(RCTShadowView *view,
* anything on the main UI thread. Invokes supplied callback with (x, y, width, * anything on the main UI thread. Invokes supplied callback with (x, y, width,
* height). * height).
*/ */
- (void)measureLayout:(NSNumber *)reactTag RCT_EXPORT_METHOD(measureLayout:(NSNumber *)reactTag
relativeTo:(NSNumber *)ancestorReactTag relativeTo:(NSNumber *)ancestorReactTag
errorCallback:(RCTResponseSenderBlock)errorCallback errorCallback:(RCTResponseSenderBlock)errorCallback
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
RCTShadowView *shadowView = _shadowViewRegistry[reactTag]; RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
RCTShadowView *ancestorShadowView = _shadowViewRegistry[ancestorReactTag]; RCTShadowView *ancestorShadowView = _shadowViewRegistry[ancestorReactTag];
RCTMeasureLayout(shadowView, ancestorShadowView, callback); RCTMeasureLayout(shadowView, ancestorShadowView, callback);
@@ -987,12 +969,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
* anything on the main UI thread. Invokes supplied callback with (x, y, width, * anything on the main UI thread. Invokes supplied callback with (x, y, width,
* height). * height).
*/ */
- (void)measureLayoutRelativeToParent:(NSNumber *)reactTag RCT_EXPORT_METHOD(measureLayoutRelativeToParent:(NSNumber *)reactTag
errorCallback:(RCTResponseSenderBlock)errorCallback errorCallback:(RCTResponseSenderBlock)errorCallback
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
RCTShadowView *shadowView = _shadowViewRegistry[reactTag]; RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
RCTMeasureLayout(shadowView, shadowView.reactSuperview, callback); RCTMeasureLayout(shadowView, shadowView.reactSuperview, callback);
} }
@@ -1004,13 +984,11 @@ static void RCTMeasureLayout(RCTShadowView *view,
* Only layouts for views that are within the rect passed in are returned. Invokes the error callback if the * Only layouts for views that are within the rect passed in are returned. Invokes the error callback if the
* passed in parent view does not exist. Invokes the supplied callback with the array of computed layouts. * passed in parent view does not exist. Invokes the supplied callback with the array of computed layouts.
*/ */
- (void)measureViewsInRect:(NSDictionary *)rect RCT_EXPORT_METHOD(measureViewsInRect:(NSDictionary *)rect
parentView:(NSNumber *)reactTag parentView:(NSNumber *)reactTag
errorCallback:(RCTResponseSenderBlock)errorCallback errorCallback:(RCTResponseSenderBlock)errorCallback
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
RCTShadowView *shadowView = _shadowViewRegistry[reactTag]; RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
if (!shadowView) { if (!shadowView) {
RCTLogError(@"Attempting to measure view that does not exist (tag #%@)", reactTag); RCTLogError(@"Attempting to measure view that does not exist (tag #%@)", reactTag);
@@ -1050,10 +1028,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
callback(@[results]); callback(@[results]);
} }
- (void)setMainScrollViewTag:(NSNumber *)reactTag RCT_EXPORT_METHOD(setMainScrollViewTag:(NSNumber *)reactTag)
{ {
RCT_EXPORT();
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
// - There should be at most one designated "main scroll view" // - There should be at most one designated "main scroll view"
// - There should be at most one designated "`nativeMainScrollDelegate`" // - There should be at most one designated "`nativeMainScrollDelegate`"
@@ -1076,10 +1052,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
}]; }];
} }
- (void)scrollToOffsetWithView:(NSNumber *)reactTag scrollToOffsetX:(NSNumber *)offsetX offsetY:(NSNumber *)offsetY RCT_EXPORT_METHOD(scrollTo:(NSNumber *)reactTag
withOffsetX:(NSNumber *)offsetX
offsetY:(NSNumber *)offsetY)
{ {
RCT_EXPORT(scrollTo);
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) { if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
@@ -1090,10 +1066,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
}]; }];
} }
- (void)scrollWithoutAnimationToOffsetWithView:(NSNumber *)reactTag scrollToOffsetX:(NSNumber *)offsetX offsetY:(NSNumber *)offsetY RCT_EXPORT_METHOD(scrollWithoutAnimationTo:(NSNumber *)reactTag
offsetX:(NSNumber *)offsetX
offsetY:(NSNumber *)offsetY)
{ {
RCT_EXPORT(scrollWithoutAnimationTo);
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) { if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
@@ -1104,10 +1080,9 @@ static void RCTMeasureLayout(RCTShadowView *view,
}]; }];
} }
- (void)zoomToRectWithView:(NSNumber *)reactTag rect:(NSDictionary *)rectDict RCT_EXPORT_METHOD(zoomToRect:(NSNumber *)reactTag
withRect:(NSDictionary *)rectDict)
{ {
RCT_EXPORT(zoomToRect);
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];
if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) { if ([view conformsToProtocol:@protocol(RCTScrollableProtocol)]) {
@@ -1122,10 +1097,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
* JS sets what *it* considers to be the responder. Later, scroll views can use * JS sets what *it* considers to be the responder. Later, scroll views can use
* this in order to determine if scrolling is appropriate. * this in order to determine if scrolling is appropriate.
*/ */
- (void)setJSResponder:(NSNumber *)reactTag RCT_EXPORT_METHOD(setJSResponder:(NSNumber *)reactTag)
{ {
RCT_EXPORT();
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
_jsResponder = viewRegistry[reactTag]; _jsResponder = viewRegistry[reactTag];
if (!_jsResponder) { if (!_jsResponder) {
@@ -1134,10 +1107,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
}]; }];
} }
- (void)clearJSResponder RCT_EXPORT_METHOD(clearJSResponder)
{ {
RCT_EXPORT();
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
_jsResponder = nil; _jsResponder = nil;
}]; }];
@@ -1407,12 +1378,10 @@ static void RCTMeasureLayout(RCTShadowView *view,
return allJSConstants; return allJSConstants;
} }
- (void)configureNextLayoutAnimation:(NSDictionary *)config RCT_EXPORT_METHOD(configureNextLayoutAnimation:(NSDictionary *)config
withCallback:(RCTResponseSenderBlock)callback withCallback:(RCTResponseSenderBlock)callback
errorCallback:(RCTResponseSenderBlock)errorCallback errorCallback:(RCTResponseSenderBlock)errorCallback)
{ {
RCT_EXPORT();
if (_nextLayoutAnimation) { if (_nextLayoutAnimation) {
RCTLogWarn(@"Warning: Overriding previous layout animation with new one before the first began:\n%@ -> %@.", RCTLogWarn(@"Warning: Overriding previous layout animation with new one before the first began:\n%@ -> %@.",
_nextLayoutAnimation, config); _nextLayoutAnimation, config);
@@ -1424,10 +1393,8 @@ static void RCTMeasureLayout(RCTShadowView *view,
callback:callback]; callback:callback];
} }
- (void)startOrResetInteractionTiming RCT_EXPORT_METHOD(startOrResetInteractionTiming)
{ {
RCT_EXPORT();
NSSet *rootViewTags = [_rootViewTags copy]; NSSet *rootViewTags = [_rootViewTags copy];
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
for (NSNumber *reactTag in rootViewTags) { for (NSNumber *reactTag in rootViewTags) {
@@ -1439,11 +1406,9 @@ static void RCTMeasureLayout(RCTShadowView *view,
}]; }];
} }
- (void)endAndResetInteractionTiming:(RCTResponseSenderBlock)onSuccess RCT_EXPORT_METHOD(endAndResetInteractionTiming:(RCTResponseSenderBlock)onSuccess
onError:(RCTResponseSenderBlock)onError onError:(RCTResponseSenderBlock)onError)
{ {
RCT_EXPORT();
NSSet *rootViewTags = [_rootViewTags copy]; NSSet *rootViewTags = [_rootViewTags copy];
[self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
NSMutableDictionary *timingData = [[NSMutableDictionary alloc] init]; NSMutableDictionary *timingData = [[NSMutableDictionary alloc] init];

View File

@@ -36,12 +36,10 @@ RCT_EXPORT_VIEW_PROPERTY(requestedTopOfStack, NSInteger)
} }
// TODO: remove error callbacks // TODO: remove error callbacks
- (void)requestSchedulingJavaScriptNavigation:(NSNumber *)reactTag RCT_EXPORT_METHOD(requestSchedulingJavaScriptNavigation:(NSNumber *)reactTag
errorCallback:(RCTResponseSenderBlock)errorCallback errorCallback:(RCTResponseSenderBlock)errorCallback
callback:(__unused RCTResponseSenderBlock)callback callback:(__unused RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){
RCTNavigator *navigator = viewRegistry[reactTag]; RCTNavigator *navigator = viewRegistry[reactTag];
if ([navigator isKindOfClass:[RCTNavigator class]]) { if ([navigator isKindOfClass:[RCTNavigator class]]) {

View File

@@ -65,11 +65,9 @@ RCT_DEPRECATED_VIEW_PROPERTY(throttleScrollCallbackMS, scrollEventThrottle)
}; };
} }
- (void)getContentSize:(NSNumber *)reactTag RCT_EXPORT_METHOD(getContentSize:(NSNumber *)reactTag
callback:(RCTResponseSenderBlock)callback callback:(RCTResponseSenderBlock)callback)
{ {
RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];

View File

@@ -14,10 +14,10 @@
@implementation RCTTabBarManager @implementation RCTTabBarManager
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
- (UIView *)view - (UIView *)view
{ {
return [[RCTTabBar alloc] initWithEventDispatcher:_bridge.eventDispatcher]; return [[RCTTabBar alloc] initWithEventDispatcher:_bridge.eventDispatcher];

View File

@@ -19,10 +19,10 @@
@implementation RCTViewManager @implementation RCTViewManager
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
- (UIView *)view - (UIView *)view
{ {
return [[RCTView alloc] init]; return [[RCTView alloc] init];

View File

@@ -43,10 +43,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
}; };
} }
- (void)goBack:(NSNumber *)reactTag RCT_EXPORT_METHOD(goBack:(NSNumber *)reactTag)
{ {
RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTWebView *view = viewRegistry[reactTag]; RCTWebView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTWebView class]]) { if (![view isKindOfClass:[RCTWebView class]]) {
@@ -56,10 +54,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
}]; }];
} }
- (void)goForward:(NSNumber *)reactTag RCT_EXPORT_METHOD(goForward:(NSNumber *)reactTag)
{ {
RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
id view = viewRegistry[reactTag]; id view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTWebView class]]) { if (![view isKindOfClass:[RCTWebView class]]) {
@@ -70,10 +66,8 @@ RCT_EXPORT_VIEW_PROPERTY(shouldInjectAJAXHandler, BOOL);
} }
- (void)reload:(NSNumber *)reactTag RCT_EXPORT_METHOD(reload:(NSNumber *)reactTag)
{ {
RCT_EXPORT();
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTWebView *view = viewRegistry[reactTag]; RCTWebView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTWebView class]]) { if (![view isKindOfClass:[RCTWebView class]]) {