mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-24 04:16:00 +08:00
Second Update from Tue 24 Mar
This commit is contained in:
@@ -26,6 +26,9 @@
|
||||
+ (float)float:(id)json;
|
||||
+ (int)int:(id)json;
|
||||
|
||||
+ (int64_t)int64_t:(id)json;
|
||||
+ (uint64_t)uint64_t:(id)json;
|
||||
|
||||
+ (NSInteger)NSInteger:(id)json;
|
||||
+ (NSUInteger)NSUInteger:(id)json;
|
||||
|
||||
@@ -70,6 +73,7 @@
|
||||
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)json size:(id)json weight:(id)json;
|
||||
|
||||
+ (NSArray *)NSStringArray:(id)json;
|
||||
+ (NSArray *)NSURLArray:(id)json;
|
||||
+ (NSArray *)NSNumberArray:(id)json;
|
||||
+ (NSArray *)UIColorArray:(id)json;
|
||||
+ (NSArray *)CGColorArray:(id)json;
|
||||
@@ -142,6 +146,14 @@ id RCTConvertValue(id target, NSString *keypath, id json);
|
||||
#define RCT_CONVERTER(type, name, getter) \
|
||||
RCT_CONVERTER_CUSTOM(type, name, [json getter])
|
||||
|
||||
/**
|
||||
* This macro is similar to RCT_CONVERTER, but specifically geared towards
|
||||
* numeric types. It will handle string input correctly, and provides more
|
||||
* detailed error reporting if a wrong value is passed in.
|
||||
*/
|
||||
#define RCT_NUMBER_CONVERTER(type, getter) \
|
||||
RCT_CONVERTER_CUSTOM(type, type, [[self NSNumber:json] getter])
|
||||
|
||||
/**
|
||||
* This macro is used for creating converters for enum types.
|
||||
*/
|
||||
@@ -177,7 +189,7 @@ RCT_CONVERTER_CUSTOM(type, name, [json getter])
|
||||
* 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) \
|
||||
#define RCT_CGSTRUCT_CONVERTER(type, values, _aliases) \
|
||||
+ (type)type:(id)json \
|
||||
{ \
|
||||
@try { \
|
||||
@@ -194,12 +206,23 @@ RCT_CONVERTER_CUSTOM(type, name, [json getter])
|
||||
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] = [json[i] doubleValue]; \
|
||||
((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[key]; \
|
||||
if (number) { \
|
||||
((NSMutableDictionary *)json)[key] = number; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
for (NSUInteger i = 0; i < count; i++) { \
|
||||
((CGFloat *)&result)[i] = [json[fields[i]] doubleValue]; \
|
||||
((CGFloat *)&result)[i] = [self CGFloat:json[fields[i]]]; \
|
||||
} \
|
||||
} else if (json && json != [NSNull null]) { \
|
||||
RCTLogError(@"Expected NSArray or NSDictionary for %s, received %@: %@", #type, [json class], json); \
|
||||
|
||||
@@ -13,25 +13,39 @@
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
CGFloat const RCTDefaultFontSize = 14;
|
||||
NSString *const RCTDefaultFontName = @"HelveticaNeue";
|
||||
NSString *const RCTDefaultFontWeight = @"normal";
|
||||
NSString *const RCTBoldFontWeight = @"bold";
|
||||
|
||||
@implementation RCTConvert
|
||||
|
||||
RCT_CONVERTER(BOOL, BOOL, boolValue)
|
||||
RCT_CONVERTER(double, double, doubleValue)
|
||||
RCT_CONVERTER(float, float, floatValue)
|
||||
RCT_CONVERTER(int, int, intValue)
|
||||
RCT_NUMBER_CONVERTER(double, doubleValue)
|
||||
RCT_NUMBER_CONVERTER(float, floatValue)
|
||||
RCT_NUMBER_CONVERTER(int, intValue)
|
||||
|
||||
RCT_CONVERTER(NSInteger, NSInteger, integerValue)
|
||||
RCT_CONVERTER_CUSTOM(NSUInteger, NSUInteger, [json unsignedIntegerValue])
|
||||
RCT_NUMBER_CONVERTER(int64_t, longLongValue);
|
||||
RCT_NUMBER_CONVERTER(uint64_t, unsignedLongLongValue);
|
||||
|
||||
RCT_NUMBER_CONVERTER(NSInteger, integerValue)
|
||||
RCT_NUMBER_CONVERTER(NSUInteger, unsignedIntegerValue)
|
||||
|
||||
RCT_CONVERTER_CUSTOM(NSArray *, NSArray, [NSArray arrayWithArray:json])
|
||||
RCT_CONVERTER_CUSTOM(NSDictionary *, NSDictionary, [NSDictionary dictionaryWithDictionary:json])
|
||||
RCT_CONVERTER(NSString *, NSString, description)
|
||||
RCT_CONVERTER_CUSTOM(NSNumber *, NSNumber, @([json doubleValue]))
|
||||
|
||||
+ (NSNumber *)NSNumber:(id)json
|
||||
{
|
||||
if ([json isKindOfClass:[NSNumber class]]) {
|
||||
return json;
|
||||
} else if ([json isKindOfClass:[NSString class]]) {
|
||||
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
|
||||
NSNumber *number = [formatter numberFromString:json];
|
||||
if (!number) {
|
||||
RCTLogError(@"JSON String '%@' could not be interpreted as a number", json);
|
||||
}
|
||||
return number;
|
||||
} else if (json && json != [NSNull null]) {
|
||||
RCTLogError(@"JSON value '%@' of class %@ could not be interpreted as a number", json, [json class]);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSURL *)NSURL:(id)json
|
||||
{
|
||||
@@ -47,7 +61,12 @@ RCT_CONVERTER_CUSTOM(NSNumber *, NSNumber, @([json doubleValue]))
|
||||
}
|
||||
else if ([path length])
|
||||
{
|
||||
return [NSURL URLWithString:path relativeToURL:[[NSBundle mainBundle] resourceURL]];
|
||||
NSURL *URL = [NSURL URLWithString:path relativeToURL:[[NSBundle mainBundle] resourceURL]];
|
||||
if ([URL isFileURL] &&![[NSFileManager defaultManager] fileExistsAtPath:[URL absoluteString]]) {
|
||||
RCTLogWarn(@"The file '%@' does not exist", URL);
|
||||
return nil;
|
||||
}
|
||||
return URL;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
@@ -58,11 +77,11 @@ RCT_CONVERTER_CUSTOM(NSNumber *, NSNumber, @([json doubleValue]))
|
||||
}
|
||||
|
||||
// JS Standard for time is milliseconds
|
||||
RCT_CONVERTER_CUSTOM(NSDate *, NSDate, [NSDate dateWithTimeIntervalSince1970:[json doubleValue] / 1000.0])
|
||||
RCT_CONVERTER_CUSTOM(NSTimeInterval, NSTimeInterval, [json doubleValue] / 1000.0)
|
||||
RCT_CONVERTER_CUSTOM(NSDate *, NSDate, [NSDate dateWithTimeIntervalSince1970:[self double:json] / 1000.0])
|
||||
RCT_CONVERTER_CUSTOM(NSTimeInterval, NSTimeInterval, [self double:json] / 1000.0)
|
||||
|
||||
// JS standard for time zones is minutes.
|
||||
RCT_CONVERTER_CUSTOM(NSTimeZone *, NSTimeZone, [NSTimeZone timeZoneForSecondsFromGMT:[json doubleValue] * 60.0])
|
||||
RCT_CONVERTER_CUSTOM(NSTimeZone *, NSTimeZone, [NSTimeZone timeZoneForSecondsFromGMT:[self double:json] * 60.0])
|
||||
|
||||
RCT_ENUM_CONVERTER(NSTextAlignment, (@{
|
||||
@"auto": @(NSTextAlignmentNatural),
|
||||
@@ -90,11 +109,12 @@ RCT_ENUM_CONVERTER(UIKeyboardType, (@{
|
||||
@"default": @(UIKeyboardTypeDefault),
|
||||
}), UIKeyboardTypeDefault, integerValue)
|
||||
|
||||
RCT_CONVERTER(CGFloat, CGFloat, doubleValue)
|
||||
RCT_CGSTRUCT_CONVERTER(CGPoint, (@[@"x", @"y"]))
|
||||
RCT_CGSTRUCT_CONVERTER(CGSize, (@[@"w", @"h"]))
|
||||
RCT_CGSTRUCT_CONVERTER(CGRect, (@[@"x", @"y", @"w", @"h"]))
|
||||
RCT_CGSTRUCT_CONVERTER(UIEdgeInsets, (@[@"top", @"left", @"bottom", @"right"]))
|
||||
// TODO: normalise the use of w/width so we can do away with the alias values (#6566645)
|
||||
RCT_CONVERTER_CUSTOM(CGFloat, CGFloat, [self double:json])
|
||||
RCT_CGSTRUCT_CONVERTER(CGPoint, (@[@"x", @"y"]), nil)
|
||||
RCT_CGSTRUCT_CONVERTER(CGSize, (@[@"width", @"height"]), (@{@"w": @"width", @"h": @"height"}))
|
||||
RCT_CGSTRUCT_CONVERTER(CGRect, (@[@"x", @"y", @"width", @"height"]), (@{@"w": @"width", @"h": @"height"}))
|
||||
RCT_CGSTRUCT_CONVERTER(UIEdgeInsets, (@[@"top", @"left", @"bottom", @"right"]), nil)
|
||||
|
||||
RCT_ENUM_CONVERTER(CGLineJoin, (@{
|
||||
@"miter": @(kCGLineJoinMiter),
|
||||
@@ -113,9 +133,9 @@ RCT_CGSTRUCT_CONVERTER(CATransform3D, (@[
|
||||
@"m21", @"m22", @"m23", @"m24",
|
||||
@"m31", @"m32", @"m33", @"m34",
|
||||
@"m41", @"m42", @"m43", @"m44"
|
||||
]))
|
||||
]), nil)
|
||||
|
||||
RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]))
|
||||
RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty"]), nil)
|
||||
|
||||
+ (UIColor *)UIColor:(id)json
|
||||
{
|
||||
@@ -328,19 +348,19 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
|
||||
} else {
|
||||
|
||||
// Color array
|
||||
color = [UIColor colorWithRed:[json[0] doubleValue]
|
||||
green:[json[1] doubleValue]
|
||||
blue:[json[2] doubleValue]
|
||||
alpha:[json count] > 3 ? [json[3] doubleValue] : 1];
|
||||
color = [UIColor colorWithRed:[self double:json[0]]
|
||||
green:[self double:json[1]]
|
||||
blue:[self double:json[2]]
|
||||
alpha:[json count] > 3 ? [self double:json[3]] : 1];
|
||||
}
|
||||
|
||||
} else if ([json isKindOfClass:[NSDictionary class]]) {
|
||||
|
||||
// Color dictionary
|
||||
color = [UIColor colorWithRed:[json[@"r"] doubleValue]
|
||||
green:[json[@"g"] doubleValue]
|
||||
blue:[json[@"b"] doubleValue]
|
||||
alpha:[json[@"a"] ?: @1 doubleValue]];
|
||||
color = [UIColor colorWithRed:[self double:json[@"r"]]
|
||||
green:[self double:json[@"g"]]
|
||||
blue:[self double:json[@"b"]]
|
||||
alpha:[self double:json[@"a"] ?: @1]];
|
||||
|
||||
} else if (json && ![json isKindOfClass:[NSNull class]]) {
|
||||
|
||||
@@ -415,6 +435,11 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
|
||||
|
||||
+ (UIFont *)UIFont:(UIFont *)font withFamily:(id)family size:(id)size weight:(id)weight
|
||||
{
|
||||
CGFloat const RCTDefaultFontSize = 14;
|
||||
NSString *const RCTDefaultFontName = @"HelveticaNeue";
|
||||
NSString *const RCTDefaultFontWeight = @"normal";
|
||||
NSString *const RCTBoldFontWeight = @"bold";
|
||||
|
||||
// Create descriptor
|
||||
UIFontDescriptor *fontDescriptor = font.fontDescriptor ?: [UIFontDescriptor fontDescriptorWithName:RCTDefaultFontName size:RCTDefaultFontSize];
|
||||
|
||||
@@ -427,7 +452,7 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
|
||||
// Get font family
|
||||
NSString *familyName = [self NSString:family];
|
||||
if (familyName) {
|
||||
if ([UIFont fontNamesForFamilyName:familyName].count == 0) {
|
||||
if ([UIFont fontNamesForFamilyName:familyName].count == 0) {
|
||||
font = [UIFont fontWithName:familyName size:fontDescriptor.pointSize];
|
||||
if (font) {
|
||||
// It's actually a font name, not a font family name,
|
||||
@@ -437,11 +462,14 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
|
||||
} else {
|
||||
// Not a valid font or family
|
||||
RCTLogError(@"Unrecognized font family '%@'", familyName);
|
||||
familyName = [UIFont fontWithDescriptor:fontDescriptor size:0].familyName;
|
||||
}
|
||||
} else {
|
||||
// Set font family
|
||||
fontDescriptor = [fontDescriptor fontDescriptorWithFamily:familyName];
|
||||
}
|
||||
} else {
|
||||
familyName = [UIFont fontWithDescriptor:fontDescriptor size:0].familyName;
|
||||
}
|
||||
|
||||
// Get font weight
|
||||
@@ -451,29 +479,43 @@ RCT_CGSTRUCT_CONVERTER(CGAffineTransform, (@[@"a", @"b", @"c", @"d", @"tx", @"ty
|
||||
static NSSet *values;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
values = [NSSet setWithObjects:@"bold", @"normal", nil];
|
||||
values = [NSSet setWithObjects:RCTDefaultFontWeight, RCTBoldFontWeight, nil];
|
||||
});
|
||||
|
||||
if (fontWeight && ![values containsObject:fontWeight]) {
|
||||
RCTLogError(@"Unrecognized font weight '%@', must be one of %@", fontWeight, values);
|
||||
fontWeight = RCTDefaultFontWeight;
|
||||
}
|
||||
|
||||
UIFontDescriptorSymbolicTraits symbolicTraits = fontDescriptor.symbolicTraits;
|
||||
// this is hacky. we are appending the string -Medium because most fonts we currently use
|
||||
// just need to have -Medium appended to get the bold we want. we're going to revamp this
|
||||
// to make it easier to know which options are available in JS. t4996115
|
||||
if ([fontWeight isEqualToString:RCTBoldFontWeight]) {
|
||||
symbolicTraits |= UIFontDescriptorTraitBold;
|
||||
} else {
|
||||
symbolicTraits &= ~UIFontDescriptorTraitBold;
|
||||
font = nil;
|
||||
for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
|
||||
if ([fontName hasSuffix:@"-Medium"]) {
|
||||
font = [UIFont fontWithName:fontName size:fontDescriptor.pointSize];
|
||||
break;
|
||||
}
|
||||
if ([fontName hasSuffix:@"-Bold"]) {
|
||||
font = [UIFont fontWithName:fontName size:fontDescriptor.pointSize];
|
||||
// But keep searching in case there's a medium option
|
||||
}
|
||||
}
|
||||
if (font) {
|
||||
fontDescriptor = font.fontDescriptor;
|
||||
}
|
||||
}
|
||||
fontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:symbolicTraits];
|
||||
}
|
||||
|
||||
// TODO: font style
|
||||
|
||||
// Create font
|
||||
return [UIFont fontWithDescriptor:fontDescriptor size:fontDescriptor.pointSize];
|
||||
return [UIFont fontWithDescriptor:fontDescriptor size:0];
|
||||
}
|
||||
|
||||
RCT_ARRAY_CONVERTER(NSString)
|
||||
RCT_ARRAY_CONVERTER(NSURL)
|
||||
RCT_ARRAY_CONVERTER(NSNumber)
|
||||
RCT_ARRAY_CONVERTER(UIColor)
|
||||
|
||||
@@ -729,6 +771,9 @@ static id RCTConvertValueWithExplicitEncoding(id target, NSString *key, id json,
|
||||
@"extAlignment": ^(id val) {
|
||||
return [RCTConvert NSTextAlignment:val];
|
||||
},
|
||||
@"ritingDirection": ^(id val) {
|
||||
return [RCTConvert NSWritingDirection:val];
|
||||
},
|
||||
@"Cap": ^(id val) {
|
||||
return [RCTConvert CGLineCap:val];
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#import "RCTBridge.h"
|
||||
|
||||
@interface RCTRootView : UIView
|
||||
@interface RCTRootView : UIView<RCTInvalidating>
|
||||
|
||||
/**
|
||||
* The URL of the bundled application script (required).
|
||||
|
||||
@@ -29,6 +29,7 @@ NSString *const RCTReloadNotification = @"RCTReloadNotification";
|
||||
RCTBridge *_bridge;
|
||||
RCTTouchHandler *_touchHandler;
|
||||
id<RCTJavaScriptExecutor> _executor;
|
||||
BOOL _registered;
|
||||
}
|
||||
|
||||
static Class _globalExecutorClass;
|
||||
@@ -36,7 +37,7 @@ static Class _globalExecutorClass;
|
||||
+ (void)initialize
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
|
||||
// Register Cmd-R as a global refresh key
|
||||
[[RCTKeyCommands sharedInstance] registerKeyCommandWithInput:@"r"
|
||||
@@ -106,12 +107,32 @@ static Class _globalExecutorClass;
|
||||
|
||||
[_bridge enqueueJSCall:@"ReactIOS.unmountComponentAtNodeAndRemoveContainer"
|
||||
args:@[self.reactTag]];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
#pragma mark - RCTInvalidating
|
||||
|
||||
- (BOOL)isValid
|
||||
{
|
||||
return [_bridge isValid];
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
// Clear view
|
||||
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
[self removeGestureRecognizer:_touchHandler];
|
||||
[_touchHandler invalidate];
|
||||
[_executor invalidate];
|
||||
|
||||
// TODO: eventually we'll want to be able to share the bridge between
|
||||
// multiple rootviews, in which case we'll need to move this elsewhere
|
||||
[_bridge invalidate];
|
||||
}
|
||||
|
||||
#pragma mark Bundle loading
|
||||
|
||||
- (void)bundleFinishedLoading:(NSError *)error
|
||||
{
|
||||
if (error != nil) {
|
||||
@@ -124,6 +145,7 @@ static Class _globalExecutorClass;
|
||||
} else {
|
||||
|
||||
[_bridge.uiManager registerRootView:self];
|
||||
_registered = YES;
|
||||
|
||||
NSString *moduleName = _moduleName ?: @"";
|
||||
NSDictionary *appParameters = @{
|
||||
@@ -137,8 +159,7 @@ static Class _globalExecutorClass;
|
||||
|
||||
- (void)loadBundle
|
||||
{
|
||||
// Clear view
|
||||
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
[self invalidate];
|
||||
|
||||
if (!_scriptURL) {
|
||||
return;
|
||||
@@ -150,6 +171,8 @@ static Class _globalExecutorClass;
|
||||
[_executor invalidate];
|
||||
[_bridge invalidate];
|
||||
|
||||
_registered = NO;
|
||||
|
||||
// Choose local executor if specified, followed by global, followed by default
|
||||
_executor = [[_executorClass ?: _globalExecutorClass ?: [RCTContextExecutor class] alloc] init];
|
||||
_bridge = [[RCTBridge alloc] initWithExecutor:_executor moduleProvider:_moduleProvider];
|
||||
@@ -209,15 +232,20 @@ static Class _globalExecutorClass;
|
||||
[self bundleFinishedLoading:error];
|
||||
return;
|
||||
}
|
||||
if (!_bridge.isValid) {
|
||||
return; // Bridge was invalidated in the meanwhile
|
||||
}
|
||||
|
||||
// Success!
|
||||
RCTSourceCode *sourceCodeModule = _bridge.modules[NSStringFromClass([RCTSourceCode class])];
|
||||
sourceCodeModule.scriptURL = _scriptURL;
|
||||
sourceCodeModule.scriptText = rawText;
|
||||
|
||||
[_bridge enqueueApplicationScript:rawText url:_scriptURL onComplete:^(NSError *error) {
|
||||
[_bridge enqueueApplicationScript:rawText url:_scriptURL onComplete:^(NSError *_error) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self bundleFinishedLoading:error];
|
||||
if (_bridge.isValid) {
|
||||
[self bundleFinishedLoading:_error];
|
||||
}
|
||||
});
|
||||
}];
|
||||
|
||||
@@ -236,9 +264,12 @@ static Class _globalExecutorClass;
|
||||
[self loadBundle];
|
||||
}
|
||||
|
||||
- (BOOL)isReactRootView
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
return YES;
|
||||
[super layoutSubviews];
|
||||
if (_registered) {
|
||||
[_bridge.uiManager setFrame:self.frame forRootView:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reload
|
||||
|
||||
@@ -129,13 +129,15 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
|
||||
// Find closest React-managed touchable view
|
||||
UIView *targetView = touch.view;
|
||||
while (targetView) {
|
||||
if (targetView.reactTag && targetView.userInteractionEnabled) { // TODO: implement respondsToTouch: mechanism
|
||||
if (targetView.reactTag && targetView.userInteractionEnabled &&
|
||||
[targetView reactRespondsToTouch:touch]) {
|
||||
break;
|
||||
}
|
||||
targetView = targetView.superview;
|
||||
}
|
||||
|
||||
if (!targetView.reactTag || !targetView.userInteractionEnabled) {
|
||||
NSNumber *reactTag = [targetView reactTagAtPoint:[touch locationInView:targetView]];
|
||||
if (!reactTag || !targetView.userInteractionEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,7 +157,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
|
||||
|
||||
// Create touch
|
||||
NSMutableDictionary *reactTouch = [[NSMutableDictionary alloc] initWithCapacity:9];
|
||||
reactTouch[@"target"] = [targetView reactTagAtPoint:[touch locationInView:targetView]];
|
||||
reactTouch[@"target"] = reactTag;
|
||||
reactTouch[@"identifier"] = @(touchID);
|
||||
reactTouch[@"touches"] = [NSNull null]; // We hijack this touchObj to serve both as an event
|
||||
reactTouch[@"changedTouches"] = [NSNull null]; // and as a Touch object, so making this JIT friendly.
|
||||
@@ -248,15 +250,15 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
|
||||
|
||||
if (_recordingInteractionTiming) {
|
||||
[_bridgeInteractionTiming addObject:@{
|
||||
@"timeSeconds": @(touch.originatingTime),
|
||||
@"operation": @"taskOriginated",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
@"timeSeconds": @(touch.originatingTime),
|
||||
@"operation": @"taskOriginated",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
[_bridgeInteractionTiming addObject:@{
|
||||
@"timeSeconds": @(enqueueTime),
|
||||
@"operation": @"taskEnqueuedPending",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
@"timeSeconds": @(enqueueTime),
|
||||
@"operation": @"taskEnqueuedPending",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,18 +275,18 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
|
||||
if (_recordingInteractionTiming) {
|
||||
for (RCTTouchEvent *touch in _pendingTouches) {
|
||||
[_bridgeInteractionTiming addObject:@{
|
||||
@"timeSeconds": @(sender.timestamp),
|
||||
@"operation": @"frameAlignedDispatch",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
@"timeSeconds": @(sender.timestamp),
|
||||
@"operation": @"frameAlignedDispatch",
|
||||
@"taskID": @(touch.id),
|
||||
}];
|
||||
}
|
||||
|
||||
if (pendingCount > 0 || sender.timestamp - _mostRecentEnqueueJS < 0.1) {
|
||||
[_bridgeInteractionTiming addObject:@{
|
||||
@"timeSeconds": @(sender.timestamp),
|
||||
@"operation": @"mainThreadDisplayLink",
|
||||
@"taskID": @([RCTTouchEvent newID]),
|
||||
}];
|
||||
@"timeSeconds": @(sender.timestamp),
|
||||
@"operation": @"mainThreadDisplayLink",
|
||||
@"taskID": @([RCTTouchEvent newID]),
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,14 @@ id RCTJSONParse(NSString *jsonString, NSError **error)
|
||||
}
|
||||
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
|
||||
if (!jsonData) {
|
||||
RCTLog(@"RCTJSONParse received the following string, which could not be losslessly converted to UTF8 data: '%@'", jsonString);
|
||||
jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
|
||||
if (jsonData) {
|
||||
RCTLogWarn(@"RCTJSONParse received the following string, which could not be losslessly converted to UTF8 data: '%@'", jsonString);
|
||||
} else {
|
||||
// If our backup conversion fails, log the issue so we can see what strings are causing this (t6452813)
|
||||
RCTLogError(@"RCTJSONParse received the following string, which could not be converted to UTF8 data: '%@'", jsonString);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:error];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user