diff --git a/iOS/Pod/Classes/Extension/DoricBridgeExtension.m b/iOS/Pod/Classes/Extension/DoricBridgeExtension.m index e0aaed81..a2256a8b 100644 --- a/iOS/Pod/Classes/Extension/DoricBridgeExtension.m +++ b/iOS/Pod/Classes/Extension/DoricBridgeExtension.m @@ -24,7 +24,6 @@ #import "DoricRegistry.h" #import "DoricContextManager.h" #import "DoricNativePlugin.h" -#import "DoricPromise.h" #import "DoricUtil.h" #import @@ -57,7 +56,7 @@ - (id)callNativeWithContextId:(NSString *)contextId module:(NSString *)module me invocation.selector = selector; invocation.target = nativePlugin; __weak __typeof__(self) _self = self; - void (^block)(void) = ^() { + dispatch_block_t block = ^() { __strong __typeof__(_self) self = _self; @try { for (NSUInteger idx = 2; idx < methodSignature.numberOfArguments; idx++) { diff --git a/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m b/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m index bb095f8b..6a72d78c 100644 --- a/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m +++ b/iOS/Pod/Classes/Plugin/DoricShaderPlugin.m @@ -22,10 +22,15 @@ #import "DoricShaderPlugin.h" #import "DoricRootNode.h" +#import "DoricUtil.h" + +#import + +#import @implementation DoricShaderPlugin -- (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise { +- (void)render:(NSDictionary *)argument { __weak typeof(self) _self = self; dispatch_async(dispatch_get_main_queue(), ^{ __strong typeof(_self) self = _self; @@ -33,4 +38,100 @@ - (void)render:(NSDictionary *)argument withPromise:(DoricPromise *)promise { }); } +- (id)command:(NSDictionary *)argument withPromise:(DoricPromise *)promise { + NSArray *viewIds = argument[@"viewIds"]; + id args = argument[@"args"]; + NSString *name = argument[@"name"]; + DoricViewNode *viewNode = nil; + for (NSString *viewId in viewIds) { + if (!viewNode) { + viewNode = self.doricContext.rootNode; + } else { + if ([viewNode isKindOfClass:[DoricSuperNode class]]) { + viewNode = [((DoricSuperNode *) viewNode) subNodeWithViewId:viewId]; + } + } + } + if (!viewNode) { + [promise reject:@"Cannot find opposite view"]; + return nil; + } else { + return [self findClass:[viewNode class] target:viewNode method:name promise:promise argument:args]; + } +} + +- (id)createParamWithMethodName:(NSString *)method promise:(DoricPromise *)promise argument:(id)argument { + if ([method isEqualToString:@"withPromise"]) { + return promise; + } + return argument; +} + +- (id)findClass:(Class)clz target:(id)target method:(NSString *)name promise:(DoricPromise *)promise argument:(id)argument { + unsigned int count; + id ret = nil; + Method *methods = class_copyMethodList(clz, &count); + BOOL isFound = NO; + for (int i = 0; i < count; i++) { + NSString *methodName = [NSString stringWithCString:sel_getName(method_getName(methods[i])) encoding:NSUTF8StringEncoding]; + NSArray *array = [methodName componentsSeparatedByString:@":"]; + if (array && [array count] > 0) { + if ([array[0] isEqualToString:name]) { + isFound = YES; + SEL selector = NSSelectorFromString(methodName); + NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector]; + if (methodSignature) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + invocation.selector = selector; + invocation.target = target; + __weak __typeof__(self) _self = self; + dispatch_block_t block = ^() { + __strong __typeof__(_self) self = _self; + @try { + for (NSUInteger idx = 2; idx < methodSignature.numberOfArguments; idx++) { + if (idx - 2 > [array count]) { + break; + } + id param = [self createParamWithMethodName:array[idx - 2] promise:promise argument:argument]; + [invocation setArgument:¶m atIndex:idx]; + } + [invocation invoke]; + } @catch (NSException *exception) { + DoricLog(@"CallNative Error:%@", exception.reason); + } + }; + + const char *retType = methodSignature.methodReturnType; + if (!strcmp(retType, @encode(void))) { + ret = nil; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); + } else if (!strcmp(retType, @encode(id))) { + void *retValue; + block(); + [invocation getReturnValue:&retValue]; + id returnValue = (__bridge id) retValue; + [promise resolve:returnValue]; + } else { + DoricLog(@"Command Error:%@", @"Must return object type"); + ret = nil; + [promise reject:@"Command: Must return object type"]; + } + } + break; + } + } + } + + if (methods) { + free(methods); + } + if (!isFound) { + Class superclass = class_getSuperclass(clz); + if (superclass && superclass != [NSObject class]) { + return [self findClass:superclass target:target method:name promise:promise argument:argument]; + } + } + return ret; +} + @end diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.m b/iOS/Pod/Classes/Shader/DoricGroupNode.m index 5a4aae7c..a8bd3141 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.m +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.m @@ -159,4 +159,14 @@ - (void)blendSubNode:(NSDictionary *)subModel { } }]; } + +- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { + for (DoricViewNode *viewNode in self.childNodes) { + if ([viewId isEqualToString:viewNode.viewId]) { + return viewNode; + } + } + return nil; +} + @end diff --git a/iOS/Pod/Classes/Shader/DoricListNode.m b/iOS/Pod/Classes/Shader/DoricListNode.m index b4865253..aa06569e 100644 --- a/iOS/Pod/Classes/Shader/DoricListNode.m +++ b/iOS/Pod/Classes/Shader/DoricListNode.m @@ -150,4 +150,17 @@ - (void)callItem:(NSUInteger)position height:(CGFloat)height { [self.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; }]; } + +- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { + for (UITableViewCell *tableViewCell in self.view.visibleCells) { + if ([tableViewCell isKindOfClass:[DoricTableViewCell class]]) { + DoricListItemNode *node = ((DoricTableViewCell *) tableViewCell).doricListItemNode; + if ([viewId isEqualToString:node.viewId]) { + return node; + } + } + } + return nil; +} + @end diff --git a/iOS/Pod/Classes/Shader/DoricSuperNode.h b/iOS/Pod/Classes/Shader/DoricSuperNode.h index b9915f07..1fe10660 100644 --- a/iOS/Pod/Classes/Shader/DoricSuperNode.h +++ b/iOS/Pod/Classes/Shader/DoricSuperNode.h @@ -32,4 +32,6 @@ - (void)setSubModel:(NSDictionary *)model in:(NSString *)viewId; - (void)clearSubModel; + +- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId; @end \ No newline at end of file diff --git a/iOS/Pod/Classes/Shader/DoricSuperNode.m b/iOS/Pod/Classes/Shader/DoricSuperNode.m index ac1827d4..f3120924 100644 --- a/iOS/Pod/Classes/Shader/DoricSuperNode.m +++ b/iOS/Pod/Classes/Shader/DoricSuperNode.m @@ -122,4 +122,7 @@ - (void)clearSubModel { [self.subNodes removeAllObjects]; } +- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId { + return nil; +} @end \ No newline at end of file diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.m b/iOS/Pod/Classes/Shader/DoricViewNode.m index 1ef9c6e2..7049f702 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.m +++ b/iOS/Pod/Classes/Shader/DoricViewNode.m @@ -220,4 +220,12 @@ - (void)requestLayout { [self.superNode requestLayout]; } +- (NSNumber *)getWidth { + return @(self.view.width); +} + +- (NSNumber *)getHeight { + return @(self.view.height); +} + @end