iOS遠(yuǎn)程推送淺析


引言:iOS開發(fā),推送可以說是必須的傻粘,但是之前對(duì)于推送總是概念模糊每窖,最近借公司項(xiàng)目需求,深入了解了一下弦悉≈系洌“對(duì)于知識(shí)要懷有一顆敬畏的心!”稽莉,這是我iOS啟蒙老師說的話瀑志,想想真的是這樣,深感自己認(rèn)知的太淺薄劈猪!


App推送著實(shí)是很重要的一環(huán)昧甘,例如電商類的App,推送成就了其盈利的拼圖战得。
推送分為:遠(yuǎn)程推送和本地推送
遠(yuǎn)程推送:遠(yuǎn)程推送涉及較多充边,例如App運(yùn)行加載后會(huì)向蘋果的APNs服務(wù)器注冊(cè),獲得Token信息等等常侦,本文后面會(huì)介紹痛黎。
本地推送:本地推送較為簡(jiǎn)單,后續(xù)文章會(huì)介紹刮吧,本文只簡(jiǎn)單談?wù)勥h(yuǎn)程推送湖饱。

一、概要

  1. 注冊(cè)
  2. 分析接收推送消息后的調(diào)用方法
  • App運(yùn)行于前臺(tái)(Active)
  • App運(yùn)行于后臺(tái)(Background)
  • App未運(yùn)行

二杀捻、步驟細(xì)節(jié)

注冊(cè)
推送的注冊(cè)在iOS8中API變更井厌,具體如下。相信大家都已經(jīng)了解致讥,在這里就不在贅述仅仆!這里只貼出代碼。

//設(shè)置推送
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
    [[UIApplication sharedApplication] registerUserNotificationSettings:
    [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) 
                            categories:nil]];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}else {
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge| UIRemoteNotificationTypeSound];

}

需要注意的是:settingsForTypes中的類型對(duì)應(yīng)的就是原推送各個(gè)類型垢袱,但是名稱有所變化墓拜,其中Sound為推送提示聲音,badge為applicationIconBadgeNumber请契,Alert為推送提示的文字等咳榜。

注冊(cè)成功與否
在iOS開發(fā)中,App的全局代理方法內(nèi)有2個(gè)代理方法是注冊(cè)遠(yuǎn)程推送是否成功的回調(diào)方法爽锥。
注冊(cè)成功:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    //此方法返回?cái)?shù)據(jù) NSData 內(nèi)包含此設(shè)備的Token涌韩,也就是說注冊(cè)成功了。
    //在此實(shí)現(xiàn)將Token信息傳遞給你的后臺(tái)服務(wù)的代碼
}

注冊(cè)失斅纫摹:

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"推送注冊(cè)失敗:%@",error);
}

這里簡(jiǎn)要介紹下推送的流程臣樱,以便了解上述回調(diào)方法為什么要將Token信息傳遞給你的后端。
通俗的講:
首先腮考,App運(yùn)行并向Apple服務(wù)器注冊(cè)遠(yuǎn)程推送服務(wù)雇毫,也就是大家常聊起的APNs(APNs 是 Apple Push Notification service 的簡(jiǎn)稱),成功APNs會(huì)返回當(dāng)前設(shè)備的Token信息踩蔚,其次棚放,App內(nèi)部的邏輯就是將此Token信息,傳遞給你的后端服務(wù)寂纪,后端服務(wù)獲得此Token信息后就可以和APNs服務(wù)器“交互”了席吴,然后后端服務(wù)將要推送的某條信息,帶著Token信息推到APNs服務(wù)器捞蛋,APNs服務(wù)器拿到Token信息后孝冒,就知道要將推送消息推送到那臺(tái)設(shè)備上。
以上就是遠(yuǎn)程推送服務(wù)的大致流程(通俗理解)拟杉。詳細(xì)流程請(qǐng)參考 iOS程序犭袁 大神的文章庄涡。這是現(xiàn)階段最新的APNs介紹篇章,出自大神之手搬设,值得研讀哦穴店!_
至此,注冊(cè)成功后拿穴,就可以實(shí)現(xiàn)遠(yuǎn)程推送服務(wù)了

