Typedef
typedef void(^ICBCRouterURLHandler)(NSDictionary * _Nullable params);
typedef id _Nullable(^ICBCRouterURLResultHandler)(NSDictionary * _Nullable params);
URL-Handler way
Register
+ (void)registerUrl: (NSString * _Nonnull)url;
+ (void)registerUrl: (NSString * _Nonnull)url handler: (ICBCRouterURLHandler _Nullable)handler;
+ (void)registerUrl: (NSString * _Nonnull)url resultingHandler: (ICBCRouterURLResultHandler _Nullable)resultHandler;
+ (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
+ (void)callUrl: (NSString * _Nonnull)url;
+ (void)callUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params;
+ (id _Nullable)resultingUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params;
+ (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
[ICBCRouter registerUrl:kTestUrl resultingHandler:^id _Nullable(NSDictionary * _Nullable params) {
NSLog(@"params: %@",params);
return [NSObject new];
}];
id obj = [ICBCRouter resultingUrl:kTestUrl withParams:@{
@"p1": @1,
@"p2": @2
}];
NSLog(@"%@", obj);
Class-Protocol way
Bind
+ (void)bindProtocol: (Protocol *)protocol forClass: (Class)cls;
+ (Class _Nullable)classForProtocol: (Protocol *)protocol;
+ (id _Nullable)instanceForProtocol: (Protocol *)protocol;
+ (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
@protocol TestProtocol <NSObject>
- (void)test;
@end
@interface ViewController ()<TestProtocol>
@end
@implementation ViewController
- (void)test {
NSLog(@"%s",__func__);
}
@end
[ICBCRouter bindProtocol:@protocol(TestProtocol) forClass:self.class];
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