眨眼2016年就這么走到了結尾,再過兩天新年就要開始了。回顧從2016年開始養成的寫博客的習慣,一直能延續下來,保持了一整年,還是比較欣慰的一件事情。希望2017年自己的技術能夠繼續穩步的提升。
今天在這2016年的最后一篇博客里,咱來聊聊推送通知的跳轉。
當推送通知到達時,點擊推送通知跳轉到指定界面,是很多應用都會碰到的一個需求,而要實現這個功能,解決的方法也很多,若是去谷歌搜索,有一個萬能跳轉的文章可能會進入您的眼簾,但是我實際的去看了這個項目的源碼之后,感覺這個庫有一定的局限性,用runtime實現跳轉這不假,但是在請求字段里加上了ViewController
的類名,這其實就是局限的地方了,畢竟除了服務咱們iOS端,你也得考慮考慮安卓端的攻城獅不是,然而如果你換一個約定的字段再來解析,那倒不如用URL
來作為判斷依據更為方便。
之前的幾篇文章,我也在研究iOS開發的組件化的架構模式,也有的應用在走組件化的道路上使用了URL
來跳轉界面完成解耦,在實現推送時,我們也能沿用這個思路,用URL
實現界面的跳轉。關于使用哪個Router
框架,其實真的是蘿卜青菜各有所愛,很成熟的 JLRoutes、 routable-ios、 HHRouter、 MGJRouter,在經過比較已經實際使用之后,我選擇了MGJRouter
這款蘑菇街開源的組件應用到項目中。為什么會選擇MGJRouter
這款組件呢,其實理由就跟他簡單的介紹一樣,高效、靈活。
來說一說這個基本的使用方式,首先你得跟后臺約定推送的參數,比如我在跟后臺的約定里,參數名就是url
,那么我在拿到推送的userInfo
時,就需要把url
解析出來。在
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
這兩個方法中,你可以獲取到userInfo
,例如后端給我傳了這樣的推送消息
[aps: {
alert = "\U6d4b\U8bd5\U7cfb\U7edf\U6d88\U606f";
badge = 1;
category = system;
sound = "";
}, redirect: {
data = "<null>";
target = article;
"target_id" = 5397;
"target_url" = "lix://cms/articles/3333";
}, _j_msgid: 5228988433]
很清楚的看到我們需要拿到target_url
這個字段,至于怎么解析JSON,我就不啰嗦了,假設此時我們已經拿到了url
,url
其實為 lix://cms/articles/:id
這個格式,3333
是我們需要根據這個id跳轉到的文章界面。
#pragma mark - 推送地址
static NSString *ARTICLES_URL = @"lix://cms/articles/:id"; //資訊詳情
在定義好url
的情況下,我們需要先用MGJRouter
注冊我們的url
,
+ (void)registerArticlePush {
[MGJRouter registerURLPattern:ARTICLES_URL toHandler:^(NSDictionary *routerParameters) {
//打印URL
LixLog(@"routerParameterURL:%@", routerParameters[MGJRouterParameterURL]);
//獲取URL中的id
NSString *id = routerParameters[@"id"];
ArticleModel *model = [[ArticleModel alloc] init];
model._id = id;
ArticleDetailViewController *articleViewController = [[ArticleDetailViewController alloc] init];
articleViewController.articleModel = model;
//界面跳轉
[LixObjcRouter pushController:articleViewController];
}];
}
這段代碼可以當成一個完整的業務邏輯的范例,在寫好業務邏輯之后,我們需要去AppDelegate
的func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
里注冊url
。
LixObjcRouter.registerArticlePush()
做完這些之后,咱們只要
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
這兩個方法里處理推送通知就好了,非常簡單的一個Api
。
[MGJRouter openURL:url];
到這里,推送之后的頁面跳轉也就差不多完成了,只要再注意badge
的數值處理,前臺時推送通知的處理等情況就可以了。
用完蘑菇街的Router
組件,又讓我想接著啰嗦上次的組件化的思考了,用完這種方式,我還是覺得,如果把這個框架引入進行組件化,那么每次啟動,都必須去注冊這些url
,如果小工程也沒有組件化的必要,可是大工程,管理url
又是一件費神的事情。
所以推送跳轉,我選擇MGJRouter
,因為足夠方便高效,可是組件化的道路,我更看好CTMediator這樣徹底解耦的方式。感興趣的自己搜索研究吧。
年前最后一篇,新年快樂,雞年大吉吧。