Removed debug code from release builds

This commit is contained in:
Nick Lockwood 2015-04-21 09:48:29 -07:00
parent 25ae5485da
commit ee898c24c7
17 changed files with 226 additions and 121 deletions

View File

@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */
00D277161AB8C32C00DC1E48 /* RCTWebSocketExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 00D277151AB8C32C00DC1E48 /* RCTWebSocketExecutor.m */; };
00D277191AB8C35800DC1E48 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 00D277181AB8C35800DC1E48 /* SRWebSocket.m */; };
00D277191AB8C35800DC1E48 /* RCT_SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 00D277181AB8C35800DC1E48 /* RCT_SRWebSocket.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -26,8 +26,8 @@
/* Begin PBXFileReference section */
00D277141AB8C32C00DC1E48 /* RCTWebSocketExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebSocketExecutor.h; sourceTree = "<group>"; };
00D277151AB8C32C00DC1E48 /* RCTWebSocketExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebSocketExecutor.m; sourceTree = "<group>"; };
00D277171AB8C35800DC1E48 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRWebSocket.h; sourceTree = "<group>"; };
00D277181AB8C35800DC1E48 /* SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRWebSocket.m; sourceTree = "<group>"; };
00D277171AB8C35800DC1E48 /* RCT_SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCT_SRWebSocket.h; sourceTree = "<group>"; };
00D277181AB8C35800DC1E48 /* RCT_SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCT_SRWebSocket.m; sourceTree = "<group>"; };
832C81801AAF6DEF007FA2F7 /* libRCTWebSocketDebugger.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTWebSocketDebugger.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@ -45,8 +45,8 @@
832C81771AAF6DEF007FA2F7 = {
isa = PBXGroup;
children = (
00D277171AB8C35800DC1E48 /* SRWebSocket.h */,
00D277181AB8C35800DC1E48 /* SRWebSocket.m */,
00D277171AB8C35800DC1E48 /* RCT_SRWebSocket.h */,
00D277181AB8C35800DC1E48 /* RCT_SRWebSocket.m */,
00D277141AB8C32C00DC1E48 /* RCTWebSocketExecutor.h */,
00D277151AB8C32C00DC1E48 /* RCTWebSocketExecutor.m */,
832C81811AAF6DEF007FA2F7 /* Products */,
@ -119,7 +119,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00D277191AB8C35800DC1E48 /* SRWebSocket.m in Sources */,
00D277191AB8C35800DC1E48 /* RCT_SRWebSocket.m in Sources */,
00D277161AB8C32C00DC1E48 /* RCTWebSocketExecutor.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEV // Debug executors are only supported in dev mode
#import "RCTJavaScriptExecutor.h"
@interface RCTWebSocketExecutor : NSObject <RCTJavaScriptExecutor>
@ -14,3 +18,5 @@
- (instancetype)initWithURL:(NSURL *)URL;
@end
#endif

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEV // Debug executors are only supported in dev mode
#import "RCTWebSocketExecutor.h"
#import "RCTLog.h"
@ -189,3 +193,5 @@ typedef void (^WSMessageCallback)(NSError *error, NSDictionary *reply);
}
@end
#endif

View File

@ -19,6 +19,8 @@
#import <Availability.h>
#pragma clang diagnostic ignored "-Wshadow"
//NOTE: libicucore ins't actually needed for the socket to function
//and by commenting this out, we avoid the need to import it into every app.

View File

@ -314,7 +314,8 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
void (^addBlockArgument)(void) = ^{
RCT_ARG_BLOCK(
if (json && ![json isKindOfClass:[NSNumber class]]) {
if (RCT_DEBUG && json && ![json isKindOfClass:[NSNumber class]]) {
RCTLogError(@"Argument %tu (%@) of %@.%@ should be a number", index,
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName);
return;
@ -391,7 +392,7 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
#define RCT_CASE(_value, _class, _logic) \
case _value: { \
RCT_ARG_BLOCK( \
if (json && ![json isKindOfClass:[_class class]]) { \
if (RCT_DEBUG && json && ![json isKindOfClass:[_class class]]) { \
RCTLogError(@"Argument %tu (%@) of %@.%@ should be of type %@", index, \
json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, [_class class]); \
return; \
@ -407,7 +408,7 @@ static NSString *RCTStringUpToFirstArgument(NSString *methodName)
#define RCT_SIMPLE_CASE(_value, _type, _selector) \
case _value: { \
RCT_ARG_BLOCK( \
if (json && ![json respondsToSelector:@selector(_selector)]) { \
if (RCT_DEBUG && json && ![json respondsToSelector:@selector(_selector)]) { \
RCTLogError(@"Argument %tu (%@) of %@.%@ does not respond to selector: %@", \
index, json, RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, @#_selector); \
return; \
@ -888,6 +889,9 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
[loader loadBundleAtURL:_bundleURL onComplete:^(NSError *error) {
_loading = NO;
if (error != nil) {
#if RCT_DEBUG // Red box is only available in debug mode
NSArray *stack = [[error userInfo] objectForKey:@"stack"];
if (stack) {
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription]
@ -896,7 +900,11 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
[[RCTRedBox sharedInstance] showErrorMessage:[error localizedDescription]
withDetails:[error localizedFailureReason]];
}
#endif
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
object:self];
}
@ -936,6 +944,9 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
strongSelf.executorClass = Nil;
[strongSelf reload];
}];
#if RCT_DEV // Debug executors are only available in dev mode
// reload in debug mode
[commands registerKeyCommandWithInput:@"d"
modifierFlags:UIKeyModifierCommand
@ -952,6 +963,7 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
[strongSelf reload];
}];
#endif
#endif
}
@ -1156,14 +1168,18 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
return;
}
NSArray *requestsArray = [RCTConvert NSArray:buffer];
#if RCT_DEBUG
if (![buffer isKindOfClass:[NSArray class]]) {
RCTLogError(@"Buffer must be an instance of NSArray, got %@", NSStringFromClass([buffer class]));
return;
}
NSArray *requestsArray = (NSArray *)buffer;
NSUInteger bufferRowCount = [requestsArray count];
NSUInteger expectedFieldsCount = RCTBridgeFieldResponseReturnValues + 1;
if (bufferRowCount != expectedFieldsCount) {
RCTLogError(@"Must pass all fields to buffer - expected %zd, saw %zd", expectedFieldsCount, bufferRowCount);
return;
@ -1177,13 +1193,15 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
}
}
#endif
NSArray *moduleIDs = requestsArray[RCTBridgeFieldRequestModuleIDs];
NSArray *methodIDs = requestsArray[RCTBridgeFieldMethodIDs];
NSArray *paramsArrays = requestsArray[RCTBridgeFieldParamss];
NSUInteger numRequests = [moduleIDs count];
BOOL allSame = numRequests == [methodIDs count] && numRequests == [paramsArrays count];
if (!allSame) {
if (RCT_DEBUG && (numRequests != methodIDs.count || numRequests != paramsArrays.count)) {
RCTLogError(@"Invalid data message - all must be length: %zd", numRequests);
return;
}
@ -1217,22 +1235,25 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
params:(NSArray *)params
context:(NSNumber *)context
{
if (![params isKindOfClass:[NSArray class]]) {
if (RCT_DEBUG && ![params isKindOfClass:[NSArray class]]) {
RCTLogError(@"Invalid module/method/params tuple for request #%zd", i);
return NO;
}
// Look up method
NSArray *methods = RCTExportedMethodsByModuleID()[moduleID];
if (methodID >= methods.count) {
if (RCT_DEBUG && methodID >= methods.count) {
RCTLogError(@"Unknown methodID: %zd for module: %zd (%@)", methodID, moduleID, RCTModuleNamesByID[moduleID]);
return NO;
}
RCTModuleMethod *method = methods[methodID];
// Look up module
id module = self->_modulesByID[moduleID];
if (!module) {
if (RCT_DEBUG && !module) {
RCTLogError(@"No module found for name '%@'", RCTModuleNamesByID[moduleID]);
return NO;
}
@ -1249,13 +1270,17 @@ static id<RCTJavaScriptExecutor> _latestJSExecutor;
return;
}
@try {
if (!RCT_DEBUG) {
[method invokeWithBridge:strongSelf module:module arguments:params context:context];
}
@catch (NSException *exception) {
RCTLogError(@"Exception thrown while invoking %@ on target %@ with params %@: %@", method.JSMethodName, module, params, exception);
if ([exception.name rangeOfString:@"Unhandled JS Exception"].location != NSNotFound) {
@throw;
} else {
@try {
[method invokeWithBridge:strongSelf module:module arguments:params context:context];
}
@catch (NSException *exception) {
RCTLogError(@"Exception thrown while invoking %@ on target %@ with params %@: %@", method.JSMethodName, module, params, exception);
if ([exception.name rangeOfString:@"Unhandled JS Exception"].location != NSNotFound) {
@throw;
}
}
}

View File

@ -133,9 +133,11 @@ RCT_EXTERN BOOL RCTSetProperty(id target, NSString *keyPath, SEL type, id json);
RCT_EXTERN BOOL RCTCopyProperty(id target, id source, NSString *keyPath);
/**
* Underlying implementation of RCT_ENUM_CONVERTER macro. Ignore this.
* Underlying implementations of RCT_XXX_CONVERTER macros. Ignore these.
*/
RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
RCT_EXTERN NSArray *RCTConvertArrayValue(SEL, id);
RCT_EXTERN void RCTLogConvertError(id, const char *);
/**
* This macro is used for creating simple converter functions that just call
@ -150,18 +152,19 @@ RCT_CUSTOM_CONVERTER(type, name, [json getter])
#define RCT_CUSTOM_CONVERTER(type, name, code) \
+ (type)name:(id)json \
{ \
if (json == [NSNull null]) { \
json = nil; \
} \
@try { \
json = (json == (id)kCFNull) ? nil : json; \
if (!RCT_DEBUG) { \
return code; \
} else { \
@try { \
return code; \
} \
@catch (__unused NSException *e) { \
RCTLogConvertError(json, #type); \
json = nil; \
return code; \
} \
} \
@catch (__unused NSException *e) { \
RCTLogError(@"JSON value '%@' of type '%@' cannot be converted to '%s'", \
json, [json classForCoder], #type); \
json = nil; \
return code; \
} \
}
/**
@ -190,15 +193,8 @@ RCT_CUSTOM_CONVERTER(type, type, [[self NSNumber:json] getter])
/**
* This macro is used for creating converter functions for typed arrays.
*/
#define RCT_ARRAY_CONVERTER(type) \
+ (type##Array *)type##Array:(id)json \
{ \
NSMutableArray *values = [[NSMutableArray alloc] init]; \
for (id jsonValue in [self NSArray:json]) { \
id value = [self type:jsonValue]; \
if (value) { \
[values addObject:value]; \
} \
} \
return values; \
#define RCT_ARRAY_CONVERTER(type) \
+ (NSArray *)type##Array:(id)json \
{ \
return RCTConvertArrayValue(@selector(type:), json); \
}

View File

@ -11,8 +11,16 @@
#import <objc/message.h>
#import "RCTDefines.h"
@implementation RCTConvert
void RCTLogConvertError(id json, const char *type)
{
RCTLogError(@"JSON value '%@' of type '%@' cannot be converted to %s",
json, [json classForCoder], type);
}
RCT_CONVERTER(BOOL, BOOL, boolValue)
RCT_NUMBER_CONVERTER(double, doubleValue)
RCT_NUMBER_CONVERTER(float, floatValue)
@ -228,57 +236,52 @@ RCT_ENUM_CONVERTER(UIBarStyle, (@{
}), UIBarStyleDefault, integerValue)
// TODO: normalise the use of w/width so we can do away with the alias values (#6566645)
static void RCTConvertCGStructValue(const char *type, NSArray *fields, NSDictionary *aliases, CGFloat *result, id json)
{
NSUInteger count = fields.count;
if ([json isKindOfClass:[NSArray class]]) {
if (RCT_DEBUG && [json count] != count) {
RCTLogError(@"Expected array with count %zd, but count is %zd: %@", count, [json count], json);
} else {
for (NSUInteger i = 0; i < count; i++) {
result[i] = [RCTConvert CGFloat:json[i]];
}
}
} else if ([json isKindOfClass:[NSDictionary class]]) {
if (aliases.count) {
json = [json mutableCopy];
for (NSString *alias in aliases) {
NSString *key = aliases[alias];
NSNumber *number = json[alias];
if (number) {
RCTLogWarn(@"Using deprecated '%@' property for '%s'. Use '%@' instead.", alias, type, key);
((NSMutableDictionary *)json)[key] = number;
}
}
}
for (NSUInteger i = 0; i < count; i++) {
result[i] = [RCTConvert CGFloat:json[fields[i]]];
}
} else if (RCT_DEBUG && json && json != (id)kCFNull) {
RCTLogConvertError(json, type);
}
}
/**
* This macro is used for creating converter functions for structs that consist
* of a number of CGFloat properties, such as CGPoint, CGRect, etc.
*/
#define RCT_CGSTRUCT_CONVERTER(type, values, _aliases) \
+ (type)type:(id)json \
{ \
@try { \
static NSArray *fields; \
static NSUInteger count; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
fields = values; \
count = [fields count]; \
}); \
type result; \
if ([json isKindOfClass:[NSArray class]]) { \
if ([json count] != count) { \
RCTLogError(@"Expected array with count %zd, but count is %zd: %@", count, [json count], json); \
} else { \
for (NSUInteger i = 0; i < count; i++) { \
((CGFloat *)&result)[i] = [self CGFloat:json[i]]; \
} \
} \
} else if ([json isKindOfClass:[NSDictionary class]]) { \
NSDictionary *aliases = _aliases; \
if (aliases.count) { \
json = [json mutableCopy]; \
for (NSString *alias in aliases) { \
NSString *key = aliases[alias]; \
NSNumber *number = json[alias]; \
if (number) { \
RCTLogWarn(@"Using deprecated '%@' property for '%s'. Use '%@' instead.", alias, #type, key); \
((NSMutableDictionary *)json)[key] = number; \
} \
} \
} \
for (NSUInteger i = 0; i < count; i++) { \
((CGFloat *)&result)[i] = [self CGFloat:json[fields[i]]]; \
} \
} else if (json && json != [NSNull null]) { \
RCTLogError(@"Expected NSArray or NSDictionary for %s, received %@: %@", \
#type, [json classForCoder], json); \
} \
return result; \
} \
@catch (__unused NSException *e) { \
RCTLogError(@"JSON value '%@' cannot be converted to '%s'", json, #type); \
type result; \
return result; \
} \
#define RCT_CGSTRUCT_CONVERTER(type, values, aliases) \
+ (type)type:(id)json \
{ \
static NSArray *fields; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
fields = values; \
}); \
type result; \
RCTConvertCGStructValue(#type, fields, aliases, (CGFloat *)&result, json); \
return result; \
}
RCT_CUSTOM_CONVERTER(CGFloat, CGFloat, [self double:json])
@ -525,9 +528,7 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
} else if ([json isKindOfClass:[NSArray class]]) {
if ([json count] < 3 || [json count] > 4) {
RCTLogError(@"Expected array with count 3 or 4, but count is %zd: %@", [json count], json);
} else {
// Color array
@ -545,10 +546,9 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
blue:[self double:json[@"b"]]
alpha:[self double:json[@"a"] ?: @1]];
} else if (json && ![json isKindOfClass:[NSNull class]]) {
RCTLogError(@"Expected NSArray, NSDictionary or NSString for UIColor, received %@: %@",
[json classForCoder], json);
}
else if (RCT_DEBUG && json && json != (id)kCFNull) {
RCTLogConvertError(json, "a color");
}
// Default color
@ -573,8 +573,12 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[
// TODO: we might as well cache the result of these checks (and possibly the
// image itself) so as to reduce overhead on subsequent checks of the same input
if (![json isKindOfClass:[NSString class]]) {
RCTLogError(@"Expected NSString for UIImage, received %@: %@", [json classForCoder], json);
if (!json || json == (id)kCFNull) {
return nil;
}
if (RCT_DEBUG && ![json isKindOfClass:[NSString class]]) {
RCTLogConvertError(json, "an image");
return nil;
}
@ -761,6 +765,29 @@ static BOOL RCTFontIsCondensed(UIFont *font)
return bestMatch;
}
NSArray *RCTConvertArrayValue(SEL type, id json)
{
__block BOOL copy = NO;
__block NSArray *values = json = [RCTConvert NSArray:json];
[json enumerateObjectsUsingBlock:^(id jsonValue, NSUInteger idx, BOOL *stop) {
id value = ((id(*)(Class, SEL, id))objc_msgSend)([RCTConvert class], type, jsonValue);
if (copy) {
if (value) {
[(NSMutableArray *)values addObject:value];
}
} else if (value != jsonValue) {
// Converted value is different, so we'll need to copy the array
values = [[NSMutableArray alloc] initWithCapacity:values.count];
for (NSInteger i = 0; i < idx; i++) {
[(NSMutableArray *)values addObject:json[i]];
}
[(NSMutableArray *)values addObject:value];
copy = YES;
}
}];
return values;
}
RCT_ARRAY_CONVERTER(NSString)
RCT_ARRAY_CONVERTER(NSDictionary)
RCT_ARRAY_CONVERTER(NSURL)

View File

@ -51,7 +51,7 @@ RCT_EXTERN NSString *RCTThreadName(NSThread *);
* A method to generate a string from a collection of log data. To omit any
* particular data from the log, just pass nil or zero for the argument.
*/
NSString *RCTFormatLog(
RCT_EXTERN NSString *RCTFormatLog(
NSDate *timestamp,
NSThread *thread,
RCTLogLevel level,

View File

@ -184,7 +184,7 @@ void _RCTLogFormat(
level, fileName ? @(fileName) : nil, (lineNumber >= 0) ? @(lineNumber) : nil, message
);
if (RCT_DEBUG) {
#if RCT_DEBUG // Red box is only available in debug mode
// Log to red box
if (level >= RCTLOG_REDBOX_LEVEL) {
@ -193,6 +193,8 @@ void _RCTLogFormat(
// Log to JS executor
[RCTBridge logMessage:message level:level ? @(RCTLogLevels[level - 1]) : @"info"];
}
#endif
}
}

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEBUG // Red box is only available in debug mode
#import <UIKit/UIKit.h>
@interface RCTRedBox : NSObject
@ -23,3 +27,5 @@
- (void)dismiss;
@end
#endif

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEBUG // Red box is only available in debug mode
#import "RCTRedBox.h"
#import "RCTBridge.h"
@ -282,14 +286,12 @@
- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow
{
if (RCT_DEBUG) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!_window) {
_window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
[_window showErrorMessage:message withStack:stack showIfHidden:shouldShow];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
if (!_window) {
_window = [[RCTRedBoxWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
}
[_window showErrorMessage:message withStack:stack showIfHidden:shouldShow];
});
}
- (NSString *)currentErrorMessage
@ -307,3 +309,5 @@
}
@end
#endif

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEV // Debug executors are only supported in dev mode
#import <UIKit/UIKit.h>
#import "RCTJavaScriptExecutor.h"
@ -40,3 +44,5 @@
- (UIWebView *)invalidateAndReclaimWebView;
@end
#endif

View File

@ -7,6 +7,10 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTDefines.h"
#if RCT_DEV // Debug executors are only supported in dev mode
#import "RCTWebViewExecutor.h"
#import <objc/runtime.h>
@ -188,9 +192,14 @@ static void RCTReportError(RCTJavaScriptCallback callback, NSString *fmt, ...)
asGlobalObjectNamed:(NSString *)objectName
callback:(RCTJavaScriptCompleteBlock)onComplete
{
RCTAssert(!_objectsToInject[objectName],
@"already injected object named %@", _objectsToInject[objectName]);
if (RCT_DEBUG) {
RCTAssert(!_objectsToInject[objectName],
@"already injected object named %@", _objectsToInject[objectName]);
}
_objectsToInject[objectName] = script;
onComplete(nil);
}
@end
#endif

View File

@ -44,10 +44,11 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
return;
}
if (RCT_DEBUG) {
[[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack];
return;
}
#if RCT_DEBUG // Red box is only available in debug mode
[[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack];
#else
static NSUInteger reloadRetries = 0;
const NSUInteger maxMessageLength = 75;
@ -76,14 +77,21 @@ RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message
NSString *name = [@"Unhandled JS Exception: " stringByAppendingString:sanitizedMessage];
[NSException raise:name format:@"Message: %@, stack: %@", message, prettyStack];
}
#endif
}
RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message
stack:(NSArray *)stack)
{
if (RCT_DEBUG) {
#if RCT_DEBUG // Red box is only available in debug mode
[[RCTRedBox sharedInstance] updateErrorMessage:message withStack:stack];
}
#endif
}
@end

View File

@ -222,6 +222,7 @@ static NSString *RCTViewNameForModuleName(NSString *moduleName)
return name;
}
// TODO: only send name once instead of a dictionary of name and type keyed by name
static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewName)
{
NSMutableDictionary *nativeProps = [[NSMutableDictionary alloc] init];
@ -234,8 +235,13 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
SEL getInfo = method_getName(method);
const char *selName = sel_getName(getInfo);
if (strlen(selName) > prefixLength && strncmp(selName, prefix, prefixLength) == 0) {
NSDictionary *info = ((NSDictionary *(*)(id, SEL))method_getImplementation(method))(managerClass, getInfo);
nativeProps[info[@"name"]] = info;
NSString *name = @(selName);
NSRange nameRange = [name rangeOfString:@"_"];
if (nameRange.length) {
name = [name substringFromIndex:nameRange.location + 1];
NSString *type = ((NSString *(*)(id, SEL))method_getImplementation(method))(managerClass, getInfo);
nativeProps[name] = @{@"name": name, @"type": type};
}
}
}
return @{

View File

@ -106,6 +106,7 @@
137327E41AA5CF210034F82E /* RCTTabBarItemManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarItemManager.m; sourceTree = "<group>"; };
137327E51AA5CF210034F82E /* RCTTabBarManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTTabBarManager.h; sourceTree = "<group>"; };
137327E61AA5CF210034F82E /* RCTTabBarManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTabBarManager.m; sourceTree = "<group>"; };
1384149E1ADFCA4A003E0667 /* RCTDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTDefines.h; sourceTree = "<group>"; };
13A1F71C1A75392D00D3D453 /* RCTKeyCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTKeyCommands.h; sourceTree = "<group>"; };
13A1F71D1A75392D00D3D453 /* RCTKeyCommands.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTKeyCommands.m; sourceTree = "<group>"; };
13B07FC71A68125100A75B9A /* Layout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Layout.c; sourceTree = "<group>"; };
@ -364,6 +365,7 @@
83CBBA491A601E3B00E9B192 /* Base */ = {
isa = PBXGroup;
children = (
1384149E1ADFCA4A003E0667 /* RCTDefines.h */,
14200DA81AC179B3008EE6BA /* RCTJavaScriptLoader.h */,
14200DA91AC179B3008EE6BA /* RCTJavaScriptLoader.m */,
83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */,

View File

@ -130,11 +130,11 @@ RCT_CUSTOM_SHADOW_PROPERTY(name, type, RCTShadowView) { \
* refer to "json", "view" and "defaultView" to implement the required logic.
*/
#define RCT_CUSTOM_VIEW_PROPERTY(name, type, viewClass) \
+ (NSDictionary *)getPropConfigView_##name { return @{@"name": @#name, @"type": @#type}; } \
+ (NSString *)getPropConfigView_##name { return @#type; } \
- (void)set_##name:(id)json forView:(viewClass *)view withDefaultView:(viewClass *)defaultView
#define RCT_CUSTOM_SHADOW_PROPERTY(name, type, viewClass) \
+ (NSDictionary *)getPropConfigShadow_##name { return @{@"name": @#name, @"type": @#type}; } \
+ (NSString *)getPropConfigShadow_##name { return @#type; } \
- (void)set_##name:(id)json forShadowView:(viewClass *)view withDefaultView:(viewClass *)defaultView
/**