美文网首页
iOS | MJRouter 一窥

iOS | MJRouter 一窥

作者: 清無 | 来源:发表于2023-07-08 12:23 被阅读0次

Typedef

typedef void(^ICBCRouterURLHandler)(NSDictionary * _Nullable params);
typedef id _Nullable(^ICBCRouterURLResultHandler)(NSDictionary * _Nullable params);

URL-Handler way

Register

  • Interface
+ (void)registerUrl: (NSString * _Nonnull)url;
+ (void)registerUrl: (NSString * _Nonnull)url handler: (ICBCRouterURLHandler _Nullable)handler;
+ (void)registerUrl: (NSString * _Nonnull)url resultingHandler: (ICBCRouterURLResultHandler _Nullable)resultHandler;
  • Implementation
+ (void)registerUrl: (NSString * _Nonnull)url{
    [self registerUrl:url handler:nil];
}

+ (void)registerUrl: (NSString * _Nonnull)url handler: (ICBCRouterURLHandler _Nullable)handler{
    if([url length]) {
        [self sharedRouter].urlRoutes[url] = @{
            url: handler ? handler : ^(NSDictionary *_){}
        };
    }
}

+ (void)registerUrl: (NSString * _Nonnull)url resultingHandler: (ICBCRouterURLResultHandler _Nullable)resultHandler{
    if([url length]) {
        [self sharedRouter].urlRoutes[url] = resultHandler ? resultHandler : ^id(NSDictionary *_){ return nil; };
    }
}

Call

  • Interface
+ (void)callUrl: (NSString * _Nonnull)url;
+ (void)callUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params;
+ (id _Nullable)resultingUrl: (NSString * _Nonnull)url  withParams: (NSDictionary * _Nullable)params;
  • Implementation
+ (void)callUrl: (NSString * _Nonnull)url{
    [self callUrl:url withParams:@{}];
}

+ (void)callUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params{
    id handler = [self _handlerForUrl:url];
    ICBCRouterURLHandler urlHandler = (ICBCRouterURLHandler)handler;
    if(urlHandler) {
        return urlHandler(params);
    }
}

+ (id _Nullable)resultingUrl: (NSString * _Nonnull)url  withParams: (NSDictionary * _Nullable)params{
    ICBCRouterURLResultHandler resultHandler = (ICBCRouterURLResultHandler)[self _handlerForUrl:url];
    if(resultHandler) {
        return resultHandler(params);
    }
    return nil;
}

Usage

  • Register
[ICBCRouter registerUrl:kTestUrl resultingHandler:^id _Nullable(NSDictionary * _Nullable params) {
        NSLog(@"params: %@",params);
        return [NSObject new];
    }];
  • Call
id obj = [ICBCRouter resultingUrl:kTestUrl withParams:@{
        @"p1": @1,
        @"p2": @2
    }];
    NSLog(@"%@", obj);

Class-Protocol way

Bind

  • Interface
+ (void)bindProtocol: (Protocol *)protocol forClass: (Class)cls;
+ (Class _Nullable)classForProtocol: (Protocol *)protocol;
+ (id _Nullable)instanceForProtocol: (Protocol *)protocol;
  • Implementation
+ (void)bindProtocol: (Protocol *)protocol forClass: (Class)cls{
    if(![self classForProtocol:protocol]) {
        id clsName = NSStringFromClass(cls);
        id protName = NSStringFromProtocol(protocol);
        NSMutableArray *prots = [self sharedRouter].classRoutes[clsName] ?: @[].mutableCopy;
        [prots addObject:protName];
        [self sharedRouter].classRoutes[clsName] = prots;
    }
}

+ (Class _Nullable)classForProtocol: (Protocol *)protocol{
    id protName = NSStringFromProtocol(protocol);
    __block id foundClassName = nil;
    [[self sharedRouter].classRoutes enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull clsName, NSMutableArray *prots, BOOL * _Nonnull stop) {
        NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF = %@",protName];
        if([prots filteredArrayUsingPredicate:pre].firstObject) {
            foundClassName = clsName;
            *stop = YES;
        }
    }];
    return foundClassName ? NSClassFromString(foundClassName) : nil;
}

+ (id _Nullable)instanceForProtocol: (Protocol *)protocol{
    Class cls = [self classForProtocol:protocol];
    return cls ? [cls new] : nil;
}

Usage

  • TestProtocol
@protocol TestProtocol <NSObject>
- (void)test;
@end
  • ViewController
@interface ViewController ()<TestProtocol>
@end
@implementation ViewController
- (void)test {
    NSLog(@"%s",__func__);
}
@end
  • Bind
    [ICBCRouter bindProtocol:@protocol(TestProtocol) forClass:self.class];
  • Invoke
NSObject<TestProtocol> *s = [ICBCRouter instanceForProtocol:@protocol(TestProtocol)];
if(s) {
    [s test];
}

Innerdef

API disable

- (instancetype)init UNAVAILABLE_ATTRIBUTE;
- (instancetype)new UNAVAILABLE_ATTRIBUTE;

Init & Properties

@property(nonatomic, strong)NSMutableDictionary *urlRoutes;
@property(nonatomic, strong)NSMutableDictionary *classRoutes;

- (instancetype)init
{
    self = [super init];
    if (self) {
        _urlRoutes = @{}.mutableCopy;
        _classRoutes = @{}.mutableCopy;
    }
    return self;
}

Singleton

+ (instancetype)sharedRouter {
    static dispatch_once_t onceToken;
    static ICBCRouter *obj = nil;
    dispatch_once(&onceToken, ^{
        obj = [self new];
    });
    return obj;
}

Reference

相关文章

网友评论

      本文标题:iOS | MJRouter 一窥

      本文链接:https://www.haomeiwen.com/subject/mrfjudtx.html