Guest User

Untitled

a guest
Oct 14th, 2019
102
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #import "Mediator.h"
  2.  
  3. NSString * const kMediatorParamsKeySwiftTargetModuleName = @"kMediatorParamsKeySwiftTargetModuleName";
  4.  
  5.  
  6. @interface Mediator ()
  7.  
  8. @property (nonatomic, copy) NSMutableDictionary *cachedTarget;
  9.  
  10. @end
  11.  
  12. @implementation Mediator
  13.  
  14. + (instancetype)sharedInstance {
  15. static Mediator *mediator;
  16. static dispatch_once_t token;
  17. dispatch_once(&token, ^{
  18. mediator = [[Mediator alloc] init];
  19. });
  20.  
  21. return mediator;
  22. }
  23.  
  24. - (id)performActionWithUrl:(NSURL *)url completion:(void (^)(NSDictionary *))completion {
  25. NSMutableDictionary *params = [NSMutableDictionary dictionary];
  26. NSString *urlString = [url query];
  27.  
  28. for (NSString * params in [urlString componentsSeparatedByString:@"&"]) {
  29. NSArray *elements = [params componentsSeparatedByString:@"="];
  30. if (elements.count <2) {
  31. continue;
  32. }
  33.  
  34. [params setValue:elements.lastObject forKey:elements.firstObject];
  35. }
  36.  
  37. NSString *actionName = [url.path stringByReplacingOccurrencesOfString:@"/" withString:@""];
  38. if ([actionName hasPrefix:@"native"]) {
  39. return @(NO);
  40. }
  41.  
  42. id result = [self performTarget:url.host action:actionName params:params shouldCacheTarget:NO];
  43. if (completion && result) {
  44. completion(@{@"reuslt": result});
  45. } else {
  46. completion(nil);
  47. }
  48. return result;
  49. }
  50.  
  51. - (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget {
  52.  
  53. NSString *swiftModuleName = params[kMediatorParamsKeySwiftTargetModuleName];
  54.  
  55. // 1、创建 targetClassName
  56. NSString *targetClassName;
  57. if (swiftModuleName.length > 0) {
  58. targetClassName = [NSString stringWithFormat:@"%@.Target_%@", swiftModuleName, targetName];
  59. } else {
  60. targetClassName = [NSString stringWithFormat:@"Target_%@", targetName];
  61. }
  62.  
  63. NSObject *target = self.cachedTarget[targetClassName];
  64. if (target == nil) {
  65. // 2、创建 targetClass
  66. Class targetClass = NSClassFromString(targetClassName);
  67. // 3、创建 target
  68. target = [[targetClass alloc] init];
  69. }
  70.  
  71. if (shouldCacheTarget) {
  72. self.cachedTarget[targetClassName] = target;
  73. }
  74.  
  75. // 4、创建 actionString
  76. NSString *actionString = [NSString stringWithFormat:@"Action_%@", actionName];
  77. // 5、创建 selector
  78. SEL selctor = NSSelectorFromString(actionString);
  79.  
  80. if ([target respondsToSelector:selctor]) {
  81. return [self safePerformAction:target action:selctor params:params];
  82. } else {
  83. return nil;
  84. }
  85. }
  86.  
  87.  
  88.  
  89. - (id)safePerformAction:(NSObject *)target action:(SEL)action params:(NSDictionary *) params {
  90. // 6、创建 methodSignature
  91. NSMethodSignature *methodSignature = [target methodSignatureForSelector:action];
  92. if (methodSignature == nil) {
  93. return nil;
  94. }
  95.  
  96. // 7、创建 returnType
  97. const char* returnType = [methodSignature methodReturnType];
  98.  
  99. if (strcmp(returnType, @encode(void)) == 0) {
  100. // 8、创建 invocation
  101. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  102. [invocation setArgument:&params atIndex:2];
  103. [invocation setTarget:target];
  104. [invocation setSelector:action];
  105.  
  106. [invocation invoke];
  107.  
  108. return nil;
  109. }
  110.  
  111. if (strcmp(returnType, @encode(BOOL)) == 0) {
  112. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  113. [invocation setTarget:target];
  114. [invocation setSelector:action];
  115. [invocation setArgument:&params atIndex:2];
  116. [invocation invoke];
  117.  
  118. BOOL result = 0;
  119. [invocation getReturnValue:&result];
  120. return @(result);
  121. }
  122.  
  123. if (strcmp(returnType, @encode(CGFloat)) == 0) {
  124. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  125. [invocation setTarget:target];
  126. [invocation setSelector:action];
  127. [invocation setArgument:&params atIndex:2];
  128. [invocation invoke];
  129.  
  130. CGFloat result = 0;
  131. [invocation getReturnValue:&result];
  132. return @(result);
  133. }
  134.  
  135. if (strcmp(returnType, @encode(NSInteger)) == 0) {
  136. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  137. [invocation setTarget:target];
  138. [invocation setSelector:action];
  139. [invocation setArgument:&params atIndex:2];
  140. [invocation invoke];
  141.  
  142. NSInteger result = 0;
  143. [invocation getReturnValue:&result];
  144. return @(result);
  145. }
  146.  
  147. if (strcmp(returnType, @encode(NSUInteger)) == 0) {
  148. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
  149. [invocation setTarget:target];
  150. [invocation setSelector:action];
  151. [invocation setArgument:&params atIndex:2];
  152. [invocation invoke];
  153.  
  154. NSUInteger result = 0;
  155. [invocation getReturnValue:&result];
  156. return @(result);
  157. }
  158.  
  159. #pragma clang diagnostic push
  160. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  161. return [target performSelector:action withObject:params];
  162. #pragma cland diagnostic pop
  163. }
  164.  
  165. - (void)releaseCachedTargetWithTargetName:(NSString *)targetName {
  166. NSString *key = [NSString stringWithFormat:@"Target_%@",targetName];
  167. [self.cachedTarget removeObjectForKey:key];
  168. }
  169.  
  170. - (NSMutableDictionary *)cachedTarget{
  171. if (_cachedTarget == nil) {
  172. _cachedTarget = [NSMutableDictionary dictionary];
  173. }
  174. return _cachedTarget;
  175. }
  176.  
  177. @end
RAW Paste Data