分析接收遠(yuǎn)程推送調(diào)用的方法

  • App運(yùn)行于前臺(tái)(Active)
    當(dāng)App在前臺(tái)運(yùn)行時(shí)泣洞,接收到遠(yuǎn)程通知的時(shí)候,并沒有任何的提示默色,比如聲音球凰,通知欄的提示。但是這時(shí)會(huì)調(diào)用App的代理方法(后續(xù)統(tǒng)一叫推送回調(diào)方法):
  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
             //實(shí)現(xiàn)你接收到遠(yuǎn)程推送的消息處理代碼腿宰;
  }    
  • App運(yùn)行于后臺(tái)(Background)
    當(dāng)App運(yùn)行與后臺(tái)的時(shí)候分為兩種情況:
    • 點(diǎn)擊通知欄進(jìn)入App:
         - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
             //實(shí)現(xiàn)你接收到遠(yuǎn)程推送的消息處理代碼呕诉;
          } 
    * 點(diǎn)擊App圖標(biāo)進(jìn)入App:
    `無動(dòng)作--不會(huì)調(diào)用任何推送相關(guān)回調(diào)方法`
  • App未運(yùn)行
    當(dāng)App未運(yùn)行的時(shí)候分為兩種情況:
    • 點(diǎn)擊通知欄進(jìn)入App:
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions{
         //判斷l(xiāng)aunchOptions字典內(nèi)是否含有推送的鍵值對(duì)  Key:@“UIApplicationLaunchOptionsRemoteNotificationKey”
         if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
            //實(shí)現(xiàn)你接收遠(yuǎn)程推送消息的消息處理代碼;
         }
    }
 * 點(diǎn)擊App圖標(biāo)進(jìn)入App:
 `無動(dòng)作 --會(huì)調(diào)用上面的didFinishLaunchingWithOptions方法吃度,但是這時(shí)launchOptions對(duì)應(yīng)的鍵值對(duì)為空甩挫,所以也不會(huì)進(jìn)入if判斷內(nèi)。`

對(duì)于App層出不窮椿每、變幻莫測(cè)的需求伊者,顯然以上可以處理遠(yuǎn)程推送的方法遠(yuǎn)遠(yuǎn)無法滿足需求!
iOS7更新推送API间护,推出了推送喚醒功能删壮,下面我們簡(jiǎn)要介紹一下推送喚醒。簡(jiǎn)單的說兑牡,就是接收到推送時(shí)央碟,系統(tǒng)將喚醒在后臺(tái)的應(yīng)用程序,并回調(diào)App代理的方法均函,執(zhí)行一些必要的代碼亿虽,例如請(qǐng)求數(shù)據(jù)、更新UI等苞也,減少用戶解鎖進(jìn)入應(yīng)用洛勉,等待數(shù)據(jù)加載的過程。詳情請(qǐng)參閱"喵神"Blog, 多多研讀喵神的Blog如迟,會(huì)使你收益頗豐收毫!
推送喚醒
如何實(shí)現(xiàn)推送喚醒呢攻走?首先是針對(duì)Xcode的,下面針對(duì)是否開啟推送喚醒進(jìn)行Xcode相應(yīng)設(shè)置此再,配置info.plist文件昔搂,如圖所示,勾選箭頭所指選項(xiàng):
[Xcode配置]

Xcode配置文件.png

其次输拇,需要在payload中加入content-available摘符,并設(shè)置為1。

aps { 
           alert = "something";
           badge = 0;//后端返回
           content-available = 1;
           sound = default;
}

當(dāng)然payload參數(shù)也可以自定義策吠,例如:場(chǎng)景為多個(gè)平臺(tái)可以給App推送信息逛裤,這時(shí)就需要一個(gè)Type判斷是那個(gè)平臺(tái)推送的消息,分別顯示等等猴抹。
然后在AppDelegate.m文件中實(shí)現(xiàn)如下方法:

      - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
          //實(shí)現(xiàn)處理推送消息的邏輯代碼
   }

