feat:add nativeChannel on Android

This commit is contained in:
pengfei.zhou 2019-11-18 16:33:23 +08:00
parent 7d0ecfee52
commit 99c994b11b
7 changed files with 139 additions and 3 deletions

View File

@ -24,7 +24,6 @@
#import "DoricRegistry.h"
#import "DoricContextManager.h"
#import "DoricNativePlugin.h"
#import "DoricPromise.h"
#import "DoricUtil.h"
#import <JavaScriptCore/JavaScriptCore.h>
@ -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++) {

View File

@ -22,10 +22,15 @@
#import "DoricShaderPlugin.h"
#import "DoricRootNode.h"
#import "DoricUtil.h"
#import <JavaScriptCore/JavaScriptCore.h>
#import <objc/runtime.h>
@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:&param 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

View File

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

View File

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

View File

@ -32,4 +32,6 @@
- (void)setSubModel:(NSDictionary *)model in:(NSString *)viewId;
- (void)clearSubModel;
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId;
@end

View File

@ -122,4 +122,7 @@ - (void)clearSubModel {
[self.subNodes removeAllObjects];
}
- (DoricViewNode *)subNodeWithViewId:(NSString *)viewId {
return nil;
}
@end

View File

@ -220,4 +220,12 @@ - (void)requestLayout {
[self.superNode requestLayout];
}
- (NSNumber *)getWidth {
return @(self.view.width);
}
- (NSNumber *)getHeight {
return @(self.view.height);
}
@end