mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-03-26 07:04:05 +08:00
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:
committed by
facebook-github-bot-7
parent
31565781f2
commit
c5b990f65f
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user