推送喚醒調(diào)用代理方法分析

  • App運(yùn)行于前臺(tái)(Active)
    以下分析基于推送喚醒設(shè)置成功基礎(chǔ)上带族。
    當(dāng)App運(yùn)行在前臺(tái),接收到推送信息時(shí)蟀给,會(huì)調(diào)用:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
          //實(shí)現(xiàn)處理推送消息的邏輯代碼;
   }

如果沒有實(shí)現(xiàn)上述方法炉菲,則會(huì)調(diào)用:

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
          //實(shí)現(xiàn)處理推送消息的邏輯代碼;
  }

但是在實(shí)際測(cè)試過程中,即使后端未輸出content-available = 1;結(jié)果同上坤溃,實(shí)現(xiàn)- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;(后續(xù)統(tǒng)一叫推送喚醒回調(diào)方法)方法也會(huì)調(diào)用拍霜。此問題有待后續(xù)追蹤,如有了解的煩請(qǐng)告知薪介!再此謝過祠饺!

  • App運(yùn)行于后臺(tái)(Background)
    當(dāng)App運(yùn)行于后臺(tái),同時(shí)接收到推送消息時(shí)汁政,推送喚醒功能就是在此時(shí)大顯神威滴O(∩_∩)O~道偷!會(huì)直接調(diào)用:
 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
          //實(shí)現(xiàn)處理推送消息的邏輯代碼;
  }

經(jīng)過測(cè)試,如果未實(shí)現(xiàn)上述方法记劈,則會(huì)在接收到推送的時(shí)候直接調(diào)用:

  - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
          //實(shí)現(xiàn)處理推送消息的邏輯代碼;
  }

當(dāng)App運(yùn)行于后臺(tái)的時(shí)候分為兩種情況:

  • 點(diǎn)擊通知欄進(jìn)入App:
    測(cè)試結(jié)果為:點(diǎn)擊通知欄進(jìn)入App勺鸦,調(diào)用方法同上,也就是當(dāng)App運(yùn)行在后臺(tái)時(shí)目木,接收到推送消息時(shí)换途,直接調(diào)用回調(diào)方法,點(diǎn)擊通知欄進(jìn)入App時(shí)再次調(diào)用刽射,相當(dāng)于調(diào)用了2次回調(diào)方法军拟!想要實(shí)現(xiàn)的同學(xué),需要判斷一下誓禁,是否需要重復(fù)調(diào)用懈息!
  • 點(diǎn)擊App圖標(biāo)進(jìn)入App:
    點(diǎn)擊App圖標(biāo)進(jìn)入App,無任何動(dòng)作摹恰,不調(diào)用任何推送相關(guān)回調(diào)方法辫继,但是在接收到推送消息的時(shí)候已經(jīng)直接調(diào)用了回調(diào)方法怒见,此過程只調(diào)用了1次回調(diào)方法罷了

經(jīng)過測(cè)試,后端未輸出content-available = 1;不會(huì)在App運(yùn)行于后臺(tái)時(shí)直接調(diào)用回調(diào)方法姑宽,但是在點(diǎn)擊通知欄進(jìn)入App時(shí)遣耍,如果實(shí)現(xiàn)了推送喚醒回調(diào)方法,則會(huì)調(diào)用推送喚醒回調(diào)方法低千,未實(shí)現(xiàn),則會(huì)調(diào)用推送回調(diào)方法馏颂。

  • App未運(yùn)行
    當(dāng)App未運(yùn)行時(shí)示血,即使推送喚醒也是無能為力了,因?yàn)橥扑蛦拘阎皇窃贏pp運(yùn)行在后臺(tái)的時(shí)候才有效果救拉。
  • 點(diǎn)擊通知欄進(jìn)入App:
    如果實(shí)現(xiàn)了推送喚醒回調(diào)方法則調(diào)用难审,未實(shí)現(xiàn)則在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions;方法中利用字典鍵值對(duì)判斷亿絮,文章開始介紹過告喊,這就不再贅述了。
    注意:不會(huì)調(diào)用推送回調(diào)方法派昧!
    實(shí)際測(cè)試黔姜,即使后端未輸出content-available = 1;調(diào)用結(jié)果同上
  • 點(diǎn)擊App圖標(biāo)進(jìn)入App:
    點(diǎn)擊App圖標(biāo)進(jìn)入App,無任何動(dòng)作蒂萎,不調(diào)用任何推送相關(guān)回調(diào)方法秆吵。即使調(diào)用- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions;方法五慈,但是此時(shí)launchOptions字典中相應(yīng)的鍵值對(duì)值為空纳寂,所以無法處理相應(yīng)需求

