一直都有用推送梯码,但一直以來(lái)都只是知道怎么處理具體的原理、實(shí)現(xiàn)流程就不是很清楚好啰,最近有時(shí)間轩娶,就具體學(xué)習(xí)了一下,分享給大家框往,希望看完我的這篇文章鳄抒,對(duì)大家有所幫助。
APNS的推送機(jī)制
這里 Provider 是指某個(gè)應(yīng)用的Developer椰弊,當(dāng)然如果開發(fā)者使用極光的服務(wù)许溅,那么這里的Provider就是極光的推送服務(wù)程序了。上圖可以分為三步:
第一步:極光推送服務(wù)程序把要發(fā)送的消息秉版、目的設(shè)備的唯一標(biāo)識(shí)打包贤重,發(fā)給APNs。
第二步:APNs在自身的已注冊(cè)Push服務(wù)的應(yīng)用列表中清焕,查找有相應(yīng)標(biāo)識(shí)的設(shè)備并蝗,并把消息發(fā)送到設(shè)備。
第三步:iOS系統(tǒng)把發(fā)來(lái)的消息傳遞給相應(yīng)的應(yīng)用程序秸妥,并且按照設(shè)定彈出Push通知
從上圖我們可以看到滚停。
1、首先是應(yīng)用程序注冊(cè)消息推送粥惧。
2键畴、 IOS跟APNS Server要deviceToken。應(yīng)用程序接受deviceToken突雪。
3起惕、應(yīng)用程序?qū)eviceToken發(fā)送給PUSH服務(wù)端程序。
4咏删、 服務(wù)端程序向APNS服務(wù)發(fā)送消息疤祭。
5、APNS服務(wù)將消息發(fā)送給iPhone應(yīng)用程序饵婆。
代碼里面如何實(shí)現(xiàn)推送
首先,我們要獲取DeviceToken。
App需要每次啟動(dòng)的時(shí)候都去注冊(cè)遠(yuǎn)程通知——通過(guò)調(diào)用UIApplication的registerForRemoteNotificationTypes:方法侨核,傳遞給它你希望支持的消息類型參數(shù)即可草穆,例如:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// do some initiale working
...
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
return YES;
}
如果注冊(cè)成功,APNs會(huì)返回給你設(shè)備的token搓译,iOS系統(tǒng)會(huì)把它傳遞給app delegate代理——application:didRegisterForRemoteNotificationsWithDeviceToken:方法悲柱,你應(yīng)該在這個(gè)方法里面把token保存到極光后臺(tái),例如:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"Receive DeviceToken: %@", deviceToken);
[JPUSHService registerDeviceToken:deviceToken];
}
如果注冊(cè)失敗些己,application:didFailToRegisterForRemoteNotificationsWithError:方法會(huì)被調(diào)用豌鸡,通過(guò)NSError參數(shù)你可以看到具體的出錯(cuò)信息,例如:
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"注冊(cè)失敗段标,無(wú)法獲取設(shè)備ID, 具體錯(cuò)誤: %@", error);
}
請(qǐng)注意涯冠,注冊(cè)流程需要在app每次啟動(dòng)時(shí)調(diào)用,這并不不會(huì)帶來(lái)額外的負(fù)擔(dān)逼庞,因?yàn)閕OS操作系統(tǒng)在第一次獲得了有效的device token之后蛇更,會(huì)本地緩存起來(lái),以后app再調(diào)用registerForRemoteNotificationTypes:的時(shí)候會(huì)立刻返回赛糟,并不會(huì)再進(jìn)行網(wǎng)絡(luò)請(qǐng)求派任。另外,app層面不應(yīng)該對(duì)device token進(jìn)行緩存璧南,因?yàn)閐evice token也有可能變化——如果用戶重裝了操作系統(tǒng)掌逛,那么APNs再次給出的device token就會(huì)和之前的不一樣,又或者是司倚,用戶restore了原來(lái)的backup到新的設(shè)備上豆混,那么原來(lái)的device token也會(huì)失效。
其次对湃,我們要處理收到消息之后的回調(diào)
我們可以設(shè)想一下消息通知的幾種使用場(chǎng)景:
1崖叫,在app沒(méi)有被啟動(dòng)的時(shí)候,接收到了消息通知拍柒。這時(shí)候操作系統(tǒng)會(huì)按照默認(rèn)的方式來(lái)展現(xiàn)一個(gè)alert消息心傀,在app icon上標(biāo)記一個(gè)數(shù)字,甚至播放一段聲音拆讯。
2脂男,用戶看到消息之后,點(diǎn)擊了一下action按鈕或者點(diǎn)擊了應(yīng)用圖標(biāo)
如果action按鈕被點(diǎn)擊了种呐,系統(tǒng)會(huì)通過(guò)調(diào)用application:didFinishLaunchingWithOptions:這個(gè)代理方法來(lái)啟動(dòng)應(yīng)用宰翅,并且會(huì)把notification的payload數(shù)據(jù)傳遞進(jìn)去。
如果應(yīng)用圖標(biāo)被點(diǎn)擊了爽室,系統(tǒng)也一樣會(huì)調(diào)用application:didFinishLaunchingWithOptions:這個(gè)代理方法來(lái)啟動(dòng)應(yīng)用汁讼,唯一不同的是這時(shí)候啟動(dòng)參數(shù)里面不會(huì)有任何notification的信息。
3,如果遠(yuǎn)程消息發(fā)送過(guò)來(lái)的時(shí)候嘿架,app正在運(yùn)行瓶珊,這時(shí)候會(huì)發(fā)生什么呢?
app代理的application:didReceiveRemoteNotification:方法會(huì)被調(diào)用耸彪,同時(shí)遠(yuǎn)程消息中的payload數(shù)據(jù)會(huì)作為參數(shù)傳遞進(jìn)去伞芹。
示例代碼如下:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {
MyAlertShow(@"(UIBackgroundFetchResult))completionHandler", @"6666");
NSLog(@"(UIBackgroundFetchResult))completionHandler");
[MyRemoteNoticeMangeZH dealWithRemoteDic:userInfo];
}