iOS:use safe method to prevent unexpected exception

This commit is contained in:
pengfeizhou 2021-02-01 15:31:24 +08:00 committed by osborn
parent 6bf38bd290
commit 5a12a770fd
11 changed files with 125 additions and 65 deletions

View File

@ -64,6 +64,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onHidden;
- (DoricViewNode *)targetViewNode:(NSString *)viewId;
- (void)dispatchToMainQueue:(_Nonnull dispatch_block_t)block;
@end
NS_ASSUME_NONNULL_END

View File

@ -26,6 +26,7 @@
#import "DoricConstant.h"
#import "DoricExtensions.h"
#import "DoricNativeDriver.h"
#import "DoricUtil.h"
@implementation DoricContext
@ -115,10 +116,23 @@ - (void)onShow {
- (void)onHidden {
[self callEntity:DORIC_ENTITY_HIDDEN withArgumentsArray:@[]];
}
- (UIViewController *)vc {
if(!_vc) {
if (!_vc) {
return [UIApplication sharedApplication].keyWindow.rootViewController;
}
return _vc;
}
- (void)dispatchToMainQueue:(_Nonnull dispatch_block_t)block {
dispatch_async(dispatch_get_main_queue(), ^{
@try {
block();
} @catch (NSException *exception) {
DoricLog(@"dispatchToMainQueue Error:%@", exception.reason);
[self.driver.registry onException:exception inContext:self];
}
});
}
@end

View File

@ -28,7 +28,9 @@ - (void)submit:(NSDictionary *)args withPromise:(DoricPromise *)promise {
- (void)animateRender:(NSDictionary *)args withPromise:(DoricPromise *)promise {
NSNumber *duration = args[@"duration"];
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
NSString *viewId = args[@"id"];
[UIView animateWithDuration:[duration floatValue] / 1000
animations:^{
@ -45,6 +47,6 @@ - (void)animateRender:(NSDictionary *)args withPromise:(DoricPromise *)promise {
completion:^(BOOL finished) {
[promise resolve:nil];
}];
});
}];
}
@end

View File

@ -26,7 +26,9 @@
@implementation DoricCoordinatorPlugin
- (void)verticalScrolling:(NSDictionary *)params withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
NSArray <NSString *> *scrollableIds = params[@"scrollable"];
DoricViewNode *scrollNode = nil;
for (NSString *value in scrollableIds) {
@ -103,7 +105,7 @@ - (void)verticalScrolling:(NSDictionary *)params withPromise:(DoricPromise *)pro
} else {
[promise reject:@"Scroller type error"];
}
});
}];
}
- (void)setValue:(DoricViewNode *)viewNode isNavBar:(BOOL)isNavBar name:(NSString *)name value:(id)value {

View File

@ -27,7 +27,9 @@
@implementation DoricModalPlugin
- (void)toast:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
__block DoricGravity gravity = DoricGravityBottom;
[dic[@"gravity"] also:^(NSNumber *it) {
gravity = (DoricGravity) [it integerValue];
@ -37,11 +39,13 @@ - (void)toast:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
} else {
ShowToast(dic[@"msg"], gravity);
}
});
}];
}
- (void)alert:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
message:dic[@"msg"]
preferredStyle:UIAlertControllerStyleAlert];
@ -52,11 +56,13 @@ - (void)alert:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
}];
[alert addAction:action];
[self.doricContext.vc presentViewController:alert animated:YES completion:nil];
});
}];
}
- (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
message:dic[@"msg"]
preferredStyle:UIAlertControllerStyleAlert];
@ -67,20 +73,22 @@ - (void)confirm:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
[promise reject:nil];
}];
[alert addAction:cancelAction];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:dic[@"okLabel"] ?: NSLocalizedString(@"Ok", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[promise resolve:nil];
}];
[alert addAction:okAction];
[self.doricContext.vc presentViewController:alert animated:YES completion:nil];
});
}];
}
- (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:dic[@"title"]
message:dic[@"msg"]
preferredStyle:UIAlertControllerStyleAlert];
@ -113,6 +121,6 @@ - (void)prompt:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
[alert addAction:okAction];
[self.doricContext.vc presentViewController:alert animated:YES completion:nil];
});
}];
}
@end

View File

@ -30,9 +30,11 @@ @implementation DoricNavBarPlugin
- (void)isHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
[promise resolve:@([self.doricContext.navBar doric_navBar_isHidden])];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -40,10 +42,12 @@ - (void)isHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise {
- (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
[self.doricContext.navBar doric_navBar_setHidden:[param[@"hidden"] boolValue]];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -51,10 +55,12 @@ - (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise {
- (void)setTitle:(NSDictionary *)param withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
[self.doricContext.navBar doric_navBar_setTitle:param[@"title"]];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -62,11 +68,13 @@ - (void)setTitle:(NSDictionary *)param withPromise:(DoricPromise *)promise {
- (void)setBgColor:(NSDictionary *)param withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
UIColor *color = DoricColor(param[@"color"]);
[self.doricContext.navBar doric_navBar_setBackgroundColor:color];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -74,7 +82,9 @@ - (void)setBgColor:(NSDictionary *)param withPromise:(DoricPromise *)promise {
- (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
NSString *viewId = params[@"id"];
NSString *type = params[@"type"];
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
@ -82,7 +92,7 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise {
viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
it.viewId = viewId;
[it initWithSuperNode:nil];
NSMutableDictionary <NSString *, DoricViewNode *> *map = self.doricContext.headNodes[TYPE_LEFT];
if (map != nil) {
self.doricContext.headNodes[TYPE_LEFT][viewId] = it;
@ -96,7 +106,7 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise {
[viewNode blend:params[@"props"]];
[self.doricContext.navBar doric_navBar_setLeft:viewNode.view];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -104,7 +114,9 @@ - (void)setLeft:(NSDictionary *)params withPromise:(DoricPromise *)promise {
- (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
NSString *viewId = params[@"id"];
NSString *type = params[@"type"];
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
@ -112,7 +124,7 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise {
viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
it.viewId = viewId;
[it initWithSuperNode:nil];
NSMutableDictionary <NSString *, DoricViewNode *> *map = self.doricContext.headNodes[TYPE_RIGHT];
if (map != nil) {
self.doricContext.headNodes[TYPE_RIGHT][viewId] = it;
@ -126,7 +138,7 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise {
[viewNode blend:params[@"props"]];
[self.doricContext.navBar doric_navBar_setRight:viewNode.view];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}
@ -134,7 +146,9 @@ - (void)setRight:(NSDictionary *)params withPromise:(DoricPromise *)promise {
- (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise {
if (self.doricContext.navBar) {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
NSString *viewId = params[@"id"];
NSString *type = params[@"type"];
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
@ -142,7 +156,7 @@ - (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise {
viewNode = [[DoricViewNode create:self.doricContext withType:type] also:^(DoricViewNode *it) {
it.viewId = viewId;
[it initWithSuperNode:nil];
NSMutableDictionary <NSString *, DoricViewNode *> *map = self.doricContext.headNodes[TYPE_CENTER];
if (map != nil) {
self.doricContext.headNodes[TYPE_CENTER][viewId] = it;
@ -156,7 +170,7 @@ - (void)setCenter:(NSDictionary *)params withPromise:(DoricPromise *)promise {
[viewNode blend:params[@"props"]];
[self.doricContext.navBar doric_navBar_setCenter:viewNode.view];
[promise resolve:nil];
});
}];
} else {
[promise reject:@"Not implement NavBar"];
}

View File

@ -22,7 +22,9 @@
@implementation DoricNavigatorPlugin
- (void)push:(NSDictionary *)params {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
BOOL animated = YES;
NSString *source = params[@"source"];
NSString *alias = source;
@ -37,21 +39,23 @@ - (void)push:(NSDictionary *)params {
}
}
[self.doricContext.navigator doric_navigator_push:source alias:alias animated:animated extra:config[@"extra"]];
});
}];
}
- (void)pop:(NSDictionary *)params {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
BOOL animated = YES;
if (params[@"animated"]) {
animated = [params[@"animated"] boolValue];
}
[self.doricContext.navigator doric_navigator_pop:animated];
});
}];
}
- (void)openUrl:(NSString *)urlString withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
[self.doricContext dispatchToMainQueue:^{
NSURL *url = [NSURL URLWithString:urlString];
[UIApplication.sharedApplication openURL:url options:@{} completionHandler:^(BOOL success) {
if (success) {
@ -60,6 +64,6 @@ - (void)openUrl:(NSString *)urlString withPromise:(DoricPromise *)promise {
[promise reject:@"Cannot open"];
}
}];
});
}];
}
@end

View File

@ -30,7 +30,9 @@ - (instancetype)initWithContext:(DoricContext *)doricContext {
}
- (void)inset:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (@available(iOS 11.0, *)) {
UIView *superView;
if (self.doricContext.vc) {
@ -38,25 +40,25 @@ - (void)inset:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
} else {
superView = [UIApplication sharedApplication].windows.lastObject;
}
CGFloat top = superView.safeAreaInsets.top;
CGFloat left = superView.safeAreaInsets.left;
CGFloat bottom = superView.safeAreaInsets.bottom;
CGFloat right = superView.safeAreaInsets.right;
[promise resolve:@{
@"top": @(top),
@"left": @(left),
@"bottom": @(bottom),
@"right": @(right),
@"top": @(top),
@"left": @(left),
@"bottom": @(bottom),
@"right": @(right),
}];
} else {
[promise resolve:@{
@"top": @(0),
@"left": @(0),
@"bottom": @(0),
@"right": @(0),
@"top": @(0),
@"left": @(0),
@"bottom": @(0),
@"right": @(0),
}];
}
});
}];
}
@end

View File

@ -14,7 +14,9 @@ @implementation DoricPopoverPlugin
static NSString *TYPE = @"popover";
- (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
UIView *superView = self.doricContext.vc.view;
if (!self.fullScreenView) {
self.fullScreenView = [[UIView new] also:^(UIView *it) {
@ -52,12 +54,14 @@ - (void)show:(NSDictionary *)params withPromise:(DoricPromise *)promise {
[viewNode blend:params[@"props"]];
[self.fullScreenView.doricLayout apply];
[promise resolve:nil];
});
}];
}
- (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise {
NSString *viewId = params[@"id"];
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (viewId) {
DoricViewNode *viewNode = [self.doricContext targetViewNode:viewId];
[self dismissViewNode:viewNode];
@ -65,7 +69,7 @@ - (void)dismiss:(NSDictionary *)params withPromise:(DoricPromise *)promise {
[self dismissPopover];
}
[promise resolve:nil];
});
}];
}
- (void)dismissViewNode:(DoricViewNode *)node {

View File

@ -33,7 +33,7 @@ - (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
return;
}
__weak typeof(self) _self = self;
dispatch_async(dispatch_get_main_queue(), ^{
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (self.doricContext == nil) {
return;
@ -50,11 +50,13 @@ - (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
[viewNode requestLayout];
}
[promise resolve:nil];
});
}];
}
- (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (self.doricContext == nil) {
return;
}
@ -76,7 +78,7 @@ - (void)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise {
} else {
[self findClass:[viewNode class] target:viewNode method:name promise:promise argument:args];
}
});
}];
}
- (id)createParamWithMethodName:(NSString *)method promise:(DoricPromise *)promise argument:(id)argument {

View File

@ -26,36 +26,42 @@
@implementation DoricStatusBarPlugin
- (void)setHidden:(NSDictionary *)param withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (self.doricContext.navBar) {
if ([self.doricContext.navBar isKindOfClass:DoricViewController.class]) {
DoricViewController * target = ((DoricViewController *)self.doricContext.navBar);
DoricViewController *target = ((DoricViewController *) self.doricContext.navBar);
target.statusBarHidden = [param[@"hidden"] boolValue];
[target setNeedsStatusBarAppearanceUpdate];
}
}
});
}];
}
- (void)setMode:(NSDictionary *)param withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (self.doricContext.navBar) {
if ([self.doricContext.navBar isKindOfClass:DoricViewController.class]) {
DoricViewController * target = ((DoricViewController *)self.doricContext.navBar);
DoricViewController *target = ((DoricViewController *) self.doricContext.navBar);
target.statusBarMode = [param[@"mode"] intValue];
[target setNeedsStatusBarAppearanceUpdate];
}
}
});
}];
}
- (void)setColor:(NSDictionary *)param withPromise:(DoricPromise *)promise {
dispatch_async(dispatch_get_main_queue(), ^{
__weak typeof(self) _self = self;
[self.doricContext dispatchToMainQueue:^{
__strong typeof(_self) self = _self;
if (self.doricContext.navBar) {
UIColor *color = DoricColor(param[@"color"]);
[self.doricContext.navBar doric_navBar_setBackgroundColor:color];
}
});
}];
}
@end