Routable
Apr 3, 2013Find Routable on Github for Android and for iOS
Long ago, there was an iOS library known as Three20. Among Three20's many contributions was the TTNavigator, which allowed apps to be organized using URL-based routes. It was a pretty good idea, but got lost in the shuffle as Three20 fell by the wayside. Well, until now.
Routable is a set of libraries for both Android and iOS inspired by Three20's URL navigator. Here's how it works:
1. Define your routes.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ...
[[Routable sharedRouter] map:@"user/:id" toController:[UserController class]];
[[Routable sharedRouter] map:@"messages" toController:[MessagesController class]];
}
public class PropellerApplication extends Application {
@Override
public void onCreate() {
// ...
Router.sharedRouter().map("users/:id", UserActivity.class);
Router.sharedRouter().map("messsages", MessagesActivity.class);
}
}
2. Implement the required Routable protocol in either your UIViewController
or Activity
subclass:
@implementation UserController
// This is a required method
- (id)initWithRouterParams:(NSDictionary *)params {
if ((self = [self initWithNibName:nil bundle:nil])) {
self.userId = [params objectForKey: @"id"];
}
return self;
}
@end
public class UserActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Parameters are passed in the extras
Bundle intentExtras = getIntent().getExtras();
String userId = intentExtras.get("id");
}
}
3. Open a route, anywhere in your app!
[[Routable sharedRouter] open:@"users/16"];
Router.sharedRouter().open("users/16");
Why?
The benefit of structuring your app like this, as opposed to a loose collection of UIViewController
and Activity
objects, is that you can open any "screen" from any point in your code without wrangling Intent
s or controller allocations:
- (void)messagesTapped:(id)sender {
[[Routable sharedRouter] open:@"messages"];
}
aView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Router.sharedRouter().open("messages");
}
});
Or, imagine you're receiving push notifications from Apple or Google. Instead of hacking together a pseudo-protocol to determine what to show when a user opens a notification, just pass the appropriate Routable
URL:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSString *url = [userInfo objectForKey:@"url"];
// => @"messages/123123"
[[Routable sharedRouter] open: url];
}
public class GCMIntentService extends GCMBaseIntentService {
@Override
protected void onMessage(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String route = extras.getString("url");
// => "messages/123123"
Router.sharedRouter().open(route);
}
}
What else?
Routable has some other neat features, most notably the ability to route anonymous callbacks to URLs:
[[Routable sharedRouter] map:@"logout" toCallback:^(NSDictionary *params) {
[User logout];
}];
Router.sharedRouter().map("logout", new Router.RouterCallback() {
public void run(Map<String, String> extras) {
User.logout();
}
});
Contribute
We'd love to hear how you're using Routable and find out what else you think it can do. Don't hesitate to send pull-requests to the Android or iOS repos!