-
Notifications
You must be signed in to change notification settings - Fork 11
Improve URL -> VC Router for the ARSwitchboard #48
Comments
Hi @orta, let me comment about JLRoutes returning a BOOL. As I told you on twitter we use a very similar thing at what you want and also using JLRoutes. In that way we have not modified the original JLRoutes, the Router only gives us VC (doesn't do anything with presenting them) and we can also use it asynchronously. That's what we have come up with, I'm impatient to see how your approach will look like in the end ;) Cheers. |
I see the pattern you're talking about, that's interesting because it also allows for asynchronous view controllers in a way that our current use case doesn't. |
Alright thanks a lot @alexito4 - so I've hacked up a quick example based on my interpretation: @import Foundation;
@import UIKit;
@interface Route : NSObject
@property (nonatomic, strong) NSString *pattern;
@property (nonatomic, copy) UIViewController * (^generator)(NSDictionary *params);
@end
@interface ARSwitchboardTwo : NSObject
+ (instancetype)sharedInstance;
- (void)registerRoute:(Route *)route;
- (void)routePath:(NSString *)path completion:(void(^)(UIViewController *controller))completion;
@end #import "ARSwitchboardTwo.h"
@import JLRoutes;
@interface _ARInternalRoute : NSObject
@property (nonatomic, copy) NSDictionary *params;
@property (nonatomic, strong) Route *route;
@end
@implementation _ARInternalRoute
@end
@implementation Route
@end
@interface ARSwitchboardTwo()
@property (readonly, nonatomic, strong) JLRoutes *routes;
@property (readonly, nonatomic, strong) NSMutableArray <Route *> *internalRoutes;
@property (readwrite, nonatomic, strong) _ARInternalRoute *currentRoute;
@end
@implementation ARSwitchboardTwo
+ (instancetype)sharedInstance
{
static ARSwitchboardTwo *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ARSwitchboardTwo alloc] init];
});
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (!self) {
return nil;
}
_routes = [[JLRoutes alloc] init];
_internalRoutes = [NSMutableArray array];
return self;
}
- (void)registerRoute:(Route *)route
{
[self.internalRoutes addObject:route];
__weak typeof(self) weakSelf = self;
[self.routes addRoute:route.pattern handler:^BOOL(NSDictionary *parameters) {
_ARInternalRoute *current = [[_ARInternalRoute alloc] init];
current.route = route;
current.params = parameters;
weakSelf.currentRoute = current;
return YES;
}];
}
- (void)routePath:(NSString *)path completion:(void (^)(UIViewController *))completion
{
NSURL *url = [NSURL URLWithString:path];
if ([self.routes routeURL:url withParameters:nil]) {
Route *route = self.currentRoute.route;
NSDictionary *params = self.currentRoute.params;
UIViewController *result = route.generator(params);
completion(result);
} else {
self.currentRoute = nil;
completion(nil);
}
}
@end Then anything can register their own @implementation TwoViewController
+ (void)load
{
Route *route = [[Route alloc] init];
route.pattern = @"/two/:id";
route.generator = ^UIViewController * (NSDictionary *params) {
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.view.backgroundColor = [UIColor redColor];
return twoVC;
};
[[ARSwitchboardTwo sharedInstance] registerRoute:route];
}
@end and any other class can use their own completion based routing: - (IBAction)go:(id)sender
{
[[ARSwitchboardTwo sharedInstance] routePath:@"/two/thing" completion:^(UIViewController *controller) {
[self.navigationController pushViewController:controller animated:YES];
}];
} Full demo - http://cl.ly/0U0Z0l1m1N2Q/RoutingExample.zip |
@orta I like the result a lot 👍 I don’t really like the ‘current route’ state that’s needed because of the |
A lot of this is done now, and on my fork. |
/x/:id
routesJLRoutes does nearly everything here, but that it returns a BOOL rather than returning a VC. Could look into making a fork that does this, then see what Joel thinks.
The text was updated successfully, but these errors were encountered: