Added lightweight generic annotations

Summary: public

Added lightweight genarics annotations to make the code more readable and help the compiler catch bugs.

Fixed some type bugs and improved bridge validation in a few places.

Reviewed By: javache

Differential Revision: D2600189

fb-gh-sync-id: f81e22f2cdc107bf8d0b15deec6d5b83aacc5b56
This commit is contained in:
Nick Lockwood 2015-11-03 14:45:46 -08:00 committed by facebook-github-bot-7
parent 31565781f2
commit c5b990f65f
78 changed files with 497 additions and 422 deletions

View File

@ -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;

View File

@ -19,7 +19,7 @@
CGPoint _endPoint;
}
- (instancetype)initWithArray:(NSArray *)array
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
{
if ((self = [super initWithArray:array])) {
if (array.count < 5) {

View File

@ -18,7 +18,7 @@
CGRect _rect;
}
- (instancetype)initWithArray:(NSArray *)array
- (instancetype)initWithArray:(NSArray<id /* imagesource + numbers */> *)array
{
if ((self = [super initWithArray:array])) {
if (array.count < 6) {

View File

@ -21,7 +21,7 @@
CGFloat _radiusRatio;
}
- (instancetype)initWithArray:(NSArray *)array
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
{
if ((self = [super initWithArray:array])) {
if (array.count < 7) {

View File

@ -17,7 +17,7 @@
CGColorRef _color;
}
- (instancetype)initWithArray:(NSArray *)array
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
{
if ((self = [super initWithArray:array])) {
_color = CGColorRetain([RCTConvert CGColor:array offset:1]);

View File

@ -62,7 +62,7 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
}
NSString *title = [RCTConvert NSString:options[@"title"]];
NSArray *buttons = [RCTConvert NSStringArray:options[@"options"]];
NSArray<NSString *> *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<id /* NSString or NSURL */> *items = [NSMutableArray array];
NSString *message = [RCTConvert NSString:options[@"message"]];
if (message) {
[items addObject:message];

View File

@ -7,7 +7,17 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <AssetsLibrary/AssetsLibrary.h>
#import "RCTBridgeModule.h"
#import "RCTConvert.h"
@interface RCTConvert (ALAssetGroup)
+ (ALAssetsGroupType)ALAssetsGroupType:(id)json;
+ (ALAssetsFilter *)ALAssetsFilter:(id)json;
@end
@interface RCTCameraRollManager : NSObject <RCTBridgeModule>

View File

@ -9,17 +9,70 @@
#import "RCTCameraRollManager.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#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<NSDictionary *> *)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<NSDictionary *> *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;

View File

@ -23,9 +23,9 @@
@implementation RCTImagePickerManager
{
NSMutableArray *_pickers;
NSMutableArray *_pickerCallbacks;
NSMutableArray *_pickerCancelCallbacks;
NSMutableArray<UIImagePickerController *> *_pickers;
NSMutableArray<RCTResponseSenderBlock> *_pickerCallbacks;
NSMutableArray<RCTResponseSenderBlock> *_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<NSString *> *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
callback(@[@([availableMediaTypes containsObject:(NSString *)kUTTypeMovie])]);
}
@ -94,7 +94,7 @@ RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
NSMutableArray *allowedTypes = [NSMutableArray new];
NSMutableArray<NSString *> *allowedTypes = [NSMutableArray new];
if ([config[@"showImages"] boolValue]) {
[allowedTypes addObject:(NSString *)kUTTypeImage];
}

View File

@ -100,7 +100,7 @@ static NSDictionary *RCTPositionError(RCTPositionErrorCode code, NSString *msg /
{
CLLocationManager *_locationManager;
NSDictionary *_lastLocationEvent;
NSMutableArray *_pendingRequests;
NSMutableArray<RCTLocationRequest *> *_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<CLLocation *> *)locations
{
// Create event
CLLocation *location = locations.lastObject;

View File

@ -42,8 +42,8 @@ RCT_EXPORT_MODULE()
if (imageCount > 1) {
NSTimeInterval duration = 0;
NSMutableArray *delays = [NSMutableArray arrayWithCapacity:imageCount];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:imageCount];
NSMutableArray<NSNumber *> *delays = [NSMutableArray arrayWithCapacity:imageCount];
NSMutableArray<id /* CGIMageRef */> *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<NSNumber *> *keyTimes = [NSMutableArray arrayWithCapacity:delays.count];
NSTimeInterval runningDuration = 0;
for (NSNumber *delayNumber in delays) {
[keyTimes addObject:@(runningDuration / duration)];

View File

@ -35,8 +35,8 @@
@implementation RCTImageLoader
{
NSArray *_loaders;
NSArray *_decoders;
NSArray<id<RCTImageURLLoader>> *_loaders;
NSArray<id<RCTImageDataDecoder>> *_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<id<RCTImageURLLoader>> *loaders = [NSMutableArray array];
NSMutableArray<id<RCTImageDataDecoder>> *decoders = [NSMutableArray array];
for (id<RCTBridgeModule> module in bridge.modules.allValues) {
if ([module conformsToProtocol:@protocol(RCTImageURLLoader)]) {
[loaders addObject:module];
[loaders addObject:(id<RCTImageURLLoader>)module];
}
if ([module conformsToProtocol:@protocol(RCTImageDataDecoder)]) {
[decoders addObject:module];
[decoders addObject:(id<RCTImageDataDecoder>)module];
}
}

View File

@ -47,7 +47,7 @@ RCT_EXPORT_MODULE()
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
static NSSet *schemes = nil;
static NSSet<NSString *> *schemes = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// technically, RCTHTTPRequestHandler can handle file:// as well,

View File

@ -37,7 +37,7 @@ typedef RCTURLRequestCancellationBlock (^RCTHTTPQueryResult)(NSError *error, NSD
@implementation RCTHTTPFormDataHelper
{
NSMutableArray *_parts;
NSMutableArray<NSDictionary *> *_parts;
NSMutableData *_multipartBody;
RCTHTTPQueryResult _callback;
NSString *_boundary;
@ -122,7 +122,7 @@ static NSString *RCTGenerateFormBoundary()
@implementation RCTNetworking
{
NSMutableDictionary *_tasksByRequestID;
NSArray *_handlers;
NSArray<id<RCTURLRequestHandler>> *_handlers;
}
@synthesize bridge = _bridge;
@ -133,10 +133,10 @@ RCT_EXPORT_MODULE()
- (void)setBridge:(RCTBridge *)bridge
{
// get handlers
NSMutableArray *handlers = [NSMutableArray array];
NSMutableArray<id<RCTURLRequestHandler>> *handlers = [NSMutableArray array];
for (id<RCTBridgeModule> module in bridge.modules.allValues) {
if ([module conformsToProtocol:@protocol(RCTURLRequestHandler)]) {
[handlers addObject:module];
[handlers addObject:(id<RCTURLRequestHandler>)module];
}
}

View File

@ -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<id<RCTBridgeModule>> *(^)(void))block NS_DESIGNATED_INITIALIZER;
/**
* Simplest runTest function simply mounts the specified JS module with no

View File

@ -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<UIView *> *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);

View File

@ -80,7 +80,7 @@ static css_dim_t RCTMeasure(void *context, float width)
[self dirtyText];
}
- (NSDictionary *)processUpdatedProperties:(NSMutableSet *)applierBlocks
- (NSDictionary *)processUpdatedProperties:(NSMutableSet<RCTApplierBlock> *)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<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
[super applyLayoutNode:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];

View File

@ -16,7 +16,7 @@
@implementation RCTText
{
NSTextStorage *_textStorage;
NSMutableArray *_reactSubviews;
NSMutableArray<UIView *> *_reactSubviews;
CAShapeLayer *_highlightLayer;
}
@ -62,7 +62,7 @@
[_reactSubviews removeObject:subview];
}
- (NSArray *)reactSubviews
- (NSArray<UIView *> *)reactSubviews
{
return _reactSubviews;
}

View File

@ -17,7 +17,7 @@
@implementation RCTTextField
{
RCTEventDispatcher *_eventDispatcher;
NSMutableArray *_reactSubviews;
NSMutableArray<UIView *> *_reactSubviews;
BOOL _jsRequestingFirstResponder;
NSInteger _nativeEventCount;
}
@ -92,7 +92,7 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
RCTUpdatePlaceholder(self);
}
- (NSArray *)reactSubviews
- (NSArray<UIView *> *)reactSubviews
{
// TODO: do we support subviews of textfield in React?
// In any case, we should have a better approach than manually

View File

@ -65,7 +65,7 @@ RCT_EXPORT_SHADOW_PROPERTY(allowFontScaling, BOOL)
continue;
}
NSMutableArray *queue = [NSMutableArray arrayWithObject:rootView];
NSMutableArray<RCTShadowView *> *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");

View File

@ -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<NSString *> *)protocols NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithURLRequest:(NSURLRequest *)request;
// Some helper constructors.
- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray *)protocols;
- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray<NSString *> *)protocols;
- (instancetype)initWithURL:(NSURL *)url;
// Delegate queue will be dispatch_main_queue by default.

View File

@ -186,7 +186,7 @@ typedef void (^data_callback)(RCTSRWebSocket *webSocket, NSData *data);
dispatch_queue_t _delegateDispatchQueue;
dispatch_queue_t _workQueue;
NSMutableArray *_consumers;
NSMutableArray<RCTSRIOConsumer *> *_consumers;
NSInputStream *_inputStream;
NSOutputStream *_outputStream;
@ -228,12 +228,12 @@ typedef void (^data_callback)(RCTSRWebSocket *webSocket, NSData *data);
BOOL _isPumping;
NSMutableSet *_scheduledRunloops;
NSMutableSet<NSArray *> *_scheduledRunloops;
// We use this to retain ourselves.
__strong RCTSRWebSocket *_selfRetain;
NSArray *_requestedProtocols;
NSArray<NSString *> *_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<NSString *> *)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<NSString *> *)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<RCTSRIOConsumer *> *_bufferedConsumers;
}
- (instancetype)initWithBufferCapacity:(NSUInteger)poolSize;

View File

@ -59,7 +59,7 @@ void RCTAddAssertFunction(RCTAssertFunction assertFunction)
static RCTAssertFunction RCTGetLocalAssertFunction()
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSArray *functionStack = threadDictionary[RCTAssertFunctionStack];
NSArray<RCTAssertFunction> *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<RCTAssertFunction> *functionStack = threadDictionary[RCTAssertFunctionStack];
if (!functionStack) {
functionStack = [NSMutableArray new];
threadDictionary[RCTAssertFunctionStack] = functionStack;

View File

@ -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<Class> *RCTGetModuleClasses(void);
@interface RCTBridge ()
@ -64,11 +64,11 @@ RCT_EXTERN NSArray *RCTGetModuleClasses(void);
BOOL _valid;
BOOL _wasBatchActive;
__weak id<RCTJavaScriptExecutor> _javaScriptExecutor;
NSMutableArray *_pendingCalls;
NSMutableArray *_moduleDataByID;
NSMutableArray<NSArray *> *_pendingCalls;
NSMutableArray<RCTModuleData *> *_moduleDataByID;
RCTModuleMap *_modulesByName;
CADisplayLink *_jsDisplayLink;
NSMutableSet *_frameUpdateObservers;
NSMutableSet<RCTModuleData *> *_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<id<RCTBridgeModule>> *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<NSArray *> *config = [NSMutableArray new];
for (RCTModuleData *moduleData in _moduleDataByID) {
[config addObject:moduleData.config];
if ([moduleData.instance conformsToProtocol:@protocol(RCTFrameUpdateObserver)]) {
[_frameUpdateObservers addObject:moduleData];
id<RCTFrameUpdateObserver> observer = (id<RCTFrameUpdateObserver>)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<NSDictionary *> *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<NSString *> *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<NSArray *> *)buffer
{
NSArray *requestsArray = [RCTConvert NSArray:buffer];
NSArray<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<NSNumber *> *moduleIDs = requestsArray[RCTBridgeFieldRequestModuleIDs];
NSArray<NSNumber *> *methodIDs = requestsArray[RCTBridgeFieldMethodIDs];
NSArray<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<NSNumber *> *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 = ^{

View File

@ -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<id<RCTBridgeModule>> *(^RCTBridgeModuleProviderBlock)(void);
/**
* This function returns the module name for a given class.

View File

@ -39,9 +39,9 @@ NSString *const RCTDidCreateNativeModules = @"RCTDidCreateNativeModules";
@end
static NSMutableArray *RCTModuleClasses;
NSArray *RCTGetModuleClasses(void);
NSArray *RCTGetModuleClasses(void)
static NSMutableArray<Class> *RCTModuleClasses;
NSArray<Class> *RCTGetModuleClasses(void);
NSArray<Class> *RCTGetModuleClasses(void)
{
return RCTModuleClasses;
}

View File

@ -10,6 +10,7 @@
typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source);
@class RCTBridge;
@protocol RCTBridgeModule;
@protocol RCTBridgeDelegate <NSObject>
@ -17,7 +18,7 @@ typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source);
@optional
- (NSArray *)extraModulesForBridge:(RCTBridge *)bridge;
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge;
- (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback;
@end

View File

@ -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<NSString *> *)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<id<RCTBridgeMethod>> *)methodsToExport;
/**
* Injects constants into JS. These constants are made accessible via

View File

@ -96,25 +96,28 @@ typedef NSURL RCTFileURL;
scaleMultiplier:(CGFloat)scaleMultiplier;
typedef NSArray NSArrayArray;
+ (NSArrayArray *)NSArrayArray:(id)json;
+ (NSArray<NSArray *> *)NSArrayArray:(id)json;
typedef NSArray NSStringArray;
+ (NSStringArray *)NSStringArray:(id)json;
+ (NSArray<NSString *> *)NSStringArray:(id)json;
typedef NSArray NSStringArrayArray;
+ (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
typedef NSArray NSDictionaryArray;
+ (NSDictionaryArray *)NSDictionaryArray:(id)json;
+ (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
typedef NSArray NSURLArray;
+ (NSURLArray *)NSURLArray:(id)json;
+ (NSArray<NSURL *> *)NSURLArray:(id)json;
typedef NSArray RCTFileURLArray;
+ (RCTFileURLArray *)RCTFileURLArray:(id)json;
+ (NSArray<NSURL *> *)RCTFileURLArray:(id)json;
typedef NSArray NSNumberArray;
+ (NSNumberArray *)NSNumberArray:(id)json;
+ (NSArray<NSNumber *> *)NSNumberArray:(id)json;
typedef NSArray UIColorArray;
+ (UIColorArray *)UIColorArray:(id)json;
+ (NSArray<UIColor *> *)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 *> *)type##Array:(id)json \
{ \
return RCTConvertArrayValue(@selector(type:), json); \
}

View File

@ -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)

View File

@ -209,7 +209,7 @@ RCT_EXPORT_MODULE()
- (void)dispatchEvent:(id<RCTEvent>)event
{
NSMutableArray *arguments = [NSMutableArray new];
NSMutableArray<id /* any JSON value */> *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

View File

@ -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<NSDictionary *> *fakeStack = [NSMutableArray new];
for (NSDictionary *err in errorDetails[@"errors"]) {
[fakeStack addObject: @{
@"methodName": err[@"description"] ?: @"",

View File

@ -77,15 +77,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
@interface RCTKeyCommands ()
@property (nonatomic, strong) NSMutableSet *commands;
@property (nonatomic, strong) NSMutableSet<RCTKeyCommand *> *commands;
@end
@implementation UIResponder (RCTKeyCommands)
- (NSArray *)RCT_keyCommands
- (NSArray<UIKeyCommand *> *)RCT_keyCommands
{
NSSet *commands = [RCTKeyCommands sharedInstance].commands;
NSSet<RCTKeyCommand *> *commands = [RCTKeyCommands sharedInstance].commands;
return [[commands valueForKeyPath:@"keyCommand"] allObjects];
}

View File

@ -120,7 +120,7 @@ void RCTAddLogFunction(RCTLogFunction logFunction)
static RCTLogFunction RCTGetLocalLogFunction()
{
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
NSArray *functionStack = threadDictionary[RCTLogFunctionStack];
NSArray<RCTLogFunction> *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<RCTLogFunction> *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<NSString *> *stackSymbols = [NSThread callStackSymbols];
NSMutableArray<NSDictionary *> *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];

View File

@ -11,6 +11,8 @@
#import "RCTJavaScriptExecutor.h"
@protocol RCTBridgeMethod;
@interface RCTModuleData : NSObject
@property (nonatomic, weak, readonly) id<RCTJavaScriptExecutor> 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<id<RCTBridgeMethod>> *methods;
@property (nonatomic, copy, readonly) NSArray *config;
@property (nonatomic, strong) dispatch_queue_t queue;

View File

@ -17,10 +17,11 @@
@implementation RCTModuleData
{
NSDictionary *_constants;
NSArray *_methods;
NSString *_queueName;
}
@synthesize methods = _methods;
- (instancetype)initWithExecutor:(id<RCTJavaScriptExecutor>)javaScriptExecutor
moduleID:(NSNumber *)moduleID
instance:(id<RCTBridgeModule>)instance
@ -46,10 +47,10 @@
RCT_NOT_IMPLEMENTED(- (instancetype)init);
- (NSArray *)methods
- (NSArray<id<RCTBridgeMethod>> *)methods
{
if (!_methods) {
NSMutableArray *moduleMethods = [NSMutableArray new];
NSMutableArray<id<RCTBridgeMethod>> *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<NSString *> *entries =
((NSArray<NSString *> *(*)(id, SEL))imp)(_moduleClass, selector);
id<RCTBridgeMethod> 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<NSString *> *methods = self.methods.count ? [NSMutableArray new] : nil;
NSMutableArray<NSNumber *> *asyncMethods = nil;
for (id<RCTBridgeMethod> method in self.methods) {
if (method.functionType == RCTFunctionTypePromise) {
if (!asyncMethods) {

View File

@ -69,7 +69,7 @@ extern BOOL RCTBridgeModuleClassIsRegistered(Class cls);
return [_modulesByName keyEnumerator];
}
- (NSArray *)allValues
- (NSArray<id<RCTBridgeModule>> *)allValues
{
// don't perform validation in this case because we only want to error when
// an invalid module is specifically requested

View File

@ -47,7 +47,7 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
{
Class _moduleClass;
NSInvocation *_invocation;
NSArray *_argumentBlocks;
NSArray<RCTArgumentBlock> *_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<RCTMethodArgument *> **);
void RCTParseObjCMethodName(NSString **objCMethodName, NSArray<RCTMethodArgument *> **arguments)
{
static NSRegularExpression *typeNameRegex;
static dispatch_once_t onceToken;
@ -148,7 +148,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
- (void)processMethodSignature
{
NSArray *arguments;
NSArray<RCTMethodArgument *> *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<RCTArgumentBlock> *argumentBlocks =
[[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
#define RCT_ARG_BLOCK(_logic) \
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) { \

View File

@ -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<NSNumber *> *RCTPerformanceLoggerOutput(void);
NSArray *RCTPerformanceLoggerLabels(void);

View File

@ -36,7 +36,7 @@ void RCTPerformanceLoggerSet(RCTPLTag tag, int64_t value)
RCTPLData[tag][1] = value;
}
NSArray *RCTPerformanceLoggerOutput(void)
NSArray<NSNumber *> *RCTPerformanceLoggerOutput(void)
{
return @[
@(RCTPLData[RCTPLScriptDownload][0]),

View File

@ -27,7 +27,7 @@
- (id)objectForKeyedSubscript:(NSNumber *)key;
@property (readonly, nonatomic) NSUInteger count;
@property (readonly, nonatomic, copy) NSArray *allIndexes;
@property (readonly, nonatomic, copy) NSArray<NSNumber *> *allIndexes;
@property (readonly, nonatomic, copy) NSArray *allObjects;
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSNumber *idx, BOOL *stop))block;

View File

@ -79,7 +79,7 @@
return _storage.count;
}
- (NSArray *)allIndexes
- (NSArray<NSNumber *> *)allIndexes
{
return _storage.allKeys;
}

View File

@ -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<UITouch *> *_nativeTouches;
NSMutableArray<NSMutableDictionary *> *_reactTouches;
NSMutableArray<UIView *> *_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<UITouch *> *)touches
{
for (UITouch *touch in touches) {
@ -121,7 +121,7 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
}
}
- (void)_recordRemovedTouches:(NSSet *)touches
- (void)_recordRemovedTouches:(NSSet<UITouch *> *)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<UITouch *> *)touches
eventName:(NSString *)eventName
originatingTime:(__unused CFTimeInterval)originatingTime
{
// Update touches
NSMutableArray *changedIndexes = [NSMutableArray new];
NSMutableArray<NSNumber *> *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<NSDictionary *> *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<UITouch *> *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<UITouch *> *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<UITouch *> *)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<UITouch *> *)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<UITouch *> *)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<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];

View File

@ -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<NSString *> *otherButtonTitles);
// Return YES if image has an alpha component
RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image);

View File

@ -24,7 +24,7 @@
NSString *RCTJSONStringify(id jsonObject, NSError **error)
{
static SEL JSONKitSelector = NULL;
static NSSet *collectionTypes;
static NSSet<Class> *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<Class> *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<NSString *> *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<NSString *> *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;

View File

@ -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<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<NSArray *> *calls){
if (!weakSelf.valid || !calls) {
return;
}

View File

@ -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<UIAlertView *> *_alerts;
NSMutableArray<UIAlertController *> *_alertControllers;
NSMutableArray<RCTResponseSenderBlock> *_alertCallbacks;
NSMutableArray<NSArray<NSString *> *> *_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<NSString *> *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<NSString *> *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];

View File

@ -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;

View File

@ -14,6 +14,7 @@
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#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<NSDictionary *> **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<NSDictionary *> **)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<NSArray<NSString *> *> *)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<NSString *> *)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<NSDictionary *> *errors;
NSMutableArray<NSArray<NSString *> *> *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<NSDictionary *> *errors;
for (NSArray<NSString *> *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<NSDictionary *> *errors;
for (__strong NSArray<NSString *> *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<NSDictionary *> *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 {

View File

@ -138,8 +138,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
NSURLSessionDataTask *_updateTask;
NSURL *_liveReloadURL;
BOOL _jsLoaded;
NSArray *_presentedItems;
NSMutableArray *_extraMenuItems;
NSArray<RCTDevMenuItem *> *_presentedItems;
NSMutableArray<RCTDevMenuItem *> *_extraMenuItems;
}
@synthesize bridge = _bridge;
@ -375,9 +375,9 @@ RCT_EXPORT_MODULE()
[self settingsDidChange];
}
- (NSArray *)menuItems
- (NSArray<RCTDevMenuItem *> *)menuItems
{
NSMutableArray *items = [NSMutableArray new];
NSMutableArray<RCTDevMenuItem *> *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<RCTDevMenuItem *> *items = [self menuItems];
for (RCTDevMenuItem *item in items) {
switch (item.type) {
case RCTDevMenuTypeButton: {

View File

@ -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<NSDictionary *> *)stack;
- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack;
- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack;
- (void)handleSoftJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
- (void)handleFatalJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
- (void)updateJSExceptionWithMessage:(NSString *)message stack:(NSArray<NSDictionary *> *)stack exceptionId:(NSNumber *)exceptionId;
@end

View File

@ -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];
}

View File

@ -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<NSDictionary *> *)stack;
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack;
- (void)dismiss;

View File

@ -23,7 +23,7 @@
{
UITableView *_stackTraceTableView;
NSString *_lastErrorMessage;
NSArray *_lastStackTrace;
NSArray<NSDictionary *> *_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<NSDictionary *> *)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<UIKeyCommand *> *)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<NSDictionary *> *)stack
{
[self showErrorMessage:message withStack:stack showIfHidden:YES];
}
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray *)stack
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack
{
[self showErrorMessage:message withStack:stack showIfHidden:NO];
}
- (void)showErrorMessage:(NSString *)message withStack:(NSArray *)stack showIfHidden:(BOOL)shouldShow
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)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<NSDictionary *> *)stack {}
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack {}
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack showIfHidden:(BOOL)shouldShow {}
- (void)dismiss {}
@end

View File

@ -145,7 +145,7 @@ RCT_EXPORT_MODULE()
- (void)didUpdateFrame:(__unused RCTFrameUpdate *)update
{
NSMutableArray *timersToCall = [NSMutableArray new];
NSMutableArray<NSNumber *> *timersToCall = [NSMutableArray new];
for (RCTTimer *timer in _timers.allObjects) {
if ([timer updateFoundNeedsJSUpdate]) {
[timersToCall addObject:timer.callbackID];

View File

@ -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<NSNumber *> *_rootViewTags;
NSMutableArray<dispatch_block_t> *_pendingUIBlocks;
// Animation
RCTLayoutAnimation *_nextLayoutAnimation; // RCT thread only
@ -201,7 +201,7 @@ static UIViewAnimationOptions UIViewAnimationOptionsFromRCTAnimationType(RCTAnim
// Keyed by viewName
NSDictionary *_componentDataByName;
NSMutableSet *_bridgeTransactionListeners;
NSMutableSet<id<RCTComponent>> *_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<id<RCTComponent>> *)children
fromRegistry:(RCTSparseArray *)registry
{
for (id<RCTComponent> child in children) {
RCTTraverseViewNodes(registry[child.reactTag], ^(id<RCTComponent> 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<RCTShadowView *> *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<NSNumber *> *frameReactTags =
[NSMutableArray arrayWithCapacity:viewsWithNewFrames.count];
NSMutableArray<NSValue *> *frames =
[NSMutableArray arrayWithCapacity:viewsWithNewFrames.count];
NSMutableArray<NSNumber *> *areNew =
[NSMutableArray arrayWithCapacity:viewsWithNewFrames.count];
NSMutableArray<NSNumber *> *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<RCTViewManagerUIBlock> *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<RCTApplierBlock> *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<NSNumber *> *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<RCTComponent>)container
atIndices:(NSArray *)atIndices
- (NSArray<id<RCTComponent>> *)_childrenToRemoveFromContainer:(id<RCTComponent>)container
atIndices:(NSArray<NSNumber *> *)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<id<RCTComponent>> *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<RCTComponent>)container
- (void)_removeChildren:(NSArray<id<RCTComponent>> *)children
fromContainer:(id<RCTComponent>)container
{
for (id removedChild in children) {
for (id<RCTComponent> 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<id<RCTComponent>> *)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<id<RCTComponent>> *)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<NSNumber *> *removeAtIndices = @[@(indexOfView)];
NSArray<NSNumber *> *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<NSNumber *> *)moveFromIndices
moveToIndices:(NSArray<NSNumber *> *)moveToIndices
addChildReactTags:(NSArray<NSNumber *> *)addChildReactTags
addAtIndices:(NSArray<NSNumber *> *)addAtIndices
removeAtIndices:(NSArray<NSNumber *> *)removeAtIndices
registry:(RCTSparseArray *)registry
{
id<RCTComponent> 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<id<RCTComponent>> *permanentlyRemovedChildren =
[self _childrenToRemoveFromContainer:container atIndices:removeAtIndices];
NSArray<id<RCTComponent>> *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<RCTComponent> view = registry[addChildReactTags[index]];
if (view) {
destinationsToChildrenToAdd[addAtIndices[index]] = view;
}
}
NSArray *sortedIndices = [destinationsToChildrenToAdd.allKeys sortedArrayUsingSelector:@selector(compare:)];
NSArray<NSNumber *> *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<dispatch_block_t> *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<RCTShadowView *> *childShadowViews = [shadowView reactSubviews];
NSMutableArray<NSDictionary *> *results =
[[NSMutableArray alloc] initWithCapacity:childShadowViews.count];
[childShadowViews enumerateObjectsUsingBlock:
^(RCTShadowView *childShadowView, NSUInteger idx, __unused BOOL *stop) {

View File

@ -424,7 +424,7 @@ RCT_EXPORT_MODULE()
_remaining = nil;
}
NSArray *lines = [log componentsSeparatedByString:@"\n"];
NSArray<NSString *> *lines = [log componentsSeparatedByString:@"\n"];
if (lines.count == 1) { // no newlines
_remaining = log;
return;

View File

@ -336,10 +336,11 @@ NSString *RCTProfileEnd(RCTBridge *bridge)
}
}
static NSMutableArray *RCTProfileGetThreadEvents(void)
static NSMutableArray<NSArray *> *RCTProfileGetThreadEvents(void)
{
static NSString *const RCTProfileThreadEventsKey = @"RCTProfileThreadEventsKey";
NSMutableArray *threadEvents = [NSThread currentThread].threadDictionary[RCTProfileThreadEventsKey];
NSMutableArray<NSArray *> *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<NSArray *> *events = RCTProfileGetThreadEvents();
NSArray *event = events.lastObject;
[events removeLastObject];

View File

@ -27,7 +27,7 @@ typedef void (^RCTBubblingEventBlock)(NSDictionary *body);
- (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex;
- (void)removeReactSubview:(id<RCTComponent>)subview;
- (NSArray *)reactSubviews;
- (NSArray<id<RCTComponent>> *)reactSubviews;
- (id<RCTComponent>)reactSuperview;
- (NSNumber *)reactTagAtPoint:(CGPoint)point;

View File

@ -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<NSString *> *typeAndKeyPath =
((NSArray<NSString *> *(*)(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<NSString *> *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<NSString *> *directEvents = [NSMutableArray new];
if (RCTClassOverridesInstanceMethod(managerClass, @selector(customDirectEventTypes))) {
NSArray *events = [_manager customDirectEventTypes];
NSArray<NSString *> *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<NSString *> *bubblingEvents = [NSMutableArray new];
if (RCTClassOverridesInstanceMethod(managerClass, @selector(customBubblingEventTypes))) {
NSArray *events = [_manager customBubblingEventTypes];
NSArray<NSString *> *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<NSString *> *(*)(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);

View File

@ -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<NSString *> *annotationIds;
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@property (nonatomic, copy) RCTBubblingEventBlock onPress;

View File

@ -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<NSString *> *newAnnotationIds = [NSMutableArray new];
NSMutableArray<RCTPointAnnotation *> *annotationsToDelete = [NSMutableArray new];
NSMutableArray<RCTPointAnnotation *> *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<id<MKAnnotation>> *)annotationsToDelete];
}
if (annotationsToAdd.count) {
[self addAnnotations:annotationsToAdd];
[self addAnnotations:(NSArray<id<MKAnnotation>> *)annotationsToAdd];
}
NSMutableArray *newIds = [NSMutableArray new];
for (RCTPointAnnotation *anno in self.annotations) {
if ([anno isKindOfClass:[MKUserLocation class]]) {
NSMutableArray<NSString *> *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;
}

View File

@ -51,18 +51,18 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
}
}
- (NSArray *)reactSubviews
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
{
return [NSArray arrayWithObjects:_modalViewController.view, nil];
return _modalViewController.view ? @[_modalViewController.view] : @[];
}
- (void)insertReactSubview:(UIView *)subview atIndex:(__unused NSInteger)atIndex
- (void)insertReactSubview:(UIView<RCTComponent> *)subview atIndex:(__unused NSInteger)atIndex
{
[subview addGestureRecognizer:_touchHandler];
_modalViewController.view = subview;
}
- (void)removeReactSubview:(UIView *)subview
- (void)removeReactSubview:(UIView<RCTComponent> *)subview
{
RCTAssert(subview == _modalViewController.view, @"Cannot remove view other than modal view");
_modalViewController.view = nil;

View File

@ -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<RCTNavItem *> *previousViews;
@property (nonatomic, readwrite, strong) NSMutableArray<RCTNavItem *> *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<RCTNavItem *> *)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");

View File

@ -9,6 +9,12 @@
#import <UIKit/UIKit.h>
#import "UIView+React.h"
@interface RCTPicker : UIPickerView
@property (nonatomic, copy) NSArray<NSDictionary *> *items;
@property (nonatomic, assign) NSInteger selectedIndex;
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@end

View File

@ -10,14 +10,8 @@
#import "RCTPicker.h"
#import "RCTUtils.h"
#import "UIView+React.h"
@interface RCTPicker() <UIPickerViewDataSource, UIPickerViewDelegate>
@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<NSDictionary *> *)items
{
_items = [items copy];
[self setNeedsLayout];

View File

@ -117,7 +117,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (RCTScrollEvent *)coalesceWithEvent:(RCTScrollEvent *)newEvent
{
NSArray *updatedChildFrames = [_userData[@"updatedChildFrames"] arrayByAddingObjectsFromArray:newEvent->_userData[@"updatedChildFrames"]];
NSArray<NSDictionary *> *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<NSValue *> *_cachedChildFrames;
BOOL _allowNextScrollNoMatterWhat;
CGRect _lastClippedToRect;
}
@ -412,7 +412,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
[subview removeFromSuperview];
}
- (NSArray *)reactSubviews
- (NSArray<UIView<RCTComponent> *> *)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<NSDictionary *> *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<NSDictionary *> *)calculateChildFramesData
{
NSMutableArray *updatedChildFrames = [NSMutableArray new];
NSMutableArray<NSDictionary *> *updatedChildFrames = [NSMutableArray new];
[[_contentView reactSubviews] enumerateObjectsUsingBlock:
^(UIView *subview, NSUInteger idx, __unused BOOL *stop) {

View File

@ -16,7 +16,7 @@
@interface RCTScrollView (Private)
- (NSArray *)calculateChildFramesData;
- (NSArray<NSDictionary *> *)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<NSDictionary *> *childFrames = [view calculateChildFramesData];
if (childFrames) {
callback(@[childFrames]);
}
}];
}
- (NSArray *)customDirectEventTypes
- (NSArray<NSString *> *)customDirectEventTypes
{
return @[
@"scrollBeginDrag",

View File

@ -13,7 +13,7 @@
@interface RCTSegmentedControl : UISegmentedControl
@property (nonatomic, copy) NSArray *values;
@property (nonatomic, copy) NSArray<NSString *> *values;
@property (nonatomic, assign) NSInteger selectedIndex;
@property (nonatomic, copy) RCTBubblingEventBlock onChange;

View File

@ -25,7 +25,7 @@
return self;
}
- (void)setValues:(NSArray *)values
- (void)setValues:(NSArray<NSString *> *)values
{
_values = [values copy];
[self removeAllSegments];

View File

@ -35,6 +35,9 @@ typedef void (^RCTApplierBlock)(RCTSparseArray *viewRegistry);
*/
@interface RCTShadowView : NSObject <RCTComponent>
- (NSArray<RCTShadowView *> *)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<RCTApplierBlock> *)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<RCTApplierBlock> *)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<RCTShadowView *> *)viewsWithNewFrame;
/**
* Recursively apply layout to children.
*/
- (void)applyLayoutNode:(css_node_t *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
viewsWithNewFrame:(NSMutableSet<RCTShadowView *> *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER;
/**

View File

@ -36,7 +36,7 @@ typedef NS_ENUM(unsigned int, meta_prop_t) {
RCTUpdateLifecycle _propagationLifecycle;
RCTUpdateLifecycle _textLifecycle;
NSDictionary *_lastParentProperties;
NSMutableArray *_reactSubviews;
NSMutableArray<RCTShadowView *> *_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<RCTShadowView *> *)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<RCTApplierBlock> *)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<RCTApplierBlock> *)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<RCTShadowView *> *)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<RCTShadowView *> *)reactSubviews
{
return _reactSubviews;
}

View File

@ -26,7 +26,7 @@
{
BOOL _tabsChanged;
UITabBarController *_tabController;
NSMutableArray *_tabViews;
NSMutableArray<RCTTabBarItem *> *_tabViews;
}
- (instancetype)initWithFrame:(CGRect)frame
@ -52,12 +52,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
_tabController.delegate = nil;
}
- (NSArray *)reactSubviews
- (NSArray<RCTTabBarItem *> *)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<UIViewController *> *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;
}

View File

@ -92,7 +92,7 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
@implementation RCTView
{
NSMutableArray *_reactSubviews;
NSMutableArray<UIView<RCTComponent> *> *_reactSubviews;
UIColor *_backgroundColor;
}
@ -413,7 +413,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused)
[subview removeFromSuperview];
}
- (NSArray *)reactSubviews
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
{
// The _reactSubviews array is only used when we have hidden
// offscreen views. If _reactSubviews is nil, we can assume

View File

@ -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<NSString *> *)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<NSString *> *)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<NSString *> *)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<NSString *> *)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<NSString *> *)propConfigShadow_##name { return @[@#type]; }
@end

View File

@ -69,7 +69,7 @@ RCT_EXPORT_MODULE()
return [RCTShadowView new];
}
- (NSArray *)customBubblingEventTypes
- (NSArray<NSString *> *)customBubblingEventTypes
{
return @[
@ -90,7 +90,7 @@ RCT_EXPORT_MODULE()
];
}
- (NSArray *)customDirectEventTypes
- (NSArray<NSString *> *)customDirectEventTypes
{
return @[];
}

View File

@ -15,6 +15,9 @@
@interface UIView (React) <RCTComponent>
- (NSArray<UIView<RCTComponent> *> *)reactSubviews;
- (UIView<RCTComponent> *)reactSuperview;
/**
* Used by the UIIManager to set the view frame.
* May be overriden to disable animation, etc.

View File

@ -51,12 +51,12 @@
[subview removeFromSuperview];
}
- (NSArray *)reactSubviews
- (NSArray<UIView<RCTComponent> *> *)reactSubviews
{
return self.subviews;
}
- (UIView *)reactSuperview
- (UIView<RCTComponent> *)reactSuperview
{
return self.superview;
}