SHARE
TWEET

Untitled

a guest Oct 14th, 2019 92 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top