到此泻拦,遠(yuǎn)程推送的所有回調(diào)方法的調(diào)用場(chǎng)景全部羅列完成毙芜,若有遺漏、錯(cuò)誤争拐,非常歡迎指出腋粥,煩請(qǐng)動(dòng)動(dòng)您的手指,反饋一下架曹,文章中我提到的未能明確的問題灯抛,如有了解的煩請(qǐng)告知,再次拜謝音瓷!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末对嚼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绳慎,更是在濱河造成了極大的恐慌纵竖,老刑警劉巖漠烧,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異靡砌,居然都是意外死亡已脓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門通殃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來度液,“玉大人,你說我怎么就攤上這事画舌《榈#” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵曲聂,是天一觀的道長(zhǎng)霹购。 經(jīng)常有香客問我,道長(zhǎng)朋腋,這世上最難降的妖魔是什么齐疙? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旭咽,結(jié)果婚禮上贞奋,老公的妹妹穿的比我還像新娘。我一直安慰自己穷绵,他們只是感情好忆矛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著请垛,像睡著了一般催训。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宗收,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天漫拭,我揣著相機(jī)與錄音,去河邊找鬼混稽。 笑死采驻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的匈勋。 我是一名探鬼主播礼旅,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼洽洁!你這毒婦竟也來了痘系?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饿自,失蹤者是張志新(化名)和其女友劉穎汰翠,沒想到半個(gè)月后龄坪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡复唤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年健田,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佛纫。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妓局,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呈宇,到底是詐尸還是另有隱情好爬,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布攒盈,位于F島的核電站抵拘,受9級(jí)特大地震影響哎榴,放射性物質(zhì)發(fā)生泄漏型豁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一尚蝌、第九天 我趴在偏房一處隱蔽的房頂上張望迎变。 院中可真熱鬧,春花似錦飘言、人聲如沸衣形。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谆吴。三九已至,卻和暖如春苛预,著一層夾襖步出監(jiān)牢的瞬間句狼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工热某, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腻菇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓昔馋,卻偏偏與公主長(zhǎng)得像筹吐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秘遏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 極光推送: 1.JPush當(dāng)前版本是1.8.2丘薛,其SDK的開發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,719評(píng)論 10 16
  • 寫作原因:網(wǎng)上看了很多推送文章都沒有完美的解答我的疑惑邦危;主要有以下兩點(diǎn)榔袋,1:推送來了我點(diǎn)擊應(yīng)用圖標(biāo)進(jìn)入應(yīng)用怎么取到...
    Thebloodelves閱讀 4,508評(píng)論 26 71
  • 許多集成的步驟個(gè)推官網(wǎng)都有了周拐,這里只寫關(guān)于推送的遠(yuǎn)程推送和本地通知的步驟和代碼。APP在后臺(tái)時(shí):走蘋果的APNS通...
    AllureJM閱讀 2,717評(píng)論 1 9
  • 推送通知 注意:這里說的推送通知跟NSNotification有所區(qū)別 NSNotification是抽象的凰兑,不可...
    iOS開發(fā)攻城獅閱讀 4,222評(píng)論 1 13
  • 前言 本文是一篇轉(zhuǎn)載文章妥粟,在這一篇實(shí)用的文章里,你可以按照上面的步驟實(shí)現(xiàn)不借助第三方和服務(wù)器端吏够,自己給自己的設(shè)備發(fā)...
    進(jìn)無盡閱讀 1,668評(píng)論 6 6