diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj index 8469b9dc6..40e9ef5f1 100644 --- a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj +++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj @@ -51,7 +51,7 @@ 14D6D7291B2222EF001FB087 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AADF041AC3DB95002390C9 /* libReact.a */; }; 14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; }; 3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; }; - 3D36915B1BDA8CBB007B22D8 /* uie_thumb_big.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D36915A1BDA8CBB007B22D8 /* uie_thumb_big.png */; settings = {ASSET_TAGS = (); }; }; + 3D36915B1BDA8CBB007B22D8 /* uie_thumb_big.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D36915A1BDA8CBB007B22D8 /* uie_thumb_big.png */; }; 3DB99D0C1BA0340600302749 /* UIExplorerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB99D0B1BA0340600302749 /* UIExplorerIntegrationTests.m */; }; 834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; }; 83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; }; @@ -1082,6 +1082,7 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -1109,6 +1110,7 @@ WARNING_CFLAGS = ( "-Wextra", "-Wall", + "-Wincompatible-pointer-types", ); }; name = Debug; @@ -1139,6 +1141,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -1166,6 +1169,7 @@ WARNING_CFLAGS = ( "-Wextra", "-Wall", + "-Wincompatible-pointer-types", ); }; name = Release; diff --git a/Libraries/ART/Brushes/ARTLinearGradient.m b/Libraries/ART/Brushes/ARTLinearGradient.m index 8793ff07b..e34fd59fd 100644 --- a/Libraries/ART/Brushes/ARTLinearGradient.m +++ b/Libraries/ART/Brushes/ARTLinearGradient.m @@ -19,7 +19,7 @@ CGPoint _endPoint; } -- (instancetype)initWithArray:(NSArray *)array +- (instancetype)initWithArray:(NSArray *)array { if ((self = [super initWithArray:array])) { if (array.count < 5) { diff --git a/Libraries/ART/Brushes/ARTPattern.m b/Libraries/ART/Brushes/ARTPattern.m index 07dd86700..a0e6d5a5d 100644 --- a/Libraries/ART/Brushes/ARTPattern.m +++ b/Libraries/ART/Brushes/ARTPattern.m @@ -18,7 +18,7 @@ CGRect _rect; } -- (instancetype)initWithArray:(NSArray *)array +- (instancetype)initWithArray:(NSArray *)array { if ((self = [super initWithArray:array])) { if (array.count < 6) { diff --git a/Libraries/ART/Brushes/ARTRadialGradient.m b/Libraries/ART/Brushes/ARTRadialGradient.m index b59b17369..cb3ae65a2 100644 --- a/Libraries/ART/Brushes/ARTRadialGradient.m +++ b/Libraries/ART/Brushes/ARTRadialGradient.m @@ -21,7 +21,7 @@ CGFloat _radiusRatio; } -- (instancetype)initWithArray:(NSArray *)array +- (instancetype)initWithArray:(NSArray *)array { if ((self = [super initWithArray:array])) { if (array.count < 7) { diff --git a/Libraries/ART/Brushes/ARTSolidColor.m b/Libraries/ART/Brushes/ARTSolidColor.m index 229942dde..bfeff00bd 100644 --- a/Libraries/ART/Brushes/ARTSolidColor.m +++ b/Libraries/ART/Brushes/ARTSolidColor.m @@ -17,7 +17,7 @@ CGColorRef _color; } -- (instancetype)initWithArray:(NSArray *)array +- (instancetype)initWithArray:(NSArray *)array { if ((self = [super initWithArray:array])) { _color = CGColorRetain([RCTConvert CGColor:array offset:1]); diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.m b/Libraries/ActionSheetIOS/RCTActionSheetManager.m index dbc10a46e..841292bc3 100644 --- a/Libraries/ActionSheetIOS/RCTActionSheetManager.m +++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.m @@ -62,7 +62,7 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options } NSString *title = [RCTConvert NSString:options[@"title"]]; - NSArray *buttons = [RCTConvert NSStringArray:options[@"options"]]; + NSArray *buttons = [RCTConvert NSStringArray:options[@"options"]]; NSInteger destructiveButtonIndex = options[@"destructiveButtonIndex"] ? [RCTConvert NSInteger:options[@"destructiveButtonIndex"]] : -1; NSInteger cancelButtonIndex = options[@"cancelButtonIndex"] ? [RCTConvert NSInteger:options[@"cancelButtonIndex"]] : -1; @@ -151,7 +151,7 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options return; } - NSMutableArray *items = [NSMutableArray array]; + NSMutableArray *items = [NSMutableArray array]; NSString *message = [RCTConvert NSString:options[@"message"]]; if (message) { [items addObject:message]; diff --git a/Libraries/CameraRoll/RCTCameraRollManager.h b/Libraries/CameraRoll/RCTCameraRollManager.h index 51921b7ed..30407c9f6 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.h +++ b/Libraries/CameraRoll/RCTCameraRollManager.h @@ -7,7 +7,17 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#import + #import "RCTBridgeModule.h" +#import "RCTConvert.h" + +@interface RCTConvert (ALAssetGroup) + ++ (ALAssetsGroupType)ALAssetsGroupType:(id)json; ++ (ALAssetsFilter *)ALAssetsFilter:(id)json; + +@end @interface RCTCameraRollManager : NSObject diff --git a/Libraries/CameraRoll/RCTCameraRollManager.m b/Libraries/CameraRoll/RCTCameraRollManager.m index ba3696856..e2044f03c 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.m +++ b/Libraries/CameraRoll/RCTCameraRollManager.m @@ -9,17 +9,70 @@ #import "RCTCameraRollManager.h" -#import #import #import #import #import "RCTAssetsLibraryImageLoader.h" #import "RCTBridge.h" +#import "RCTConvert.h" #import "RCTImageLoader.h" #import "RCTLog.h" #import "RCTUtils.h" +@implementation RCTConvert (ALAssetGroup) + +RCT_ENUM_CONVERTER(ALAssetsGroupType, (@{ + + // New values + @"album": @(ALAssetsGroupAlbum), + @"all": @(ALAssetsGroupAll), + @"event": @(ALAssetsGroupEvent), + @"faces": @(ALAssetsGroupFaces), + @"library": @(ALAssetsGroupLibrary), + @"photo-stream": @(ALAssetsGroupPhotoStream), + @"saved-photos": @(ALAssetsGroupSavedPhotos), + + // Legacy values + @"Album": @(ALAssetsGroupAlbum), + @"All": @(ALAssetsGroupAll), + @"Event": @(ALAssetsGroupEvent), + @"Faces": @(ALAssetsGroupFaces), + @"Library": @(ALAssetsGroupLibrary), + @"PhotoStream": @(ALAssetsGroupPhotoStream), + @"SavedPhotos": @(ALAssetsGroupSavedPhotos), + +}), ALAssetsGroupSavedPhotos, integerValue) + ++ (ALAssetsFilter *)ALAssetsFilter:(id)json +{ + static NSDictionary *options; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + options = @{ + + // New values + @"photos": [ALAssetsFilter allPhotos], + @"videos": [ALAssetsFilter allVideos], + @"all": [ALAssetsFilter allAssets], + + // Legacy values + @"Photos": [ALAssetsFilter allPhotos], + @"Videos": [ALAssetsFilter allVideos], + @"All": [ALAssetsFilter allAssets], + }; + }); + + ALAssetsFilter *filter = options[json ?: @"photos"]; + if (!filter) { + RCTLogError(@"Invalid filter option: '%@'. Expected one of 'photos'," + "'videos' or 'all'.", json); + } + return filter ?: [ALAssetsFilter allPhotos]; +} + +@end + @implementation RCTCameraRollManager RCT_EXPORT_MODULE() @@ -49,7 +102,9 @@ RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag }]; } -- (void)callCallback:(RCTResponseSenderBlock)callback withAssets:(NSArray *)assets hasNextPage:(BOOL)hasNextPage +- (void)callCallback:(RCTResponseSenderBlock)callback + withAssets:(NSArray *)assets + hasNextPage:(BOOL)hasNextPage { if (!assets.count) { callback(@[@{ @@ -72,45 +127,21 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params callback:(RCTResponseSenderBlock)callback errorCallback:(RCTResponseErrorBlock)errorCallback) { - NSUInteger first = [params[@"first"] integerValue]; - NSString *afterCursor = params[@"after"]; - NSString *groupTypesStr = params[@"groupTypes"]; - NSString *groupName = params[@"groupName"]; - NSString *assetType = params[@"assetType"]; - ALAssetsGroupType groupTypes; - - if ([groupTypesStr isEqualToString:@"Album"]) { - groupTypes = ALAssetsGroupAlbum; - } else if ([groupTypesStr isEqualToString:@"All"]) { - groupTypes = ALAssetsGroupAll; - } else if ([groupTypesStr isEqualToString:@"Event"]) { - groupTypes = ALAssetsGroupEvent; - } else if ([groupTypesStr isEqualToString:@"Faces"]) { - groupTypes = ALAssetsGroupFaces; - } else if ([groupTypesStr isEqualToString:@"Library"]) { - groupTypes = ALAssetsGroupLibrary; - } else if ([groupTypesStr isEqualToString:@"PhotoStream"]) { - groupTypes = ALAssetsGroupPhotoStream; - } else { - groupTypes = ALAssetsGroupSavedPhotos; - } + NSUInteger first = [RCTConvert NSInteger:params[@"first"]]; + NSString *afterCursor = [RCTConvert NSString:params[@"after"]]; + NSString *groupName = [RCTConvert NSString:params[@"groupName"]]; + ALAssetsFilter *assetType = [RCTConvert ALAssetsFilter:params[@"assetType"]]; + ALAssetsGroupType groupTypes = [RCTConvert ALAssetsGroupType:params[@"groupTypes"]]; BOOL __block foundAfter = NO; BOOL __block hasNextPage = NO; BOOL __block calledCallback = NO; - NSMutableArray *assets = [NSMutableArray new]; + NSMutableArray *assets = [NSMutableArray new]; [_bridge.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) { if (group && (groupName == nil || [groupName isEqualToString:[group valueForProperty:ALAssetsGroupPropertyName]])) { - if (assetType == nil || [assetType isEqualToString:@"Photos"]) { - [group setAssetsFilter:ALAssetsFilter.allPhotos]; - } else if ([assetType isEqualToString:@"Videos"]) { - [group setAssetsFilter:ALAssetsFilter.allVideos]; - } else if ([assetType isEqualToString:@"All"]) { - [group setAssetsFilter:ALAssetsFilter.allAssets]; - } - + [group setAssetsFilter:assetType]; [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopAssets) { if (result) { NSString *uri = ((NSURL *)[result valueForProperty:ALAssetPropertyAssetURL]).absoluteString; diff --git a/Libraries/CameraRoll/RCTImagePickerManager.m b/Libraries/CameraRoll/RCTImagePickerManager.m index 281149196..c778c1f48 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.m +++ b/Libraries/CameraRoll/RCTImagePickerManager.m @@ -23,9 +23,9 @@ @implementation RCTImagePickerManager { - NSMutableArray *_pickers; - NSMutableArray *_pickerCallbacks; - NSMutableArray *_pickerCancelCallbacks; + NSMutableArray *_pickers; + NSMutableArray *_pickerCallbacks; + NSMutableArray *_pickerCancelCallbacks; } RCT_EXPORT_MODULE(ImagePickerIOS); @@ -42,7 +42,7 @@ RCT_EXPORT_MODULE(ImagePickerIOS); RCT_EXPORT_METHOD(canRecordVideos:(RCTResponseSenderBlock)callback) { - NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]; + NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]; callback(@[@([availableMediaTypes containsObject:(NSString *)kUTTypeMovie])]); } @@ -59,7 +59,7 @@ RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config cancelCallback(@[@"Camera access is unavailable in an app extension"]); return; } - + UIWindow *keyWindow = RCTSharedApplication().keyWindow; UIViewController *rootViewController = keyWindow.rootViewController; @@ -86,7 +86,7 @@ RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config cancelCallback(@[@"Image picker is currently unavailable in an app extension"]); return; } - + UIWindow *keyWindow = RCTSharedApplication().keyWindow; UIViewController *rootViewController = keyWindow.rootViewController; @@ -94,7 +94,7 @@ RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config imagePicker.delegate = self; imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; - NSMutableArray *allowedTypes = [NSMutableArray new]; + NSMutableArray *allowedTypes = [NSMutableArray new]; if ([config[@"showImages"] boolValue]) { [allowedTypes addObject:(NSString *)kUTTypeImage]; } diff --git a/Libraries/Geolocation/RCTLocationObserver.m b/Libraries/Geolocation/RCTLocationObserver.m index ebb66f4e1..b97011630 100644 --- a/Libraries/Geolocation/RCTLocationObserver.m +++ b/Libraries/Geolocation/RCTLocationObserver.m @@ -100,7 +100,7 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg / { CLLocationManager *_locationManager; NSDictionary *_lastLocationEvent; - NSMutableArray *_pendingRequests; + NSMutableArray *_pendingRequests; BOOL _observingLocation; RCTLocationOptions _observerOptions; } @@ -249,7 +249,8 @@ RCT_EXPORT_METHOD(getCurrentPosition:(RCTLocationOptions)options #pragma mark - CLLocationManagerDelegate -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations +- (void)locationManager:(CLLocationManager *)manager + didUpdateLocations:(NSArray *)locations { // Create event CLLocation *location = locations.lastObject; diff --git a/Libraries/Image/RCTGIFImageDecoder.m b/Libraries/Image/RCTGIFImageDecoder.m index 899a266e8..473210025 100644 --- a/Libraries/Image/RCTGIFImageDecoder.m +++ b/Libraries/Image/RCTGIFImageDecoder.m @@ -42,8 +42,8 @@ RCT_EXPORT_MODULE() if (imageCount > 1) { NSTimeInterval duration = 0; - NSMutableArray *delays = [NSMutableArray arrayWithCapacity:imageCount]; - NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount]; + NSMutableArray *delays = [NSMutableArray arrayWithCapacity:imageCount]; + NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount]; for (size_t i = 0; i < imageCount; i++) { CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, i, NULL); @@ -75,7 +75,7 @@ RCT_EXPORT_MODULE() } CFRelease(imageSource); - NSMutableArray *keyTimes = [NSMutableArray arrayWithCapacity:delays.count]; + NSMutableArray *keyTimes = [NSMutableArray arrayWithCapacity:delays.count]; NSTimeInterval runningDuration = 0; for (NSNumber *delayNumber in delays) { [keyTimes addObject:@(runningDuration / duration)]; diff --git a/Libraries/Image/RCTImageLoader.m b/Libraries/Image/RCTImageLoader.m index 99641387a..d298f8cea 100644 --- a/Libraries/Image/RCTImageLoader.m +++ b/Libraries/Image/RCTImageLoader.m @@ -35,8 +35,8 @@ @implementation RCTImageLoader { - NSArray *_loaders; - NSArray *_decoders; + NSArray> *_loaders; + NSArray> *_decoders; NSURLCache *_cache; } @@ -47,14 +47,14 @@ RCT_EXPORT_MODULE() - (void)setBridge:(RCTBridge *)bridge { // Get image loaders and decoders - NSMutableArray *loaders = [NSMutableArray array]; - NSMutableArray *decoders = [NSMutableArray array]; + NSMutableArray> *loaders = [NSMutableArray array]; + NSMutableArray> *decoders = [NSMutableArray array]; for (id module in bridge.modules.allValues) { if ([module conformsToProtocol:@protocol(RCTImageURLLoader)]) { - [loaders addObject:module]; + [loaders addObject:(id)module]; } if ([module conformsToProtocol:@protocol(RCTImageDataDecoder)]) { - [decoders addObject:module]; + [decoders addObject:(id)module]; } } diff --git a/Libraries/Network/RCTHTTPRequestHandler.m b/Libraries/Network/RCTHTTPRequestHandler.m index 961bedb22..f52a20426 100644 --- a/Libraries/Network/RCTHTTPRequestHandler.m +++ b/Libraries/Network/RCTHTTPRequestHandler.m @@ -47,7 +47,7 @@ RCT_EXPORT_MODULE() - (BOOL)canHandleRequest:(NSURLRequest *)request { - static NSSet *schemes = nil; + static NSSet *schemes = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // technically, RCTHTTPRequestHandler can handle file:// as well, diff --git a/Libraries/Network/RCTNetworking.m b/Libraries/Network/RCTNetworking.m index 7d5e1fd2c..b1450a631 100644 --- a/Libraries/Network/RCTNetworking.m +++ b/Libraries/Network/RCTNetworking.m @@ -37,7 +37,7 @@ typedef RCTURLRequestCancellationBlock (^RCTHTTPQueryResult)(NSError *error, NSD @implementation RCTHTTPFormDataHelper { - NSMutableArray *_parts; + NSMutableArray *_parts; NSMutableData *_multipartBody; RCTHTTPQueryResult _callback; NSString *_boundary; @@ -122,7 +122,7 @@ static NSString *RCTGenerateFormBoundary() @implementation RCTNetworking { NSMutableDictionary *_tasksByRequestID; - NSArray *_handlers; + NSArray> *_handlers; } @synthesize bridge = _bridge; @@ -133,10 +133,10 @@ RCT_EXPORT_MODULE() - (void)setBridge:(RCTBridge *)bridge { // get handlers - NSMutableArray *handlers = [NSMutableArray array]; + NSMutableArray> *handlers = [NSMutableArray array]; for (id module in bridge.modules.allValues) { if ([module conformsToProtocol:@protocol(RCTURLRequestHandler)]) { - [handlers addObject:module]; + [handlers addObject:(id)module]; } } diff --git a/Libraries/RCTTest/RCTTestRunner.h b/Libraries/RCTTest/RCTTestRunner.h index efde32f21..097bef6bf 100644 --- a/Libraries/RCTTest/RCTTestRunner.h +++ b/Libraries/RCTTest/RCTTestRunner.h @@ -22,6 +22,8 @@ referenceDirectory:@FB_REFERENCE_IMAGE_DIR \ moduleProvider:(moduleProvider__)] +@protocol RCTBridgeModule; + @interface RCTTestRunner : NSObject @property (nonatomic, assign) BOOL recordMode; @@ -37,7 +39,7 @@ */ - (instancetype)initWithApp:(NSString *)app referenceDirectory:(NSString *)referenceDirectory - moduleProvider:(NSArray *(^)(void))block NS_DESIGNATED_INITIALIZER; + moduleProvider:(NSArray> *(^)(void))block NS_DESIGNATED_INITIALIZER; /** * Simplest runTest function simply mounts the specified JS module with no diff --git a/Libraries/RCTTest/RCTTestRunner.m b/Libraries/RCTTest/RCTTestRunner.m index ea67bbe36..13d38247b 100644 --- a/Libraries/RCTTest/RCTTestRunner.m +++ b/Libraries/RCTTest/RCTTestRunner.m @@ -126,7 +126,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) RCTSetLogFunction(RCTDefaultLogFunction); - NSArray *nonLayoutSubviews = [vc.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) { + NSArray *nonLayoutSubviews = [vc.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) { return ![NSStringFromClass([subview class]) isEqualToString:@"_UILayoutGuide"]; }]]; RCTAssert(nonLayoutSubviews.count == 0, @"There shouldn't be any other views: %@", nonLayoutSubviews); diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index 33e8c8485..b29b5accb 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -80,7 +80,7 @@ static css_dim_t RCTMeasure(void *context, float width) [self dirtyText]; } -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks +- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties { parentProperties = [super processUpdatedProperties:applierBlocks @@ -99,7 +99,7 @@ static css_dim_t RCTMeasure(void *context, float width) } - (void)applyLayoutNode:(css_node_t *)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame + viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame absolutePosition:(CGPoint)absolutePosition { [super applyLayoutNode:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition]; diff --git a/Libraries/Text/RCTText.m b/Libraries/Text/RCTText.m index 47b7de6a5..c45287917 100644 --- a/Libraries/Text/RCTText.m +++ b/Libraries/Text/RCTText.m @@ -16,7 +16,7 @@ @implementation RCTText { NSTextStorage *_textStorage; - NSMutableArray *_reactSubviews; + NSMutableArray *_reactSubviews; CAShapeLayer *_highlightLayer; } @@ -62,7 +62,7 @@ [_reactSubviews removeObject:subview]; } -- (NSArray *)reactSubviews +- (NSArray *)reactSubviews { return _reactSubviews; } diff --git a/Libraries/Text/RCTTextField.m b/Libraries/Text/RCTTextField.m index 2593f0137..954ae827f 100644 --- a/Libraries/Text/RCTTextField.m +++ b/Libraries/Text/RCTTextField.m @@ -17,7 +17,7 @@ @implementation RCTTextField { RCTEventDispatcher *_eventDispatcher; - NSMutableArray *_reactSubviews; + NSMutableArray *_reactSubviews; BOOL _jsRequestingFirstResponder; NSInteger _nativeEventCount; } @@ -92,7 +92,7 @@ static void RCTUpdatePlaceholder(RCTTextField *self) RCTUpdatePlaceholder(self); } -- (NSArray *)reactSubviews +- (NSArray *)reactSubviews { // TODO: do we support subviews of textfield in React? // In any case, we should have a better approach than manually diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m index 1b205ca08..a67cb6cd2 100644 --- a/Libraries/Text/RCTTextManager.m +++ b/Libraries/Text/RCTTextManager.m @@ -65,7 +65,7 @@ RCT_EXPORT_SHADOW_PROPERTY(allowFontScaling, BOOL) continue; } - NSMutableArray *queue = [NSMutableArray arrayWithObject:rootView]; + NSMutableArray *queue = [NSMutableArray arrayWithObject:rootView]; for (NSInteger i = 0; i < queue.count; i++) { RCTShadowView *shadowView = queue[i]; RCTAssert([shadowView isTextDirty], @"Don't process any nodes that don't have dirty text"); diff --git a/Libraries/WebSocket/RCTSRWebSocket.h b/Libraries/WebSocket/RCTSRWebSocket.h index c185daca9..0c209c21c 100644 --- a/Libraries/WebSocket/RCTSRWebSocket.h +++ b/Libraries/WebSocket/RCTSRWebSocket.h @@ -60,11 +60,11 @@ extern NSString *const RCTSRHTTPResponseErrorKey; @property (nonatomic, readonly, copy) NSString *protocol; // Protocols should be an array of strings that turn into Sec-WebSocket-Protocol. -- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols NS_DESIGNATED_INITIALIZER; - (instancetype)initWithURLRequest:(NSURLRequest *)request; // Some helper constructors. -- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray *)protocols; +- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray *)protocols; - (instancetype)initWithURL:(NSURL *)url; // Delegate queue will be dispatch_main_queue by default. diff --git a/Libraries/WebSocket/RCTSRWebSocket.m b/Libraries/WebSocket/RCTSRWebSocket.m index 4085d750c..a345f373a 100644 --- a/Libraries/WebSocket/RCTSRWebSocket.m +++ b/Libraries/WebSocket/RCTSRWebSocket.m @@ -186,7 +186,7 @@ typedef void (^data_callback)(RCTSRWebSocket *webSocket, NSData *data); dispatch_queue_t _delegateDispatchQueue; dispatch_queue_t _workQueue; - NSMutableArray *_consumers; + NSMutableArray *_consumers; NSInputStream *_inputStream; NSOutputStream *_outputStream; @@ -228,12 +228,12 @@ typedef void (^data_callback)(RCTSRWebSocket *webSocket, NSData *data); BOOL _isPumping; - NSMutableSet *_scheduledRunloops; + NSMutableSet *_scheduledRunloops; // We use this to retain ourselves. __strong RCTSRWebSocket *_selfRetain; - NSArray *_requestedProtocols; + NSArray *_requestedProtocols; RCTSRIOConsumerPool *_consumerPool; } @@ -244,7 +244,7 @@ static __strong NSData *CRLFCRLF; CRLFCRLF = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4]; } -- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols; +- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols; { RCTAssertParam(request); @@ -271,7 +271,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) return [self initWithURL:URL protocols:nil]; } -- (instancetype)initWithURL:(NSURL *)URL protocols:(NSArray *)protocols; +- (instancetype)initWithURL:(NSURL *)URL protocols:(NSArray *)protocols; { NSURLRequest *request = URL ? [NSURLRequest requestWithURL:URL] : nil; return [self initWithURLRequest:request protocols:protocols]; @@ -1456,7 +1456,7 @@ static const size_t RCTSRFrameHeaderOverhead = 32; @implementation RCTSRIOConsumerPool { NSUInteger _poolSize; - NSMutableArray *_bufferedConsumers; + NSMutableArray *_bufferedConsumers; } - (instancetype)initWithBufferCapacity:(NSUInteger)poolSize; diff --git a/React/Base/RCTAssert.m b/React/Base/RCTAssert.m index 80bb6d65b..7d242ba9a 100644 --- a/React/Base/RCTAssert.m +++ b/React/Base/RCTAssert.m @@ -59,7 +59,7 @@ void RCTAddAssertFunction(RCTAssertFunction assertFunction) static RCTAssertFunction RCTGetLocalAssertFunction() { NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary; - NSArray *functionStack = threadDictionary[RCTAssertFunctionStack]; + NSArray *functionStack = threadDictionary[RCTAssertFunctionStack]; RCTAssertFunction assertFunction = functionStack.lastObject; if (assertFunction) { return assertFunction; @@ -70,7 +70,7 @@ static RCTAssertFunction RCTGetLocalAssertFunction() void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction) { NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary; - NSMutableArray *functionStack = threadDictionary[RCTAssertFunctionStack]; + NSMutableArray *functionStack = threadDictionary[RCTAssertFunctionStack]; if (!functionStack) { functionStack = [NSMutableArray new]; threadDictionary[RCTAssertFunctionStack] = functionStack; diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index 1e3687609..da7f33e14 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -11,6 +11,7 @@ #import "RCTAssert.h" #import "RCTBridge.h" +#import "RCTBridgeMethod.h" #import "RCTConvert.h" #import "RCTContextExecutor.h" #import "RCTFrameUpdate.h" @@ -18,7 +19,6 @@ #import "RCTLog.h" #import "RCTModuleData.h" #import "RCTModuleMap.h" -#import "RCTBridgeMethod.h" #import "RCTPerformanceLogger.h" #import "RCTProfile.h" #import "RCTRedBox.h" @@ -43,7 +43,7 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) { RCTBridgeFieldParamss, }; -RCT_EXTERN NSArray *RCTGetModuleClasses(void); +RCT_EXTERN NSArray *RCTGetModuleClasses(void); @interface RCTBridge () @@ -64,11 +64,11 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void); BOOL _valid; BOOL _wasBatchActive; __weak id _javaScriptExecutor; - NSMutableArray *_pendingCalls; - NSMutableArray *_moduleDataByID; + NSMutableArray *_pendingCalls; + NSMutableArray *_moduleDataByID; RCTModuleMap *_modulesByName; CADisplayLink *_jsDisplayLink; - NSMutableSet *_frameUpdateObservers; + NSMutableSet *_frameUpdateObservers; } - (instancetype)initWithParentBridge:(RCTBridge *)bridge @@ -233,7 +233,7 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void); // Register passed-in module instances NSMutableDictionary *preregisteredModules = [NSMutableDictionary new]; - NSArray *extraModules = nil; + NSArray> *extraModules = nil; if (self.delegate) { if ([self.delegate respondsToSelector:@selector(extraModulesForBridge:)]) { extraModules = [self.delegate extraModulesForBridge:_parentBridge]; @@ -308,12 +308,11 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void); - (NSString *)moduleConfig { - NSMutableArray *config = [NSMutableArray new]; + NSMutableArray *config = [NSMutableArray new]; for (RCTModuleData *moduleData in _moduleDataByID) { [config addObject:moduleData.config]; if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) { [_frameUpdateObservers addObject:moduleData]; - id observer = (id)moduleData.instance; __weak typeof(self) weakSelf = self; __weak typeof(_javaScriptExecutor) weakJavaScriptExecutor = _javaScriptExecutor; @@ -417,7 +416,7 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void); _loading = NO; - NSArray *stack = error.userInfo[@"stack"]; + NSArray *stack = error.userInfo[@"stack"]; if (stack) { [self.redBox showErrorMessage:error.localizedDescription withStack:stack]; } else { @@ -559,7 +558,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR */ - (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args { - NSArray *ids = [moduleDotMethod componentsSeparatedByString:@"."]; + NSArray *ids = [moduleDotMethod componentsSeparatedByString:@"."]; [self _invokeAndProcessModule:@"BatchedBridge" method:@"callFunctionReturnFlushedQueue" @@ -698,57 +697,45 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR } } -- (void)handleBuffer:(id)buffer +- (void)handleBuffer:(NSArray *)buffer { - NSArray *requestsArray = [RCTConvert NSArray:buffer]; + NSArray *requestsArray = [RCTConvert NSArrayArray:buffer]; -#if RCT_DEBUG - - if (![buffer isKindOfClass:[NSArray class]]) { - RCTLogError(@"Buffer must be an instance of NSArray, got %@", NSStringFromClass([buffer class])); + if (RCT_DEBUG && requestsArray.count <= RCTBridgeFieldParamss) { + RCTLogError(@"Buffer should contain at least %tu sub-arrays. Only found %tu", + RCTBridgeFieldParamss + 1, requestsArray.count); return; } - for (NSUInteger fieldIndex = RCTBridgeFieldRequestModuleIDs; fieldIndex <= RCTBridgeFieldParamss; fieldIndex++) { - id field = requestsArray[fieldIndex]; - if (![field isKindOfClass:[NSArray class]]) { - RCTLogError(@"Field at index %zd in buffer must be an instance of NSArray, got %@", fieldIndex, NSStringFromClass([field class])); - return; - } - } + NSArray *moduleIDs = requestsArray[RCTBridgeFieldRequestModuleIDs]; + NSArray *methodIDs = requestsArray[RCTBridgeFieldMethodIDs]; + NSArray *paramsArrays = requestsArray[RCTBridgeFieldParamss]; -#endif - - NSArray *moduleIDs = requestsArray[RCTBridgeFieldRequestModuleIDs]; - NSArray *methodIDs = requestsArray[RCTBridgeFieldMethodIDs]; - NSArray *paramsArrays = requestsArray[RCTBridgeFieldParamss]; - - NSUInteger numRequests = moduleIDs.count; - - if (RCT_DEBUG && (numRequests != methodIDs.count || numRequests != paramsArrays.count)) { - RCTLogError(@"Invalid data message - all must be length: %zd", numRequests); + if (RCT_DEBUG && (moduleIDs.count != methodIDs.count || moduleIDs.count != paramsArrays.count)) { + RCTLogError(@"Invalid data message - all must be length: %zd", moduleIDs.count); return; } NSMapTable *buckets = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsStrongMemory capacity:_moduleDataByID.count]; - for (NSUInteger i = 0; i < numRequests; i++) { - RCTModuleData *moduleData = _moduleDataByID[[moduleIDs[i] integerValue]]; + + [moduleIDs enumerateObjectsUsingBlock:^(NSNumber *moduleID, NSUInteger i, __unused BOOL *stop) { + RCTModuleData *moduleData = _moduleDataByID[moduleID.integerValue]; if (RCT_DEBUG) { // verify that class has been registered (void)_modulesByName[moduleData.name]; } - id queue = [moduleData queue]; - NSMutableOrderedSet *set = [buckets objectForKey:queue]; + dispatch_queue_t queue = moduleData.queue; + NSMutableOrderedSet *set = [buckets objectForKey:queue]; if (!set) { set = [NSMutableOrderedSet new]; [buckets setObject:set forKey:queue]; } [set addObject:@(i)]; - } + }]; - for (id queue in buckets) { + for (dispatch_queue_t queue in buckets) { RCTProfileBeginFlowEvent(); dispatch_block_t block = ^{ diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 88bcf8971..c16786b45 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -52,7 +52,7 @@ RCT_EXTERN NSString *const RCTDidCreateNativeModules; * For this reason, the block should always return new module instances, and * module instances should not be shared between bridges. */ -typedef NSArray *(^RCTBridgeModuleProviderBlock)(void); +typedef NSArray> *(^RCTBridgeModuleProviderBlock)(void); /** * This function returns the module name for a given class. diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 4334be311..189cdb096 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -39,9 +39,9 @@ NSString *const RCTDidCreateNativeModules = @"RCTDidCreateNativeModules"; @end -static NSMutableArray *RCTModuleClasses; -NSArray *RCTGetModuleClasses(void); -NSArray *RCTGetModuleClasses(void) +static NSMutableArray *RCTModuleClasses; +NSArray *RCTGetModuleClasses(void); +NSArray *RCTGetModuleClasses(void) { return RCTModuleClasses; } diff --git a/React/Base/RCTBridgeDelegate.h b/React/Base/RCTBridgeDelegate.h index a8a3c937f..2e6e8387a 100644 --- a/React/Base/RCTBridgeDelegate.h +++ b/React/Base/RCTBridgeDelegate.h @@ -10,6 +10,7 @@ typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source); @class RCTBridge; +@protocol RCTBridgeModule; @protocol RCTBridgeDelegate @@ -17,7 +18,7 @@ typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source); @optional -- (NSArray *)extraModulesForBridge:(RCTBridge *)bridge; +- (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge; - (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback; @end diff --git a/React/Base/RCTBridgeModule.h b/React/Base/RCTBridgeModule.h index 93f8f6e98..07c6932b5 100644 --- a/React/Base/RCTBridgeModule.h +++ b/React/Base/RCTBridgeModule.h @@ -12,6 +12,7 @@ #import "RCTDefines.h" @class RCTBridge; +@protocol RCTBridgeMethod; /** * The type of a block that is capable of sending a response to a bridged @@ -208,7 +209,8 @@ RCT_EXTERN void RCTRegisterModule(Class); \ * Like RCT_EXTERN_REMAP_METHOD, but allows setting a custom JavaScript name. */ #define RCT_EXTERN_REMAP_METHOD(js_name, method) \ - + (NSArray *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \ + + (NSArray *)RCT_CONCAT(__rct_export__, \ + RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \ return @[@#js_name, @#method]; \ } @@ -217,7 +219,7 @@ RCT_EXTERN void RCTRegisterModule(Class); \ * methods defined using the macros above. This method is called only once, * before registration. */ -- (NSArray *)methodsToExport; +- (NSArray> *)methodsToExport; /** * Injects constants into JS. These constants are made accessible via diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index d03140e08..7dbcab6d8 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -96,25 +96,28 @@ typedef NSURL RCTFileURL; scaleMultiplier:(CGFloat)scaleMultiplier; typedef NSArray NSArrayArray; -+ (NSArrayArray *)NSArrayArray:(id)json; ++ (NSArray *)NSArrayArray:(id)json; typedef NSArray NSStringArray; -+ (NSStringArray *)NSStringArray:(id)json; ++ (NSArray *)NSStringArray:(id)json; + +typedef NSArray NSStringArrayArray; ++ (NSArray *> *)NSStringArrayArray:(id)json; typedef NSArray NSDictionaryArray; -+ (NSDictionaryArray *)NSDictionaryArray:(id)json; ++ (NSArray *)NSDictionaryArray:(id)json; typedef NSArray NSURLArray; -+ (NSURLArray *)NSURLArray:(id)json; ++ (NSArray *)NSURLArray:(id)json; typedef NSArray RCTFileURLArray; -+ (RCTFileURLArray *)RCTFileURLArray:(id)json; ++ (NSArray *)RCTFileURLArray:(id)json; typedef NSArray NSNumberArray; -+ (NSNumberArray *)NSNumberArray:(id)json; ++ (NSArray *)NSNumberArray:(id)json; typedef NSArray UIColorArray; -+ (UIColorArray *)UIColorArray:(id)json; ++ (NSArray *)UIColorArray:(id)json; typedef NSArray CGColorArray; + (CGColorArray *)CGColorArray:(id)json; @@ -223,7 +226,7 @@ RCT_CUSTOM_CONVERTER(type, type, [RCT_DEBUG ? [self NSNumber:json] : json getter * This macro is used for creating converter functions for typed arrays. */ #define RCT_ARRAY_CONVERTER(type) \ -+ (NSArray *)type##Array:(id)json \ ++ (NSArray *)type##Array:(id)json \ { \ return RCTConvertArrayValue(@selector(type:), json); \ } diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 822108d31..bcf5876ca 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -711,6 +711,7 @@ RCT_ARRAY_CONVERTER(UIColor) RCT_JSON_ARRAY_CONVERTER(NSArray) RCT_JSON_ARRAY_CONVERTER(NSString) +RCT_JSON_ARRAY_CONVERTER(NSStringArray) RCT_JSON_ARRAY_CONVERTER(NSDictionary) RCT_JSON_ARRAY_CONVERTER(NSNumber) diff --git a/React/Base/RCTEventDispatcher.m b/React/Base/RCTEventDispatcher.m index 39503f9ab..d8d6f3268 100644 --- a/React/Base/RCTEventDispatcher.m +++ b/React/Base/RCTEventDispatcher.m @@ -209,7 +209,7 @@ RCT_EXPORT_MODULE() - (void)dispatchEvent:(id)event { - NSMutableArray *arguments = [NSMutableArray new]; + NSMutableArray *arguments = [NSMutableArray new]; if (event.viewTag) { [arguments addObject:event.viewTag]; @@ -221,8 +221,7 @@ RCT_EXPORT_MODULE() [arguments addObject:event.body]; } - [_bridge enqueueJSCall:[[event class] moduleDotMethod] - args:arguments]; + [_bridge enqueueJSCall:[[event class] moduleDotMethod] args:arguments]; } - (dispatch_queue_t)methodQueue diff --git a/React/Base/RCTJavaScriptLoader.m b/React/Base/RCTJavaScriptLoader.m index 889f136a0..763e36893 100755 --- a/React/Base/RCTJavaScriptLoader.m +++ b/React/Base/RCTJavaScriptLoader.m @@ -82,7 +82,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) NSDictionary *errorDetails = RCTJSONParse(rawText, nil); if ([errorDetails isKindOfClass:[NSDictionary class]] && [errorDetails[@"errors"] isKindOfClass:[NSArray class]]) { - NSMutableArray *fakeStack = [NSMutableArray new]; + NSMutableArray *fakeStack = [NSMutableArray new]; for (NSDictionary *err in errorDetails[@"errors"]) { [fakeStack addObject: @{ @"methodName": err[@"description"] ?: @"", diff --git a/React/Base/RCTKeyCommands.m b/React/Base/RCTKeyCommands.m index 36516bbc1..92747519f 100644 --- a/React/Base/RCTKeyCommands.m +++ b/React/Base/RCTKeyCommands.m @@ -77,15 +77,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) @interface RCTKeyCommands () -@property (nonatomic, strong) NSMutableSet *commands; +@property (nonatomic, strong) NSMutableSet *commands; @end @implementation UIResponder (RCTKeyCommands) -- (NSArray *)RCT_keyCommands +- (NSArray *)RCT_keyCommands { - NSSet *commands = [RCTKeyCommands sharedInstance].commands; + NSSet *commands = [RCTKeyCommands sharedInstance].commands; return [[commands valueForKeyPath:@"keyCommand"] allObjects]; } diff --git a/React/Base/RCTLog.m b/React/Base/RCTLog.m index 5f8420aef..bc095afaf 100644 --- a/React/Base/RCTLog.m +++ b/React/Base/RCTLog.m @@ -120,7 +120,7 @@ void RCTAddLogFunction(RCTLogFunction logFunction) static RCTLogFunction RCTGetLocalLogFunction() { NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary; - NSArray *functionStack = threadDictionary[RCTLogFunctionStack]; + NSArray *functionStack = threadDictionary[RCTLogFunctionStack]; RCTLogFunction logFunction = functionStack.lastObject; if (logFunction) { return logFunction; @@ -131,7 +131,7 @@ static RCTLogFunction RCTGetLocalLogFunction() void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction) { NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary; - NSMutableArray *functionStack = threadDictionary[RCTLogFunctionStack]; + NSMutableArray *functionStack = threadDictionary[RCTLogFunctionStack]; if (!functionStack) { functionStack = [NSMutableArray new]; threadDictionary[RCTLogFunctionStack] = functionStack; @@ -216,8 +216,9 @@ void _RCTLogInternal( // Log to red box if ([UIApplication sharedApplication] && level >= RCTLOG_REDBOX_LEVEL) { - NSArray *stackSymbols = [NSThread callStackSymbols]; - NSMutableArray *stack = [NSMutableArray arrayWithCapacity:(stackSymbols.count - 1)]; + NSArray *stackSymbols = [NSThread callStackSymbols]; + NSMutableArray *stack = + [NSMutableArray arrayWithCapacity:(stackSymbols.count - 1)]; [stackSymbols enumerateObjectsUsingBlock:^(NSString *frameSymbols, NSUInteger idx, __unused BOOL *stop) { if (idx > 0) { // don't include the current frame NSString *address = [[frameSymbols componentsSeparatedByString:@"0x"][1] componentsSeparatedByString:@" "][0]; diff --git a/React/Base/RCTModuleData.h b/React/Base/RCTModuleData.h index d01ccbdd7..cc3747eae 100644 --- a/React/Base/RCTModuleData.h +++ b/React/Base/RCTModuleData.h @@ -11,6 +11,8 @@ #import "RCTJavaScriptExecutor.h" +@protocol RCTBridgeMethod; + @interface RCTModuleData : NSObject @property (nonatomic, weak, readonly) id javaScriptExecutor; @@ -19,7 +21,7 @@ @property (nonatomic, strong, readonly) Class moduleClass; @property (nonatomic, copy, readonly) NSString *name; -@property (nonatomic, copy, readonly) NSArray *methods; +@property (nonatomic, copy, readonly) NSArray> *methods; @property (nonatomic, copy, readonly) NSArray *config; @property (nonatomic, strong) dispatch_queue_t queue; diff --git a/React/Base/RCTModuleData.m b/React/Base/RCTModuleData.m index c7db2d4d9..ddd0384d4 100644 --- a/React/Base/RCTModuleData.m +++ b/React/Base/RCTModuleData.m @@ -17,10 +17,11 @@ @implementation RCTModuleData { NSDictionary *_constants; - NSArray *_methods; NSString *_queueName; } +@synthesize methods = _methods; + - (instancetype)initWithExecutor:(id)javaScriptExecutor moduleID:(NSNumber *)moduleID instance:(id)instance @@ -46,10 +47,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); -- (NSArray *)methods +- (NSArray> *)methods { if (!_methods) { - NSMutableArray *moduleMethods = [NSMutableArray new]; + NSMutableArray> *moduleMethods = [NSMutableArray new]; if ([_instance respondsToSelector:@selector(methodsToExport)]) { [moduleMethods addObjectsFromArray:[_instance methodsToExport]]; @@ -63,11 +64,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); SEL selector = method_getName(method); if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) { IMP imp = method_getImplementation(method); - NSArray *entries = ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector); + NSArray *entries = + ((NSArray *(*)(id, SEL))imp)(_moduleClass, selector); id moduleMethod = - [[RCTModuleMethod alloc] initWithObjCMethodName:entries[1] - JSMethodName:entries[0] - moduleClass:_moduleClass]; + [[RCTModuleMethod alloc] initWithObjCMethodName:entries[1] + JSMethodName:entries[0] + moduleClass:_moduleClass]; [moduleMethods addObject:moduleMethod]; } @@ -86,8 +88,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init); return (id)kCFNull; // Nothing to export } - NSMutableArray *methods = self.methods.count ? [NSMutableArray new] : nil; - NSMutableArray *asyncMethods = nil; + NSMutableArray *methods = self.methods.count ? [NSMutableArray new] : nil; + NSMutableArray *asyncMethods = nil; for (id method in self.methods) { if (method.functionType == RCTFunctionTypePromise) { if (!asyncMethods) { diff --git a/React/Base/RCTModuleMap.m b/React/Base/RCTModuleMap.m index 5491c1256..fef338763 100644 --- a/React/Base/RCTModuleMap.m +++ b/React/Base/RCTModuleMap.m @@ -69,7 +69,7 @@ extern BOOL RCTBridgeModuleClassIsRegistered(Class cls); return [_modulesByName keyEnumerator]; } -- (NSArray *)allValues +- (NSArray> *)allValues { // don't perform validation in this case because we only want to error when // an invalid module is specifically requested diff --git a/React/Base/RCTModuleMethod.m b/React/Base/RCTModuleMethod.m index f484142fc..c35017c98 100644 --- a/React/Base/RCTModuleMethod.m +++ b/React/Base/RCTModuleMethod.m @@ -47,7 +47,7 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id); { Class _moduleClass; NSInvocation *_invocation; - NSArray *_argumentBlocks; + NSArray *_argumentBlocks; NSString *_objCMethodName; SEL _selector; NSDictionary *_profileArgs; @@ -66,8 +66,8 @@ static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index, RCT_NOT_IMPLEMENTED(- (instancetype)init) -void RCTParseObjCMethodName(NSString **, NSArray **); -void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments) +void RCTParseObjCMethodName(NSString **, NSArray **); +void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments) { static NSRegularExpression *typeNameRegex; static dispatch_once_t onceToken; @@ -148,7 +148,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments) - (void)processMethodSignature { - NSArray *arguments; + NSArray *arguments; NSString *objCMethodName = _objCMethodName; RCTParseObjCMethodName(&objCMethodName, &arguments); @@ -164,7 +164,8 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments) // Process arguments NSUInteger numberOfArguments = methodSignature.numberOfArguments; - NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2]; + NSMutableArray *argumentBlocks = + [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2]; #define RCT_ARG_BLOCK(_logic) \ [argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) { \ diff --git a/React/Base/RCTPerformanceLogger.h b/React/Base/RCTPerformanceLogger.h index f84db3d1a..499617df1 100644 --- a/React/Base/RCTPerformanceLogger.h +++ b/React/Base/RCTPerformanceLogger.h @@ -25,5 +25,5 @@ typedef NS_ENUM(NSUInteger, RCTPLTag) { void RCTPerformanceLoggerStart(RCTPLTag tag); void RCTPerformanceLoggerEnd(RCTPLTag tag); void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value); -NSArray *RCTPerformanceLoggerOutput(void); +NSArray *RCTPerformanceLoggerOutput(void); NSArray *RCTPerformanceLoggerLabels(void); diff --git a/React/Base/RCTPerformanceLogger.m b/React/Base/RCTPerformanceLogger.m index 012850cd8..f099db677 100644 --- a/React/Base/RCTPerformanceLogger.m +++ b/React/Base/RCTPerformanceLogger.m @@ -36,7 +36,7 @@ void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value) RCTPLData[tag][1] = value; } -NSArray *RCTPerformanceLoggerOutput(void) +NSArray *RCTPerformanceLoggerOutput(void) { return @[ @(RCTPLData[RCTPLScriptDownload][0]), diff --git a/React/Base/RCTSparseArray.h b/React/Base/RCTSparseArray.h index 806f27315..78410d72d 100644 --- a/React/Base/RCTSparseArray.h +++ b/React/Base/RCTSparseArray.h @@ -27,7 +27,7 @@ - (id)objectForKeyedSubscript:(NSNumber *)key; @property (readonly, nonatomic) NSUInteger count; -@property (readonly, nonatomic, copy) NSArray *allIndexes; +@property (readonly, nonatomic, copy) NSArray *allIndexes; @property (readonly, nonatomic, copy) NSArray *allObjects; - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSNumber *idx, BOOL *stop))block; diff --git a/React/Base/RCTSparseArray.m b/React/Base/RCTSparseArray.m index 1c67df644..76e01d677 100644 --- a/React/Base/RCTSparseArray.m +++ b/React/Base/RCTSparseArray.m @@ -79,7 +79,7 @@ return _storage.count; } -- (NSArray *)allIndexes +- (NSArray *)allIndexes { return _storage.allKeys; } diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index eb902b8eb..707830aab 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -31,9 +31,9 @@ * These must be kept track of because `UIKit` destroys the touch targets * if touches are canceled, and we have no other way to recover this info. */ - NSMutableOrderedSet *_nativeTouches; - NSMutableArray *_reactTouches; - NSMutableArray *_touchViews; + NSMutableOrderedSet *_nativeTouches; + NSMutableArray *_reactTouches; + NSMutableArray *_touchViews; BOOL _dispatchedInitialTouches; BOOL _recordingInteractionTiming; @@ -71,7 +71,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { #pragma mark - Bookkeeping for touch indices -- (void)_recordNewTouches:(NSSet *)touches +- (void)_recordNewTouches:(NSSet *)touches { for (UITouch *touch in touches) { @@ -121,7 +121,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { } } -- (void)_recordRemovedTouches:(NSSet *)touches +- (void)_recordRemovedTouches:(NSSet *)touches { for (UITouch *touch in touches) { NSUInteger index = [_nativeTouches indexOfObject:touch]; @@ -163,12 +163,12 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { * (start/end/move/cancel) and the indices that represent "changed" `Touch`es * from that array. */ -- (void)_updateAndDispatchTouches:(NSSet *)touches +- (void)_updateAndDispatchTouches:(NSSet *)touches eventName:(NSString *)eventName originatingTime:(__unused CFTimeInterval)originatingTime { // Update touches - NSMutableArray *changedIndexes = [NSMutableArray new]; + NSMutableArray *changedIndexes = [NSMutableArray new]; for (UITouch *touch in touches) { NSInteger index = [_nativeTouches indexOfObject:touch]; if (index == NSNotFound) { @@ -185,7 +185,8 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { // Deep copy the touches because they will be accessed from another thread // TODO: would it be safer to do this in the bridge or executor, rather than trusting caller? - NSMutableArray *reactTouches = [[NSMutableArray alloc] initWithCapacity:_reactTouches.count]; + NSMutableArray *reactTouches = + [[NSMutableArray alloc] initWithCapacity:_reactTouches.count]; for (NSDictionary *touch in _reactTouches) { [reactTouches addObject:[touch copy]]; } @@ -197,7 +198,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) { #pragma mark - Gesture Recognizer Delegate Callbacks -static BOOL RCTAllTouchesAreCancelledOrEnded(NSSet *touches) +static BOOL RCTAllTouchesAreCancelledOrEnded(NSSet *touches) { for (UITouch *touch in touches) { if (touch.phase == UITouchPhaseBegan || @@ -209,7 +210,7 @@ static BOOL RCTAllTouchesAreCancelledOrEnded(NSSet *touches) return YES; } -static BOOL RCTAnyTouchesChanged(NSSet *touches) +static BOOL RCTAnyTouchesChanged(NSSet *touches) { for (UITouch *touch in touches) { if (touch.phase == UITouchPhaseBegan || @@ -238,7 +239,7 @@ static BOOL RCTAnyTouchesChanged(NSSet *touches) // dispatch the updates from the raw touch methods below. } -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; @@ -253,7 +254,7 @@ static BOOL RCTAnyTouchesChanged(NSSet *touches) } } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; @@ -263,7 +264,7 @@ static BOOL RCTAnyTouchesChanged(NSSet *touches) } } -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesEnded:touches withEvent:event]; @@ -279,7 +280,7 @@ static BOOL RCTAnyTouchesChanged(NSSet *touches) [self _recordRemovedTouches:touches]; } -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesCancelled:touches withEvent:event]; diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index 1f915e66d..de25e3728 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -60,7 +60,11 @@ RCT_EXTERN UIApplication *RCTSharedApplication(void); // Return a UIAlertView initialized with the given values // or nil if running in an app extension -RCT_EXTERN UIAlertView *RCTAlertView(NSString *title, NSString *message, id delegate, NSString *cancelButtonTitle, NSArray *otherButtonTitles); +RCT_EXTERN UIAlertView *RCTAlertView(NSString *title, + NSString *message, + id delegate, + NSString *cancelButtonTitle, + NSArray *otherButtonTitles); // Return YES if image has an alpha component RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index f1faa9004..f59577d79 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -24,7 +24,7 @@ NSString *RCTJSONStringify(id jsonObject, NSError **error) { static SEL JSONKitSelector = NULL; - static NSSet *collectionTypes; + static NSSet *collectionTypes; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SEL selector = NSSelectorFromString(@"JSONStringWithOptions:error:"); @@ -121,7 +121,7 @@ id RCTJSONParseMutable(NSString *jsonString, NSError **error) id RCTJSONClean(id object) { static dispatch_once_t onceToken; - static NSSet *validLeafTypes; + static NSSet *validLeafTypes; dispatch_once(&onceToken, ^{ validLeafTypes = [[NSSet alloc] initWithArray:@[ [NSString class], @@ -301,7 +301,7 @@ NSDictionary *RCTMakeError(NSString *message, id toStringify, NSDictionary *extr NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary *extraData) { - id error = RCTMakeError(message, toStringify, extraData); + NSDictionary *error = RCTMakeError(message, toStringify, extraData); RCTLogError(@"\nError: %@", error); return error; } @@ -310,9 +310,9 @@ NSDictionary *RCTMakeAndLogError(NSString *message, id toStringify, NSDictionary NSDictionary *RCTJSErrorFromNSError(NSError *error) { NSString *errorMessage; - NSArray *stackTrace = [NSThread callStackSymbols]; + NSArray *stackTrace = [NSThread callStackSymbols]; NSMutableDictionary *errorInfo = - [NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"]; + [NSMutableDictionary dictionaryWithObject:stackTrace forKey:@"nativeStackIOS"]; if (error) { errorMessage = error.localizedDescription ?: @"Unknown error from a native module"; @@ -351,7 +351,11 @@ id RCTSharedApplication(void) return [[UIApplication class] performSelector:@selector(sharedApplication)]; } -id RCTAlertView(NSString *title, NSString *message, id delegate, NSString *cancelButtonTitle, NSArray *otherButtonTitles) +id RCTAlertView(NSString *title, + NSString *message, + id delegate, + NSString *cancelButtonTitle, + NSArray *otherButtonTitles) { if (RCTRunningInAppExtension()) { RCTLogError(@"RCTAlertView is unavailable when running in an app extension"); @@ -366,8 +370,7 @@ id RCTAlertView(NSString *title, NSString *message, id delegate, NSString *cance [alertView addButtonWithTitle:cancelButtonTitle]; alertView.cancelButtonIndex = 0; } - for (NSString *buttonTitle in otherButtonTitles) - { + for (NSString *buttonTitle in otherButtonTitles) { [alertView addButtonWithTitle:buttonTitle]; } return alertView; diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index 429bb0f62..8c2aa9947 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -93,7 +93,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init) // Private bridge interface to allow middle-batch calls @interface RCTBridge (RCTContextExecutor) -- (void)handleBuffer:(NSArray *)buffer batchEnded:(BOOL)hasEnded; +- (void)handleBuffer:(NSArray *)buffer batchEnded:(BOOL)hasEnded; @end @@ -345,7 +345,7 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) [strongSelf _addNativeHook:RCTNoop withName:"noop"]; __weak RCTBridge *bridge = strongSelf->_bridge; - strongSelf->_context.context[@"nativeFlushQueueImmediate"] = ^(NSArray *calls){ + strongSelf->_context.context[@"nativeFlushQueueImmediate"] = ^(NSArray *calls){ if (!weakSelf.valid || !calls) { return; } diff --git a/React/Modules/RCTAlertManager.m b/React/Modules/RCTAlertManager.m index 937bcf5da..992ef25ca 100644 --- a/React/Modules/RCTAlertManager.m +++ b/React/Modules/RCTAlertManager.m @@ -10,6 +10,7 @@ #import "RCTAlertManager.h" #import "RCTAssert.h" +#import "RCTConvert.h" #import "RCTLog.h" #import "RCTUtils.h" @@ -19,10 +20,10 @@ @implementation RCTAlertManager { - NSMutableArray *_alerts; - NSMutableArray *_alertControllers; - NSMutableArray *_alertCallbacks; - NSMutableArray *_alertButtonKeys; + NSMutableArray *_alerts; + NSMutableArray *_alertControllers; + NSMutableArray *_alertCallbacks; + NSMutableArray *> *_alertButtonKeys; } RCT_EXPORT_MODULE() @@ -70,10 +71,10 @@ RCT_EXPORT_MODULE() RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args callback:(RCTResponseSenderBlock)callback) { - NSString *title = args[@"title"]; - NSString *message = args[@"message"]; - NSString *type = args[@"type"]; - NSArray *buttons = args[@"buttons"]; + NSString *title = [RCTConvert NSString:args[@"title"]]; + NSString *message = [RCTConvert NSString:args[@"message"]]; + NSString *type = [RCTConvert NSString:args[@"type"]]; + NSDictionaryArray *buttons = [RCTConvert NSDictionaryArray:args[@"buttons"]]; BOOL allowsTextInput = [type isEqual:@"plain-text"]; if (!title && !message) { @@ -95,9 +96,11 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args } #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0 + if ([UIAlertController class] == nil) { + UIAlertView *alertView = RCTAlertView(title, nil, self, nil, nil); - NSMutableArray *buttonKeys = [[NSMutableArray alloc] initWithCapacity:buttons.count]; + NSMutableArray *buttonKeys = [[NSMutableArray alloc] initWithCapacity:buttons.count]; if (allowsTextInput) { alertView.alertViewStyle = UIAlertViewStylePlainTextInput; @@ -126,8 +129,11 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args [_alertButtonKeys addObject:buttonKeys]; [alertView show]; + } else + #endif + { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title @@ -152,7 +158,7 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args UITextField *textField = allowsTextInput ? alertController.textFields.firstObject : nil; [alertController addAction:[UIAlertAction actionWithTitle:buttonTitle style:buttonStyle - handler:^(UIAlertAction *action) { + handler:^(__unused UIAlertAction *action) { if (callback) { if (allowsTextInput) { callback(@[buttonKey, textField.text]); @@ -175,17 +181,14 @@ RCT_EXPORT_METHOD(alertWithArgs:(NSDictionary *)args RCTAssert(index != NSNotFound, @"Dismissed alert was not recognised"); RCTResponseSenderBlock callback = _alertCallbacks[index]; - NSArray *buttonKeys = _alertButtonKeys[index]; - NSArray *args; + NSArray *buttonKeys = _alertButtonKeys[index]; if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput) { - args = @[buttonKeys[buttonIndex], [alertView textFieldAtIndex:0].text]; + callback(@[buttonKeys[buttonIndex], [alertView textFieldAtIndex:0].text]); } else { - args = @[buttonKeys[buttonIndex]]; + callback(@[buttonKeys[buttonIndex]]); } - callback(args); - [_alerts removeObjectAtIndex:index]; [_alertCallbacks removeObjectAtIndex:index]; [_alertButtonKeys removeObjectAtIndex:index]; diff --git a/React/Modules/RCTAsyncLocalStorage.h b/React/Modules/RCTAsyncLocalStorage.h index e7e871b02..e6c129ef2 100644 --- a/React/Modules/RCTAsyncLocalStorage.h +++ b/React/Modules/RCTAsyncLocalStorage.h @@ -27,11 +27,8 @@ @property (nonatomic, readonly, getter=isValid) BOOL valid; -- (void)multiGet:(NSArray *)keys callback:(RCTResponseSenderBlock)callback; -- (void)multiSet:(NSArray *)kvPairs callback:(RCTResponseSenderBlock)callback; -- (void)multiRemove:(NSArray *)keys callback:(RCTResponseSenderBlock)callback; -- (void)clear:(RCTResponseSenderBlock)callback; -- (void)getAllKeys:(RCTResponseSenderBlock)callback; +// Clear the RCTAsyncLocalStorage data from native code +- (void)clearAllData; // For clearing data when the bridge may not exist, e.g. when logging out. + (void)clearAllData; diff --git a/React/Modules/RCTAsyncLocalStorage.m b/React/Modules/RCTAsyncLocalStorage.m index 1ef86eb84..b1bb67ef4 100644 --- a/React/Modules/RCTAsyncLocalStorage.m +++ b/React/Modules/RCTAsyncLocalStorage.m @@ -14,6 +14,7 @@ #import #import +#import "RCTConvert.h" #import "RCTLog.h" #import "RCTUtils.h" @@ -23,7 +24,7 @@ static const NSUInteger RCTInlineValueThreshold = 100; #pragma mark - Static helper functions -static id RCTErrorForKey(NSString *key) +static NSDictionary *RCTErrorForKey(NSString *key) { if (![key isKindOfClass:[NSString class]]) { return RCTMakeAndLogError(@"Invalid key - must be a string. Key: ", key, @{@"key": key}); @@ -34,7 +35,7 @@ static id RCTErrorForKey(NSString *key) } } -static void RCTAppendError(id error, NSMutableArray **errors) +static void RCTAppendError(NSDictionary *error, NSMutableArray **errors) { if (error && errors) { if (!*errors) { @@ -44,7 +45,7 @@ static void RCTAppendError(id error, NSMutableArray **errors) } } -static id RCTReadFile(NSString *filePath, NSString *key, NSDictionary **errorOut) +static NSString *RCTReadFile(NSString *filePath, NSString *key, NSDictionary **errorOut) { if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { NSError *error; @@ -148,6 +149,14 @@ RCT_EXPORT_MODULE() return RCTGetMethodQueue(); } +- (void)clearAllData +{ + dispatch_async(RCTGetMethodQueue(), ^{ + _manifest = [NSMutableDictionary new]; + RCTDeleteStorageDirectory(); + }); +} + + (void)clearAllData { dispatch_async(RCTGetMethodQueue(), ^{ @@ -181,7 +190,7 @@ RCT_EXPORT_MODULE() return [RCTGetStorageDirectory() stringByAppendingPathComponent:safeFileName]; } -- (id)_ensureSetup +- (NSDictionary *)_ensureSetup { RCTAssertThread(RCTGetMethodQueue(), @"Must be executed on storage thread"); @@ -199,7 +208,7 @@ RCT_EXPORT_MODULE() if (!_haveSetup) { NSDictionary *errorOut; NSString *serialized = RCTReadFile(RCTGetManifestFilePath(), nil, &errorOut); - _manifest = serialized ? [RCTJSONParse(serialized, &error) mutableCopy] : [NSMutableDictionary new]; + _manifest = serialized ? RCTJSONParseMutable(serialized, &error) : [NSMutableDictionary new]; if (error) { RCTLogWarn(@"Failed to parse manifest - creating new one.\n\n%@", error); _manifest = [NSMutableDictionary new]; @@ -209,12 +218,12 @@ RCT_EXPORT_MODULE() return nil; } -- (id)_writeManifest:(NSMutableArray **)errors +- (NSDictionary *)_writeManifest:(NSMutableArray **)errors { NSError *error; NSString *serialized = RCTJSONStringify(_manifest, &error); [serialized writeToFile:RCTGetManifestFilePath() atomically:YES encoding:NSUTF8StringEncoding error:&error]; - id errorOut; + NSDictionary *errorOut; if (error) { errorOut = RCTMakeError(@"Failed to write manifest file.", error, nil); RCTAppendError(errorOut, errors); @@ -222,20 +231,21 @@ RCT_EXPORT_MODULE() return errorOut; } -- (id)_appendItemForKey:(NSString *)key toArray:(NSMutableArray *)result +- (NSDictionary *)_appendItemForKey:(NSString *)key + toArray:(NSMutableArray *> *)result { - id errorOut = RCTErrorForKey(key); + NSDictionary *errorOut = RCTErrorForKey(key); if (errorOut) { return errorOut; } - id value = [self _getValueForKey:key errorOut:&errorOut]; + NSString *value = [self _getValueForKey:key errorOut:&errorOut]; [result addObject:@[key, RCTNullIfNil(value)]]; // Insert null if missing or failure. return errorOut; } - (NSString *)_getValueForKey:(NSString *)key errorOut:(NSDictionary **)errorOut { - id value = _manifest[key]; // nil means missing, null means there is a data file, anything else is an inline value. + id value = _manifest[key]; // nil means missing, null means there is a data file, else: NSString if (value == (id)kCFNull) { NSString *filePath = [self _filePathForKey:key]; value = RCTReadFile(filePath, key, errorOut); @@ -243,16 +253,13 @@ RCT_EXPORT_MODULE() return value; } -- (id)_writeEntry:(NSArray *)entry +- (NSDictionary *)_writeEntry:(NSArray *)entry { - if (![entry isKindOfClass:[NSArray class]] || entry.count != 2) { + if (entry.count != 2) { return RCTMakeAndLogError(@"Entries must be arrays of the form [key: string, value: string], got: ", entry, nil); } - if (![entry[1] isKindOfClass:[NSString class]]) { - return RCTMakeAndLogError(@"Values must be strings, got: ", entry[1], @{@"key": entry[0]}); - } NSString *key = entry[0]; - id errorOut = RCTErrorForKey(key); + NSDictionary *errorOut = RCTErrorForKey(key); if (errorOut) { return errorOut; } @@ -278,66 +285,63 @@ RCT_EXPORT_MODULE() #pragma mark - Exported JS Functions -RCT_EXPORT_METHOD(multiGet:(NSArray *)keys +RCT_EXPORT_METHOD(multiGet:(NSStringArray *)keys callback:(RCTResponseSenderBlock)callback) { - if (!callback) { - RCTLogError(@"Called getItem without a callback."); - return; - } - - id errorOut = [self _ensureSetup]; + NSDictionary *errorOut = [self _ensureSetup]; if (errorOut) { callback(@[@[errorOut], (id)kCFNull]); return; } - NSMutableArray *errors; - NSMutableArray *result = [[NSMutableArray alloc] initWithCapacity:keys.count]; + NSMutableArray *errors; + NSMutableArray *> *result = [[NSMutableArray alloc] initWithCapacity:keys.count]; for (NSString *key in keys) { - id keyError = [self _appendItemForKey:key toArray:result]; + NSDictionary *keyError = [self _appendItemForKey:key toArray:result]; RCTAppendError(keyError, &errors); } callback(@[RCTNullIfNil(errors), result]); } -RCT_EXPORT_METHOD(multiSet:(NSArray *)kvPairs +RCT_EXPORT_METHOD(multiSet:(NSStringArrayArray *)kvPairs callback:(RCTResponseSenderBlock)callback) { - id errorOut = [self _ensureSetup]; + NSDictionary *errorOut = [self _ensureSetup]; if (errorOut) { callback(@[@[errorOut]]); return; } - NSMutableArray *errors; - for (NSArray *entry in kvPairs) { - id keyError = [self _writeEntry:entry]; + NSMutableArray *errors; + for (NSArray *entry in kvPairs) { + NSDictionary *keyError = [self _writeEntry:entry]; RCTAppendError(keyError, &errors); } [self _writeManifest:&errors]; - if (callback) { - callback(@[RCTNullIfNil(errors)]); - } + callback(@[RCTNullIfNil(errors)]); } -RCT_EXPORT_METHOD(multiMerge:(NSArray *)kvPairs - callback:(RCTResponseSenderBlock)callback) +RCT_EXPORT_METHOD(multiMerge:(NSStringArrayArray *)kvPairs + callback:(RCTResponseSenderBlock)callback) { - id errorOut = [self _ensureSetup]; + NSDictionary *errorOut = [self _ensureSetup]; if (errorOut) { callback(@[@[errorOut]]); return; } - NSMutableArray *errors; - for (__strong NSArray *entry in kvPairs) { - id keyError; + NSMutableArray *errors; + for (__strong NSArray *entry in kvPairs) { + NSDictionary *keyError; NSString *value = [self _getValueForKey:entry[0] errorOut:&keyError]; if (keyError) { RCTAppendError(keyError, &errors); } else { if (value) { - NSMutableDictionary *mergedVal = [RCTJSONParseMutable(value, &keyError) mutableCopy]; - RCTMergeRecursive(mergedVal, RCTJSONParse(entry[1], &keyError)); - entry = @[entry[0], RCTJSONStringify(mergedVal, &keyError)]; + NSError *jsonError; + NSMutableDictionary *mergedVal = RCTJSONParseMutable(value, &jsonError); + RCTMergeRecursive(mergedVal, RCTJSONParse(entry[1], &jsonError)); + entry = @[entry[0], RCTNullIfNil(RCTJSONStringify(mergedVal, NULL))]; + if (jsonError) { + keyError = RCTJSErrorFromNSError(jsonError); + } } if (!keyError) { keyError = [self _writeEntry:entry]; @@ -346,22 +350,20 @@ RCT_EXPORT_METHOD(multiMerge:(NSArray *)kvPairs } } [self _writeManifest:&errors]; - if (callback) { - callback(@[RCTNullIfNil(errors)]); - } + callback(@[RCTNullIfNil(errors)]); } -RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys +RCT_EXPORT_METHOD(multiRemove:(NSStringArray *)keys callback:(RCTResponseSenderBlock)callback) { - id errorOut = [self _ensureSetup]; + NSDictionary *errorOut = [self _ensureSetup]; if (errorOut) { callback(@[@[errorOut]]); return; } - NSMutableArray *errors; + NSMutableArray *errors; for (NSString *key in keys) { - id keyError = RCTErrorForKey(key); + NSDictionary *keyError = RCTErrorForKey(key); if (!keyError) { NSString *filePath = [self _filePathForKey:key]; [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; @@ -370,23 +372,19 @@ RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys RCTAppendError(keyError, &errors); } [self _writeManifest:&errors]; - if (callback) { - callback(@[RCTNullIfNil(errors)]); - } + callback(@[RCTNullIfNil(errors)]); } RCT_EXPORT_METHOD(clear:(RCTResponseSenderBlock)callback) { _manifest = [NSMutableDictionary new]; NSError *error = RCTDeleteStorageDirectory(); - if (callback) { - callback(@[RCTNullIfNil(error)]); - } + callback(@[RCTNullIfNil(error)]); } RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback) { - id errorOut = [self _ensureSetup]; + NSDictionary *errorOut = [self _ensureSetup]; if (errorOut) { callback(@[errorOut, (id)kCFNull]); } else { diff --git a/React/Modules/RCTDevMenu.m b/React/Modules/RCTDevMenu.m index bc2ca9f8e..2da16ccb4 100644 --- a/React/Modules/RCTDevMenu.m +++ b/React/Modules/RCTDevMenu.m @@ -138,8 +138,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) NSURLSessionDataTask *_updateTask; NSURL *_liveReloadURL; BOOL _jsLoaded; - NSArray *_presentedItems; - NSMutableArray *_extraMenuItems; + NSArray *_presentedItems; + NSMutableArray *_extraMenuItems; } @synthesize bridge = _bridge; @@ -375,9 +375,9 @@ RCT_EXPORT_MODULE() [self settingsDidChange]; } -- (NSArray *)menuItems +- (NSArray *)menuItems { - NSMutableArray *items = [NSMutableArray new]; + NSMutableArray *items = [NSMutableArray new]; // Add built-in items @@ -435,7 +435,7 @@ RCT_EXPORT_METHOD(show) actionSheet.title = @"React Native: Development"; actionSheet.delegate = self; - NSArray *items = [self menuItems]; + NSArray *items = [self menuItems]; for (RCTDevMenuItem *item in items) { switch (item.type) { case RCTDevMenuTypeButton: { diff --git a/React/Modules/RCTExceptionsManager.h b/React/Modules/RCTExceptionsManager.h index adb575501..dac22b220 100644 --- a/React/Modules/RCTExceptionsManager.h +++ b/React/Modules/RCTExceptionsManager.h @@ -15,13 +15,14 @@ // NOTE: Remove these three methods and the @optional directive after updating the codebase to use only the three below @optional -- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; -- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; -- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; -- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; -- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; -- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; +- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; +- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; +- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack; + +- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; +- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; +- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray *)stack exceptionId:(NSNumber *)exceptionId; @end diff --git a/React/Modules/RCTExceptionsManager.m b/React/Modules/RCTExceptionsManager.m index ac4048d2c..17a713e8e 100644 --- a/React/Modules/RCTExceptionsManager.m +++ b/React/Modules/RCTExceptionsManager.m @@ -9,6 +9,7 @@ #import "RCTExceptionsManager.h" +#import "RCTConvert.h" #import "RCTDefines.h" #import "RCTLog.h" #import "RCTRedBox.h" @@ -39,7 +40,7 @@ RCT_EXPORT_MODULE() } RCT_EXPORT_METHOD(reportSoftException:(NSString *)message - stack:(NSArray *)stack + stack:(NSDictionaryArray *)stack exceptionId:(nonnull NSNumber *)exceptionId) { // TODO(#7070533): report a soft error to the server @@ -55,7 +56,7 @@ RCT_EXPORT_METHOD(reportSoftException:(NSString *)message } RCT_EXPORT_METHOD(reportFatalException:(NSString *)message - stack:(NSArray *)stack + stack:(NSDictionaryArray *)stack exceptionId:(nonnull NSNumber *)exceptionId) { if (_delegate) { @@ -98,7 +99,7 @@ RCT_EXPORT_METHOD(reportFatalException:(NSString *)message } RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message - stack:(NSArray *)stack + stack:(NSDictionaryArray *)stack exceptionId:(nonnull NSNumber *)exceptionId) { if (_delegate) { @@ -115,7 +116,7 @@ RCT_EXPORT_METHOD(updateExceptionMessage:(NSString *)message // Deprecated. Use reportFatalException directly instead. RCT_EXPORT_METHOD(reportUnhandledException:(NSString *)message - stack:(NSArray *)stack) + stack:(NSDictionaryArray *)stack) { [self reportFatalException:message stack:stack exceptionId:@-1]; } diff --git a/React/Modules/RCTRedBox.h b/React/Modules/RCTRedBox.h index a90f43deb..7703f5f8b 100644 --- a/React/Modules/RCTRedBox.h +++ b/React/Modules/RCTRedBox.h @@ -17,8 +17,8 @@ - (void)showError:(NSError *)error; - (void)showErrorMessage:(NSString *)message; - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details; -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack; -- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack; +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack; +- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack; - (void)dismiss; diff --git a/React/Modules/RCTRedBox.m b/React/Modules/RCTRedBox.m index 733a43713..6abb6dd7a 100644 --- a/React/Modules/RCTRedBox.m +++ b/React/Modules/RCTRedBox.m @@ -23,7 +23,7 @@ { UITableView *_stackTraceTableView; NSString *_lastErrorMessage; - NSArray *_lastStackTrace; + NSArray *_lastStackTrace; } - (instancetype)initWithFrame:(CGRect)frame @@ -103,7 +103,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) [[[NSURLSession sharedSession] dataTaskWithRequest:request] resume]; } -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow { if ((self.hidden && shouldShow) || (!self.hidden && [_lastErrorMessage isEqualToString:message])) { _lastStackTrace = stack; @@ -225,7 +225,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) #pragma mark - Key commands -- (NSArray *)keyCommands +- (NSArray *)keyCommands { // NOTE: We could use RCTKeyCommands for this, but since // we control this window, we can use the standard, non-hacky @@ -281,17 +281,17 @@ RCT_EXPORT_MODULE() [self showErrorMessage:combinedMessage]; } -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack { [self showErrorMessage:message withStack:stack showIfHidden:YES]; } -- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack +- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack { [self showErrorMessage:message withStack:stack showIfHidden:NO]; } -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow { dispatch_async(dispatch_get_main_queue(), ^{ if (!_window) { @@ -332,9 +332,9 @@ RCT_EXPORT_MODULE() - (void)showError:(NSError *)message {} - (void)showErrorMessage:(NSString *)message {} - (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details {} -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack {} -- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack {} -- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow {} +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack {} +- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack {} +- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow {} - (void)dismiss {} @end diff --git a/React/Modules/RCTTiming.m b/React/Modules/RCTTiming.m index 9da28d9df..41d90d41a 100644 --- a/React/Modules/RCTTiming.m +++ b/React/Modules/RCTTiming.m @@ -145,7 +145,7 @@ RCT_EXPORT_MODULE() - (void)didUpdateFrame:(__unused RCTFrameUpdate *)update { - NSMutableArray *timersToCall = [NSMutableArray new]; + NSMutableArray *timersToCall = [NSMutableArray new]; for (RCTTimer *timer in _timers.allObjects) { if ([timer updateFoundNeedsJSUpdate]) { [timersToCall addObject:timer.callbackID]; diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 06434ffc9..6c7e500a4 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -191,8 +191,8 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim dispatch_queue_t _shadowQueue; // Root views are only mutated on the shadow queue - NSMutableSet *_rootViewTags; - NSMutableArray *_pendingUIBlocks; + NSMutableSet *_rootViewTags; + NSMutableArray *_pendingUIBlocks; // Animation RCTLayoutAnimation *_nextLayoutAnimation; // RCT thread only @@ -201,7 +201,7 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim // Keyed by viewName NSDictionary *_componentDataByName; - NSMutableSet *_bridgeTransactionListeners; + NSMutableSet> *_bridgeTransactionListeners; } @synthesize bridge = _bridge; @@ -396,7 +396,8 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls); /** * Unregisters views from registries */ -- (void)_purgeChildren:(NSArray *)children fromRegistry:(RCTSparseArray *)registry +- (void)_purgeChildren:(NSArray> *)children + fromRegistry:(RCTSparseArray *)registry { for (id child in children) { RCTTraverseViewNodes(registry[child.reactTag], ^(id subview) { @@ -442,7 +443,7 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls); { RCTAssert(![NSThread isMainThread], @"Should be called on shadow thread"); - NSMutableSet *viewsWithNewFrames = [NSMutableSet setWithCapacity:1]; + NSMutableSet *viewsWithNewFrames = [NSMutableSet setWithCapacity:1]; // This is nuanced. In the JS thread, we create a new update buffer // `frameTags`/`frames` that is created/mutated in the JS thread. We access @@ -452,10 +453,14 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls); [rootShadowView collectRootUpdatedFrames:viewsWithNewFrames]; // Parallel arrays are built and then handed off to main thread - NSMutableArray *frameReactTags = [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; - NSMutableArray *frames = [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; - NSMutableArray *areNew = [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; - NSMutableArray *parentsAreNew = [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; + NSMutableArray *frameReactTags = + [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; + NSMutableArray *frames = + [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; + NSMutableArray *areNew = + [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; + NSMutableArray *parentsAreNew = + [NSMutableArray arrayWithCapacity:viewsWithNewFrames.count]; for (RCTShadowView *shadowView in viewsWithNewFrames) { [frameReactTags addObject:shadowView.reactTag]; @@ -473,7 +478,7 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls); // reactSetFrame: has been called. Note that if reactSetFrame: is not called, // these won't be called either, so this is not a suitable place to update // properties that aren't related to layout. - NSMutableArray *updateBlocks = [NSMutableArray new]; + NSMutableArray *updateBlocks = [NSMutableArray new]; for (RCTShadowView *shadowView in viewsWithNewFrames) { RCTViewManager *manager = [_componentDataByName[shadowView.viewName] manager]; RCTViewManagerUIBlock block = [manager uiBlockToAmendWithShadowView:shadowView]; @@ -583,7 +588,7 @@ extern NSString *RCTBridgeModuleNameForClass(Class cls); - (void)_amendPendingUIBlocksWithStylePropagationUpdateForRootView:(RCTShadowView *)topView { - NSMutableSet *applierBlocks = [NSMutableSet setWithCapacity:1]; + NSMutableSet *applierBlocks = [NSMutableSet setWithCapacity:1]; [topView collectUpdatedProperties:applierBlocks parentProperties:@{}]; if (applierBlocks.count) { @@ -605,7 +610,7 @@ RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(nonnull NSNumber *)containe RCTAssert(container != nil, @"container view (for ID %@) not found", containerID); NSUInteger subviewsCount = [container reactSubviews].count; - NSMutableArray *indices = [[NSMutableArray alloc] initWithCapacity:subviewsCount]; + NSMutableArray *indices = [[NSMutableArray alloc] initWithCapacity:subviewsCount]; for (NSUInteger childIndex = 0; childIndex < subviewsCount; childIndex++) { [indices addObject:@(childIndex)]; } @@ -624,8 +629,8 @@ RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(nonnull NSNumber *)containe * * @returns Array of removed items. */ -- (NSArray *)_childrenToRemoveFromContainer:(id)container - atIndices:(NSArray *)atIndices +- (NSArray> *)_childrenToRemoveFromContainer:(id)container + atIndices:(NSArray *)atIndices { // If there are no indices to move or the container has no subviews don't bother // We support parents with nil subviews so long as they're all nil so this allows for this behavior @@ -633,7 +638,7 @@ RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(nonnull NSNumber *)containe return nil; } // Construction of removed children must be done "up front", before indices are disturbed by removals. - NSMutableArray *removedChildren = [NSMutableArray arrayWithCapacity:atIndices.count]; + NSMutableArray> *removedChildren = [NSMutableArray arrayWithCapacity:atIndices.count]; RCTAssert(container != nil, @"container view (for ID %@) not found", container); for (NSNumber *indexNumber in atIndices) { NSUInteger index = indexNumber.unsignedIntegerValue; @@ -648,9 +653,10 @@ RCT_EXPORT_METHOD(removeSubviewsFromContainerWithID:(nonnull NSNumber *)containe return removedChildren; } -- (void)_removeChildren:(NSArray *)children fromContainer:(id)container +- (void)_removeChildren:(NSArray> *)children + fromContainer:(id)container { - for (id removedChild in children) { + for (id removedChild in children) { [container removeReactSubview:removedChild]; } } @@ -659,14 +665,14 @@ RCT_EXPORT_METHOD(removeRootView:(nonnull NSNumber *)rootReactTag) { RCTShadowView *rootShadowView = _shadowViewRegistry[rootReactTag]; RCTAssert(rootShadowView.superview == nil, @"root view cannot have superview (ID %@)", rootReactTag); - [self _purgeChildren:rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry]; + [self _purgeChildren:(NSArray> *)rootShadowView.reactSubviews fromRegistry:_shadowViewRegistry]; _shadowViewRegistry[rootReactTag] = nil; [_rootViewTags removeObject:rootReactTag]; [self addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry){ RCTAssertMainThread(); UIView *rootView = viewRegistry[rootReactTag]; - [uiManager _purgeChildren:rootView.reactSubviews fromRegistry:viewRegistry]; + [uiManager _purgeChildren:(NSArray> *)rootView.reactSubviews fromRegistry:viewRegistry]; viewRegistry[rootReactTag] = nil; [[NSNotificationCenter defaultCenter] postNotificationName:RCTUIManagerDidRemoveRootViewNotification @@ -675,7 +681,8 @@ RCT_EXPORT_METHOD(removeRootView:(nonnull NSNumber *)rootReactTag) }]; } -RCT_EXPORT_METHOD(replaceExistingNonRootView:(nonnull NSNumber *)reactTag withView:(nonnull NSNumber *)newReactTag) +RCT_EXPORT_METHOD(replaceExistingNonRootView:(nonnull NSNumber *)reactTag + withView:(nonnull NSNumber *)newReactTag) { RCTShadowView *shadowView = _shadowViewRegistry[reactTag]; RCTAssert(shadowView != nil, @"shadowView (for ID %@) not found", reactTag); @@ -685,8 +692,8 @@ RCT_EXPORT_METHOD(replaceExistingNonRootView:(nonnull NSNumber *)reactTag withVi NSUInteger indexOfView = [superShadowView.reactSubviews indexOfObject:shadowView]; RCTAssert(indexOfView != NSNotFound, @"View's superview doesn't claim it as subview (id %@)", reactTag); - NSArray *removeAtIndices = @[@(indexOfView)]; - NSArray *addTags = @[newReactTag]; + NSArray *removeAtIndices = @[@(indexOfView)]; + NSArray *addTags = @[newReactTag]; [self manageChildren:superShadowView.reactTag moveFromIndices:nil moveToIndices:nil @@ -696,11 +703,11 @@ RCT_EXPORT_METHOD(replaceExistingNonRootView:(nonnull NSNumber *)reactTag withVi } RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag - moveFromIndices:(NSArray *)moveFromIndices - moveToIndices:(NSArray *)moveToIndices - addChildReactTags:(NSArray *)addChildReactTags - addAtIndices:(NSArray *)addAtIndices - removeAtIndices:(NSArray *)removeAtIndices) + moveFromIndices:(NSNumberArray *)moveFromIndices + moveToIndices:(NSNumberArray *)moveToIndices + addChildReactTags:(NSNumberArray *)addChildReactTags + addAtIndices:(NSNumberArray *)addAtIndices + removeAtIndices:(NSNumberArray *)removeAtIndices) { [self _manageChildren:containerReactTag moveFromIndices:moveFromIndices @@ -722,11 +729,11 @@ RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag } - (void)_manageChildren:(NSNumber *)containerReactTag - moveFromIndices:(NSArray *)moveFromIndices - moveToIndices:(NSArray *)moveToIndices - addChildReactTags:(NSArray *)addChildReactTags - addAtIndices:(NSArray *)addAtIndices - removeAtIndices:(NSArray *)removeAtIndices + moveFromIndices:(NSArray *)moveFromIndices + moveToIndices:(NSArray *)moveToIndices + addChildReactTags:(NSArray *)addChildReactTags + addAtIndices:(NSArray *)addAtIndices + removeAtIndices:(NSArray *)removeAtIndices registry:(RCTSparseArray *)registry { id container = registry[containerReactTag]; @@ -734,8 +741,10 @@ RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag RCTAssert(addChildReactTags.count == addAtIndices.count, @"there should be at least one React child to add"); // Removes (both permanent and temporary moves) are using "before" indices - NSArray *permanentlyRemovedChildren = [self _childrenToRemoveFromContainer:container atIndices:removeAtIndices]; - NSArray *temporarilyRemovedChildren = [self _childrenToRemoveFromContainer:container atIndices:moveFromIndices]; + NSArray> *permanentlyRemovedChildren = + [self _childrenToRemoveFromContainer:container atIndices:removeAtIndices]; + NSArray> *temporarilyRemovedChildren = + [self _childrenToRemoveFromContainer:container atIndices:moveFromIndices]; [self _removeChildren:permanentlyRemovedChildren fromContainer:container]; [self _removeChildren:temporarilyRemovedChildren fromContainer:container]; @@ -749,15 +758,17 @@ RCT_EXPORT_METHOD(manageChildren:(nonnull NSNumber *)containerReactTag destinationsToChildrenToAdd[moveToIndices[index]] = temporarilyRemovedChildren[index]; } for (NSInteger index = 0, length = addAtIndices.count; index < length; index++) { - id view = registry[addChildReactTags[index]]; + id view = registry[addChildReactTags[index]]; if (view) { destinationsToChildrenToAdd[addAtIndices[index]] = view; } } - NSArray *sortedIndices = [destinationsToChildrenToAdd.allKeys sortedArrayUsingSelector:@selector(compare:)]; + NSArray *sortedIndices = + [destinationsToChildrenToAdd.allKeys sortedArrayUsingSelector:@selector(compare:)]; for (NSNumber *reactIndex in sortedIndices) { - [container insertReactSubview:destinationsToChildrenToAdd[reactIndex] atIndex:reactIndex.integerValue]; + [container insertReactSubview:destinationsToChildrenToAdd[reactIndex] + atIndex:reactIndex.integerValue]; } } @@ -894,7 +905,7 @@ RCT_EXPORT_METHOD(findSubviewIn:(nonnull NSNumber *)reactTag atPoint:(CGPoint)po // First copy the previous blocks into a temporary variable, then reset the // pending blocks to a new array. This guards against mutation while // processing the pending blocks in another thread. - NSArray *previousPendingUIBlocks = _pendingUIBlocks; + NSArray *previousPendingUIBlocks = _pendingUIBlocks; _pendingUIBlocks = [NSMutableArray new]; if (previousPendingUIBlocks.count) { @@ -1036,8 +1047,9 @@ RCT_EXPORT_METHOD(measureViewsInRect:(CGRect)rect RCTLogError(@"Attempting to measure view that does not exist (tag #%@)", reactTag); return; } - NSArray *childShadowViews = [shadowView reactSubviews]; - NSMutableArray *results = [[NSMutableArray alloc] initWithCapacity:childShadowViews.count]; + NSArray *childShadowViews = [shadowView reactSubviews]; + NSMutableArray *results = + [[NSMutableArray alloc] initWithCapacity:childShadowViews.count]; [childShadowViews enumerateObjectsUsingBlock: ^(RCTShadowView *childShadowView, NSUInteger idx, __unused BOOL *stop) { diff --git a/React/Profiler/RCTPerfMonitor.m b/React/Profiler/RCTPerfMonitor.m index 57a93f19c..e1ce3ad4b 100644 --- a/React/Profiler/RCTPerfMonitor.m +++ b/React/Profiler/RCTPerfMonitor.m @@ -424,7 +424,7 @@ RCT_EXPORT_MODULE() _remaining = nil; } - NSArray *lines = [log componentsSeparatedByString:@"\n"]; + NSArray *lines = [log componentsSeparatedByString:@"\n"]; if (lines.count == 1) { // no newlines _remaining = log; return; diff --git a/React/Profiler/RCTProfile.m b/React/Profiler/RCTProfile.m index c1e37e121..38678d8c7 100644 --- a/React/Profiler/RCTProfile.m +++ b/React/Profiler/RCTProfile.m @@ -336,10 +336,11 @@ NSString *RCTProfileEnd(RCTBridge *bridge) } } -static NSMutableArray *RCTProfileGetThreadEvents(void) +static NSMutableArray *RCTProfileGetThreadEvents(void) { static NSString *const RCTProfileThreadEventsKey = @"RCTProfileThreadEventsKey"; - NSMutableArray *threadEvents = [NSThread currentThread].threadDictionary[RCTProfileThreadEventsKey]; + NSMutableArray *threadEvents = + [NSThread currentThread].threadDictionary[RCTProfileThreadEventsKey]; if (!threadEvents) { threadEvents = [NSMutableArray new]; [NSThread currentThread].threadDictionary[RCTProfileThreadEventsKey] = threadEvents; @@ -377,7 +378,7 @@ void RCTProfileEndEvent( return; } - NSMutableArray *events = RCTProfileGetThreadEvents(); + NSMutableArray *events = RCTProfileGetThreadEvents(); NSArray *event = events.lastObject; [events removeLastObject]; diff --git a/React/Views/RCTComponent.h b/React/Views/RCTComponent.h index 215acb1d0..2940b4311 100644 --- a/React/Views/RCTComponent.h +++ b/React/Views/RCTComponent.h @@ -27,7 +27,7 @@ typedef void (^RCTBubblingEventBlock)(NSDictionary *body); - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex; - (void)removeReactSubview:(id)subview; -- (NSArray *)reactSubviews; +- (NSArray> *)reactSubviews; - (id)reactSuperview; - (NSNumber *)reactTagAtPoint:(CGPoint)point; diff --git a/React/Views/RCTComponentData.m b/React/Views/RCTComponentData.m index c6fd94127..1f208150d 100644 --- a/React/Views/RCTComponentData.m +++ b/React/Views/RCTComponentData.m @@ -100,7 +100,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) SEL selector = NSSelectorFromString([NSString stringWithFormat:@"propConfig%@_%@", shadowView ? @"Shadow" : @"", name]); Class managerClass = [_manager class]; if ([managerClass respondsToSelector:selector]) { - NSArray *typeAndKeyPath = ((NSArray *(*)(id, SEL))objc_msgSend)(managerClass, selector); + NSArray *typeAndKeyPath = + ((NSArray *(*)(id, SEL))objc_msgSend)(managerClass, selector); type = NSSelectorFromString([typeAndKeyPath[0] stringByAppendingString:@":"]); keyPath = typeAndKeyPath.count > 1 ? typeAndKeyPath[1] : nil; } else { @@ -125,7 +126,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) // Disect keypath NSString *key = name; - NSArray *parts = [keyPath componentsSeparatedByString:@"."]; + NSArray *parts = [keyPath componentsSeparatedByString:@"."]; if (parts) { key = parts.lastObject; parts = [parts subarrayWithRange:(NSRange){0, parts.count - 1}]; @@ -312,9 +313,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) { Class managerClass = [_manager class]; - NSMutableArray *directEvents = [NSMutableArray new]; + NSMutableArray *directEvents = [NSMutableArray new]; if (RCTClassOverridesInstanceMethod(managerClass, @selector(customDirectEventTypes))) { - NSArray *events = [_manager customDirectEventTypes]; + NSArray *events = [_manager customDirectEventTypes]; if (RCT_DEBUG) { RCTAssert(!events || [events isKindOfClass:[NSArray class]], @"customDirectEventTypes must return an array, but %@ returned %@", @@ -325,9 +326,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) } } - NSMutableArray *bubblingEvents = [NSMutableArray new]; + NSMutableArray *bubblingEvents = [NSMutableArray new]; if (RCTClassOverridesInstanceMethod(managerClass, @selector(customBubblingEventTypes))) { - NSArray *events = [_manager customBubblingEventTypes]; + NSArray *events = [_manager customBubblingEventTypes]; if (RCT_DEBUG) { RCTAssert(!events || [events isKindOfClass:[NSArray class]], @"customBubblingEventTypes must return an array, but %@ returned %@", @@ -349,7 +350,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) NSRange nameRange = [methodName rangeOfString:@"_"]; if (nameRange.length) { NSString *name = [methodName substringFromIndex:nameRange.location + 1]; - NSString *type = ((NSArray *(*)(id, SEL))objc_msgSend)(managerClass, selector)[0]; + NSString *type = ((NSArray *(*)(id, SEL))objc_msgSend)(managerClass, selector)[0]; if (RCT_DEBUG && propTypes[name] && ![propTypes[name] isEqualToString:type]) { RCTLogError(@"Property '%@' of component '%@' redefined from '%@' " "to '%@'", name, _name, propTypes[name], type); diff --git a/React/Views/RCTMap.h b/React/Views/RCTMap.h index 65e6aec94..c9025d6d3 100644 --- a/React/Views/RCTMap.h +++ b/React/Views/RCTMap.h @@ -25,7 +25,7 @@ extern const CGFloat RCTMapZoomBoundBuffer; @property (nonatomic, assign) CGFloat maxDelta; @property (nonatomic, assign) UIEdgeInsets legalLabelInsets; @property (nonatomic, strong) NSTimer *regionChangeObserveTimer; -@property (nonatomic, strong) NSMutableArray *annotationIds; +@property (nonatomic, copy) NSArray *annotationIds; @property (nonatomic, copy) RCTBubblingEventBlock onChange; @property (nonatomic, copy) RCTBubblingEventBlock onPress; diff --git a/React/Views/RCTMap.m b/React/Views/RCTMap.m index 69e4679ff..238c7a4d3 100644 --- a/React/Views/RCTMap.m +++ b/React/Views/RCTMap.m @@ -109,9 +109,9 @@ const CGFloat RCTMapZoomBoundBuffer = 0.01; - (void)setAnnotations:(RCTPointAnnotationArray *)annotations { - NSMutableArray *newAnnotationIds = [NSMutableArray new]; - NSMutableArray *annotationsToDelete = [NSMutableArray new]; - NSMutableArray *annotationsToAdd = [NSMutableArray new]; + NSMutableArray *newAnnotationIds = [NSMutableArray new]; + NSMutableArray *annotationsToDelete = [NSMutableArray new]; + NSMutableArray *annotationsToAdd = [NSMutableArray new]; for (RCTPointAnnotation *annotation in annotations) { if (![annotation isKindOfClass:[RCTPointAnnotation class]]) { @@ -138,19 +138,19 @@ const CGFloat RCTMapZoomBoundBuffer = 0.01; } if (annotationsToDelete.count) { - [self removeAnnotations:annotationsToDelete]; + [self removeAnnotations:(NSArray> *)annotationsToDelete]; } if (annotationsToAdd.count) { - [self addAnnotations:annotationsToAdd]; + [self addAnnotations:(NSArray> *)annotationsToAdd]; } - NSMutableArray *newIds = [NSMutableArray new]; - for (RCTPointAnnotation *anno in self.annotations) { - if ([anno isKindOfClass:[MKUserLocation class]]) { + NSMutableArray *newIds = [NSMutableArray new]; + for (RCTPointAnnotation *annotation in self.annotations) { + if ([annotation isKindOfClass:[MKUserLocation class]]) { continue; } - [newIds addObject:anno.identifier]; + [newIds addObject:annotation.identifier]; } self.annotationIds = newIds; } diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m index 3fed3f321..c82ab5249 100644 --- a/React/Views/RCTModalHostView.m +++ b/React/Views/RCTModalHostView.m @@ -51,18 +51,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) } } -- (NSArray *)reactSubviews +- (NSArray *> *)reactSubviews { - return [NSArray arrayWithObjects:_modalViewController.view, nil]; + return _modalViewController.view ? @[_modalViewController.view] : @[]; } -- (void)insertReactSubview:(UIView *)subview atIndex:(__unused NSInteger)atIndex +- (void)insertReactSubview:(UIView *)subview atIndex:(__unused NSInteger)atIndex { [subview addGestureRecognizer:_touchHandler]; _modalViewController.view = subview; } -- (void)removeReactSubview:(UIView *)subview +- (void)removeReactSubview:(UIView *)subview { RCTAssert(subview == _modalViewController.view, @"Cannot remove view other than modal view"); _modalViewController.view = nil; diff --git a/React/Views/RCTNavigator.m b/React/Views/RCTNavigator.m index 907eda4a9..460a5fc6e 100644 --- a/React/Views/RCTNavigator.m +++ b/React/Views/RCTNavigator.m @@ -200,8 +200,8 @@ NSInteger kNeverProgressed = -10000; // Previous views are only mainted in order to detect incorrect // addition/removal of views below the `requestedTopOfStack` -@property (nonatomic, copy, readwrite) NSArray *previousViews; -@property (nonatomic, readwrite, strong) NSMutableArray *currentViews; +@property (nonatomic, copy, readwrite) NSArray *previousViews; +@property (nonatomic, readwrite, strong) NSMutableArray *currentViews; @property (nonatomic, readwrite, strong) RCTNavigationController *navigationController; /** * Display link is used to get high frequency sample rate during @@ -400,7 +400,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) * `requestedTopOfStack` changes, there had better be enough subviews present * to satisfy the push/pop. */ -- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex +- (void)insertReactSubview:(RCTNavItem *)view atIndex:(NSInteger)atIndex { RCTAssert([view isKindOfClass:[RCTNavItem class]], @"RCTNavigator only accepts RCTNavItem subviews"); RCTAssert( @@ -410,7 +410,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) [_currentViews insertObject:view atIndex:atIndex]; } -- (NSArray *)reactSubviews +- (NSArray *)reactSubviews { return _currentViews; } @@ -422,7 +422,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) _navigationController.view.frame = self.bounds; } -- (void)removeReactSubview:(UIView *)subview +- (void)removeReactSubview:(RCTNavItem *)subview { if (_currentViews.count <= 0 || subview == _currentViews[0]) { RCTLogError(@"Attempting to remove invalid RCT subview of RCTNavigator"); diff --git a/React/Views/RCTPicker.h b/React/Views/RCTPicker.h index 704fe7587..8fb39b5a5 100644 --- a/React/Views/RCTPicker.h +++ b/React/Views/RCTPicker.h @@ -9,6 +9,12 @@ #import +#import "UIView+React.h" + @interface RCTPicker : UIPickerView +@property (nonatomic, copy) NSArray *items; +@property (nonatomic, assign) NSInteger selectedIndex; +@property (nonatomic, copy) RCTBubblingEventBlock onChange; + @end diff --git a/React/Views/RCTPicker.m b/React/Views/RCTPicker.m index 1f256cc48..f979c2116 100644 --- a/React/Views/RCTPicker.m +++ b/React/Views/RCTPicker.m @@ -10,14 +10,8 @@ #import "RCTPicker.h" #import "RCTUtils.h" -#import "UIView+React.h" @interface RCTPicker() - -@property (nonatomic, copy) NSArray *items; -@property (nonatomic, assign) NSInteger selectedIndex; -@property (nonatomic, copy) RCTBubblingEventBlock onChange; - @end @implementation RCTPicker @@ -33,7 +27,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) -- (void)setItems:(NSArray *)items +- (void)setItems:(NSArray *)items { _items = [items copy]; [self setNeedsLayout]; diff --git a/React/Views/RCTScrollView.m b/React/Views/RCTScrollView.m index 1e085d265..1dfb9c1c9 100644 --- a/React/Views/RCTScrollView.m +++ b/React/Views/RCTScrollView.m @@ -117,7 +117,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) - (RCTScrollEvent *)coalesceWithEvent:(RCTScrollEvent *)newEvent { - NSArray *updatedChildFrames = [_userData[@"updatedChildFrames"] arrayByAddingObjectsFromArray:newEvent->_userData[@"updatedChildFrames"]]; + NSArray *updatedChildFrames = [_userData[@"updatedChildFrames"] arrayByAddingObjectsFromArray:newEvent->_userData[@"updatedChildFrames"]]; if (updatedChildFrames) { NSMutableDictionary *userData = [newEvent->_userData mutableCopy]; @@ -360,7 +360,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) RCTCustomScrollView *_scrollView; UIView *_contentView; NSTimeInterval _lastScrollDispatchTime; - NSMutableArray *_cachedChildFrames; + NSMutableArray *_cachedChildFrames; BOOL _allowNextScrollNoMatterWhat; CGRect _lastClippedToRect; } @@ -412,7 +412,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) [subview removeFromSuperview]; } -- (NSArray *)reactSubviews +- (NSArray *> *)reactSubviews { return _contentView ? @[_contentView] : @[]; } @@ -564,7 +564,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove) (_scrollEventThrottle > 0 && _scrollEventThrottle < (now - _lastScrollDispatchTime))) { // Calculate changed frames - NSArray *childFrames = [self calculateChildFramesData]; + NSArray *childFrames = [self calculateChildFramesData]; // Dispatch event [_eventDispatcher sendScrollEventWithType:RCTScrollEventTypeMove @@ -579,9 +579,9 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove) RCT_FORWARD_SCROLL_EVENT(scrollViewDidScroll:scrollView); } -- (NSArray *)calculateChildFramesData +- (NSArray *)calculateChildFramesData { - NSMutableArray *updatedChildFrames = [NSMutableArray new]; + NSMutableArray *updatedChildFrames = [NSMutableArray new]; [[_contentView reactSubviews] enumerateObjectsUsingBlock: ^(UIView *subview, NSUInteger idx, __unused BOOL *stop) { diff --git a/React/Views/RCTScrollViewManager.m b/React/Views/RCTScrollViewManager.m index 18f5eaf1d..6470f10f1 100644 --- a/React/Views/RCTScrollViewManager.m +++ b/React/Views/RCTScrollViewManager.m @@ -16,7 +16,7 @@ @interface RCTScrollView (Private) -- (NSArray *)calculateChildFramesData; +- (NSArray *)calculateChildFramesData; @end @@ -83,13 +83,13 @@ RCT_EXPORT_METHOD(getContentSize:(nonnull NSNumber *)reactTag { [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { - UIView *view = viewRegistry[reactTag]; - if (!view) { - RCTLogError(@"Cannot find view with tag #%@", reactTag); + RCTScrollView *view = viewRegistry[reactTag]; + if (!view || ![view isKindOfClass:[RCTScrollView class]]) { + RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag); return; } - CGSize size = ((RCTScrollView *)view).scrollView.contentSize; + CGSize size = view.scrollView.contentSize; callback(@[@{ @"width" : @(size.width), @"height" : @(size.height) @@ -102,20 +102,20 @@ RCT_EXPORT_METHOD(calculateChildFrames:(nonnull NSNumber *)reactTag { [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { - UIView *view = viewRegistry[reactTag]; - if (!view) { - RCTLogError(@"Cannot find view with tag #%@", reactTag); + RCTScrollView *view = viewRegistry[reactTag]; + if (!view || ![view isKindOfClass:[RCTScrollView class]]) { + RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag); return; } - NSArray *childFrames = [((RCTScrollView *)view) calculateChildFramesData]; + NSArray *childFrames = [view calculateChildFramesData]; if (childFrames) { callback(@[childFrames]); } }]; } -- (NSArray *)customDirectEventTypes +- (NSArray *)customDirectEventTypes { return @[ @"scrollBeginDrag", diff --git a/React/Views/RCTSegmentedControl.h b/React/Views/RCTSegmentedControl.h index 500a236e9..296afb10e 100644 --- a/React/Views/RCTSegmentedControl.h +++ b/React/Views/RCTSegmentedControl.h @@ -13,7 +13,7 @@ @interface RCTSegmentedControl : UISegmentedControl -@property (nonatomic, copy) NSArray *values; +@property (nonatomic, copy) NSArray *values; @property (nonatomic, assign) NSInteger selectedIndex; @property (nonatomic, copy) RCTBubblingEventBlock onChange; diff --git a/React/Views/RCTSegmentedControl.m b/React/Views/RCTSegmentedControl.m index 1857bb0ad..4d10a3d20 100644 --- a/React/Views/RCTSegmentedControl.m +++ b/React/Views/RCTSegmentedControl.m @@ -25,7 +25,7 @@ return self; } -- (void)setValues:(NSArray *)values +- (void)setValues:(NSArray *)values { _values = [values copy]; [self removeAllSegments]; diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index 8461c818d..1d697083a 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -35,6 +35,9 @@ typedef void (^RCTApplierBlock)(RCTSparseArray *viewRegistry); */ @interface RCTShadowView : NSObject +- (NSArray *)reactSubviews; +- (RCTShadowView *)reactSuperview; + @property (nonatomic, weak, readonly) RCTShadowView *superview; @property (nonatomic, assign, readonly) css_node_t *cssNode; @property (nonatomic, copy) NSString *viewName; @@ -120,27 +123,27 @@ typedef void (^RCTApplierBlock)(RCTSparseArray *viewRegistry); * The applierBlocks set contains RCTApplierBlock functions that must be applied * on the main thread in order to update the view. */ -- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks +- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties; /** * Process the updated properties and apply them to view. Shadow view classes * that add additional propagating properties should override this method. */ -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks +- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties NS_REQUIRES_SUPER; /** * Calculate all views whose frame needs updating after layout has been calculated. * The viewsWithNewFrame set contains the reactTags of the views that need updating. */ -- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame; +- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame; /** * Recursively apply layout to children. */ - (void)applyLayoutNode:(css_node_t *)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame + viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER; /** diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 2161a3763..ed4fef1d9 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -36,7 +36,7 @@ typedef NS_ENUM(unsigned int, meta_prop_t) { RCTUpdateLifecycle _propagationLifecycle; RCTUpdateLifecycle _textLifecycle; NSDictionary *_lastParentProperties; - NSMutableArray *_reactSubviews; + NSMutableArray *_reactSubviews; BOOL _recomputePadding; BOOL _recomputeMargin; BOOL _recomputeBorder; @@ -123,7 +123,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st // You'll notice that this is the same width we calculated for the parent view because we've taken its position into account. - (void)applyLayoutNode:(css_node_t *)node - viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame + viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame absolutePosition:(CGPoint)absolutePosition { if (!node->layout.should_update) { @@ -171,7 +171,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st } } -- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks +- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties { // TODO: we always refresh all propagated properties when propagation is @@ -201,7 +201,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st return parentProperties; } -- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks +- (void)collectUpdatedProperties:(NSMutableSet *)applierBlocks parentProperties:(NSDictionary *)parentProperties { if (_propagationLifecycle == RCTUpdateLifecycleComputed && [parentProperties isEqualToDictionary:_lastParentProperties]) { @@ -234,7 +234,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st } } -- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame +- (void)collectRootUpdatedFrames:(NSMutableSet *)viewsWithNewFrame { RCTAssert(RCTIsReactRootView(self.reactTag), @"The method has been called on a view with react tag %@, which is not a root view", self.reactTag); @@ -367,7 +367,7 @@ static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float st _cssNode->children_count = (int)_reactSubviews.count; } -- (NSArray *)reactSubviews +- (NSArray *)reactSubviews { return _reactSubviews; } diff --git a/React/Views/RCTTabBar.m b/React/Views/RCTTabBar.m index 2c0dc28e9..3b7b6693f 100644 --- a/React/Views/RCTTabBar.m +++ b/React/Views/RCTTabBar.m @@ -26,7 +26,7 @@ { BOOL _tabsChanged; UITabBarController *_tabController; - NSMutableArray *_tabViews; + NSMutableArray *_tabViews; } - (instancetype)initWithFrame:(CGRect)frame @@ -52,12 +52,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) _tabController.delegate = nil; } -- (NSArray *)reactSubviews +- (NSArray *)reactSubviews { return _tabViews; } -- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex +- (void)insertReactSubview:(RCTTabBarItem *)view atIndex:(NSInteger)atIndex { if (![view isKindOfClass:[RCTTabBarItem class]]) { RCTLogError(@"subview should be of type RCTTabBarItem"); @@ -67,7 +67,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) _tabsChanged = YES; } -- (void)removeReactSubview:(UIView *)subview +- (void)removeReactSubview:(RCTTabBarItem *)subview { if (_tabViews.count == 0) { RCTLogError(@"should have at least one view to remove a subview"); @@ -92,7 +92,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) if (_tabsChanged) { - NSMutableArray *viewControllers = [NSMutableArray array]; + NSMutableArray *viewControllers = [NSMutableArray array]; for (RCTTabBarItem *tab in [self reactSubviews]) { UIViewController *controller = tab.reactViewController; if (!controller) { @@ -105,7 +105,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) _tabsChanged = NO; } - [[self reactSubviews] enumerateObjectsUsingBlock: + [_tabViews enumerateObjectsUsingBlock: ^(RCTTabBarItem *tab, NSUInteger index, __unused BOOL *stop) { UIViewController *controller = _tabController.viewControllers[index]; controller.tabBarItem = tab.barItem; @@ -148,7 +148,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { NSUInteger index = [tabBarController.viewControllers indexOfObject:viewController]; - RCTTabBarItem *tab = [self reactSubviews][index]; + RCTTabBarItem *tab = _tabViews[index]; if (tab.onPress) tab.onPress(nil); return NO; } diff --git a/React/Views/RCTView.m b/React/Views/RCTView.m index 191dc2160..3ba4d88d6 100644 --- a/React/Views/RCTView.m +++ b/React/Views/RCTView.m @@ -92,7 +92,7 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view) @implementation RCTView { - NSMutableArray *_reactSubviews; + NSMutableArray *> *_reactSubviews; UIColor *_backgroundColor; } @@ -413,7 +413,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) [subview removeFromSuperview]; } -- (NSArray *)reactSubviews +- (NSArray *> *)reactSubviews { // The _reactSubviews array is only used when we have hidden // offscreen views. If _reactSubviews is nil, we can assume diff --git a/React/Views/RCTViewManager.h b/React/Views/RCTViewManager.h index 35c2a4d4f..5825fa8cd 100644 --- a/React/Views/RCTViewManager.h +++ b/React/Views/RCTViewManager.h @@ -70,7 +70,7 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v * Note that this method is not inherited when you subclass a view module, and * you should not call [super customBubblingEventTypes] when overriding it. */ -- (NSArray *)customBubblingEventTypes; +- (NSArray *)customBubblingEventTypes; /** * DEPRECATED: declare properties of type RCTDirectEventBlock instead @@ -83,7 +83,7 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v * Note that this method is not inherited when you subclass a view module, and * you should not call [super customDirectEventTypes] when overriding it. */ -- (NSArray *)customDirectEventTypes; +- (NSArray *)customDirectEventTypes; /** * Called to notify manager that layout has finished, in case any calculated @@ -103,13 +103,13 @@ typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, RCTSparseArray *v * This handles the simple case, where JS and native property names match. */ #define RCT_EXPORT_VIEW_PROPERTY(name, type) \ -+ (NSArray *)propConfig_##name { return @[@#type]; } ++ (NSArray *)propConfig_##name { return @[@#type]; } /** * This macro maps a named property to an arbitrary key path in the view. */ #define RCT_REMAP_VIEW_PROPERTY(name, keyPath, type) \ -+ (NSArray *)propConfig_##name { return @[@#type, @#keyPath]; } ++ (NSArray *)propConfig_##name { return @[@#type, @#keyPath]; } /** * This macro can be used when you need to provide custom logic for setting @@ -124,6 +124,6 @@ RCT_REMAP_VIEW_PROPERTY(name, __custom__, type) \ * This macro is used to map properties to the shadow view, instead of the view. */ #define RCT_EXPORT_SHADOW_PROPERTY(name, type) \ -+ (NSArray *)propConfigShadow_##name { return @[@#type]; } ++ (NSArray *)propConfigShadow_##name { return @[@#type]; } @end diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 2ad52943c..256f1a0a5 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -69,7 +69,7 @@ RCT_EXPORT_MODULE() return [RCTShadowView new]; } -- (NSArray *)customBubblingEventTypes +- (NSArray *)customBubblingEventTypes { return @[ @@ -90,7 +90,7 @@ RCT_EXPORT_MODULE() ]; } -- (NSArray *)customDirectEventTypes +- (NSArray *)customDirectEventTypes { return @[]; } diff --git a/React/Views/UIView+React.h b/React/Views/UIView+React.h index 1c3a30933..6bfb6d80e 100644 --- a/React/Views/UIView+React.h +++ b/React/Views/UIView+React.h @@ -15,6 +15,9 @@ @interface UIView (React) +- (NSArray *> *)reactSubviews; +- (UIView *)reactSuperview; + /** * Used by the UIIManager to set the view frame. * May be overriden to disable animation, etc. diff --git a/React/Views/UIView+React.m b/React/Views/UIView+React.m index cef153bd6..14c7a26c7 100644 --- a/React/Views/UIView+React.m +++ b/React/Views/UIView+React.m @@ -51,12 +51,12 @@ [subview removeFromSuperview]; } -- (NSArray *)reactSubviews +- (NSArray *> *)reactSubviews { return self.subviews; } -- (UIView *)reactSuperview +- (UIView *)reactSuperview { return self.superview; }