iOS推送通知原理

一兵琳、推送通知的基本原理:

蘋果的推送服務(wù)通知是由自己專門的推送服務(wù)器APNs (Apple Push Notification service)來完成的运翼,其過程是 APNs 接收到我們自己的應(yīng)用服務(wù)器發(fā)出的被推送的消息滔岳,將這條消息推送到指定的 iOS 的設(shè)備上,然后再由 iOS設(shè)備通知到我們的應(yīng)用程序,我們將會以通知或者聲音的形式收到推送回來的消息。 iOS 遠(yuǎn)程推送的前提是归苍,裝有我們應(yīng)用程序的 iOS 設(shè)備用狱,需要向 APNs 服務(wù)器注冊,注冊成功后拼弃,APNs 服務(wù)器將會給我們返回一個 devicetoken夏伊,我們獲取到這個 token 后會將這個 token 發(fā)送給我們自己的應(yīng)用服務(wù)器。當(dāng)我們需要推送消息時吻氧,我們的應(yīng)用服務(wù)器將消息按照指定的格式進(jìn)行打包溺忧,然后結(jié)合 iOS 設(shè)備的 devicetoken 一起發(fā)給 APNs 服務(wù)器。我們的應(yīng)用會和 APNs 服務(wù)器維持一個基于 TCP 的長連接盯孙,APNs 服務(wù)器將新消息推送到iOS 設(shè)備上砸狞,然后在設(shè)備屏幕上顯示出推送的消息。

設(shè)備注冊APNs的流程圖:


推送流程圖

上圖完成了如下步驟:

1.Device(設(shè)備)連接APNs服務(wù)器并攜帶設(shè)備序列號(UUID)

2.連接成功镀梭,APNs經(jīng)過打包和處理產(chǎn)生devicetoken并返回給注冊的Device(設(shè)備)

3.Device(設(shè)備)攜帶獲取的devicetoken發(fā)送到我們自己的應(yīng)用服務(wù)器

4.完成需要被推送的Device(設(shè)備)在APNs服務(wù)器和我們自己的應(yīng)用服務(wù)器的注冊

推送過程圖:


Push 過程

1.首先,我們的設(shè)備安裝了具有推送功能的應(yīng)用(應(yīng)用程序要用代碼注冊消息推動)踱启,我們的 iOS設(shè)備在有網(wǎng)絡(luò)的情況下會連接APNs推送服務(wù)器报账,連接過程中,APNS 服務(wù)器會驗證devicetoken埠偿,連接成功后維持一個基于TCP 的長連接透罢;

2.Provider(我們自己的應(yīng)用服務(wù)器)收到需要被推送的消息并結(jié)合被推送的 iOS設(shè)備的devicetoken一起打包發(fā)送給APNS服務(wù)器;

3.APNS服務(wù)器將推送信息推送給指定devicetoken的iOS設(shè)備冠蒋;

4.iOS設(shè)備收到推送消息后通知我們的應(yīng)用程序并顯示和提示用戶(聲音羽圃、彈出框)

信息包結(jié)構(gòu)圖:


信息結(jié)構(gòu)圖

上圖顯示的這個消息體就是我們的應(yīng)用服務(wù)器(Provider)發(fā)送給APNs服務(wù)器的消息結(jié)構(gòu),APNs驗證這個結(jié)構(gòu)正確并提取其中的信息后抖剿,再將消息推送到指定的iOS設(shè)備朽寞。這個結(jié)構(gòu)體包括五個部分,第一個部分是命令標(biāo)示符斩郎,第二個部分是我們的devicetoken的長度脑融,第三部分是我們的devicetoken字符串,第四部分是推送消 息體(Payload)的長度缩宜,最后一部分也就是真正的消息內(nèi)容了肘迎,里面包含了推送消息的基本信息,比如消息內(nèi)容锻煌,應(yīng)用Icon右上角顯示多少數(shù)字以及推送消息到達(dá)時所播放的聲音等

Payload(消息體)的結(jié)構(gòu):

{?

?“aps”:{?

?“alert”:“send message”,?

?“badge”:1,

?“sound”:“default” }

}

這其實(shí)就是個JSON結(jié)構(gòu)體妓布,alert標(biāo)簽的內(nèi)容就是會顯示在用戶手機(jī)上的推送信息,badge顯示的數(shù)量(注意是整型)是會在應(yīng)用Icon右上角顯示的數(shù)量宋梧,提示有多少條未讀消息等匣沼,sound就是當(dāng)推送信息送達(dá)是手機(jī)播放的聲音,傳defalut就標(biāo)明使用系統(tǒng)默認(rèn)聲音乃秀。

二肛著、配置證書

1.登錄Apple的Developer Member Center圆兵、

打開Safari瀏覽器,地址欄輸入并打開此網(wǎng)址:https://developer.apple.com/membercenter/index.action,然后用開發(fā)者賬號登錄.

選擇點(diǎn)擊Certificates, Identifiers & Profiles., 打開后在左側(cè)列表中選擇Certificates大類下面的All子類,出現(xiàn)如下界面:


Apple dev

2.選擇證書的類型,Sandbox或者Productuon

根據(jù)你的需求選擇Apple Push Notification service SSL (Sandbox) 或者 Apple Push Notification service SSL (Sandbox & Production)類型的證書.

然后點(diǎn)擊繼續(xù).

這里要注意一點(diǎn),選擇證書的正確類型非常重要:

一個用Development Provisioning Profile簽名的App生成的 Device Token只能和Sandbox APNS Server結(jié)合使用(開發(fā)環(huán)境測試用).

一個用AdHoc Provisioning Profile或者AppStore Provisioning Profile簽名的App生成的Device Token只能和Production APNS Server結(jié)合使用(生產(chǎn)環(huán)境發(fā)布使用).

提示:

有些用戶已經(jīng)報告過關(guān)于使用二合一的推送證書(Apple Push Notification service SSL (Sandbox & Production),新出的 )在調(diào)試測試環(huán)境進(jìn)行推送時會出問題.


生成推送證書

3.選擇你對應(yīng)的App ID

前提你要先已經(jīng)創(chuàng)建了你App使用的App ID,并在App ID下拉選項中選擇你對應(yīng)的App ID.

點(diǎn)擊繼續(xù)按鈕繼續(xù).


選擇對應(yīng)AppleID

4.查看創(chuàng)建證書簽名請求相關(guān)步驟信息

查看一下如何創(chuàng)建一個CSR文件的信息.

點(diǎn)擊繼續(xù).


apns-04

該頁面有關(guān)于如何一步一步創(chuàng)建CSR文件的詳細(xì)信息,下面我們就跟著一步一步來創(chuàng)建CSR文件.

5.打開鑰匙串訪問程序

打開Launchpad中的其他組的Keychain Access App,就是鑰匙串訪問程序.


apns-05

6.創(chuàng)建證書簽名請求文件

點(diǎn)擊鑰匙串訪問程序的菜單欄

選擇證書助理子菜單

選擇從證書頒發(fā)機(jī)構(gòu)請求證書...子子菜單


apns-06

7.填寫證書簽名請求文件詳細(xì)信息

輸入email地址,為了安全和保險起見,最好填寫和你Apple開發(fā)者賬號對應(yīng)的email地址.

接著輸入常用名稱.

最好選擇存儲到磁盤選項.

最后點(diǎn)擊繼續(xù).

apns-07

8.保存證書簽名請求文件到磁盤

選擇一個存儲位置以及輸入一個你喜歡的文件名稱

點(diǎn)擊保存


apns-08

9.完成證書簽名請求文件制作

點(diǎn)擊完成


apns-09

10.上傳正確簽名請求文件

繼續(xù)回到第四步后的瀏覽器界面

選擇 Choose File...來上傳

在彈出的文件打開對話框中定位到剛剛存儲的證書簽名請求文件所在目錄,并選擇打開該CSR文件.

點(diǎn)擊繼續(xù)


apns-10

11.下載證書文件

上一步繼續(xù)之后,你的證書應(yīng)該就已經(jīng)生成好了.

點(diǎn)擊下載按鈕來下載證書.

打開下載的證書文件,一般會自動用鑰匙串訪問程序打開的.


apns-11

三、代碼配置

打開AppDelegate.m 文件,在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中添加下面代碼,注冊消息推送

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

? ? // Override point for customization after application launch.

????if (IOSVersion >= 10.0) {

? ? ? ????? UNUserNotificationCenter *center = [UNUserNotificationCenter ????currentNotificationCenter];

? ? ? ? // 必須寫代理枢贿,不然無法監(jiān)聽通知的接收與點(diǎn)擊

? ? ? ? center.delegate=self;

? ? ? ? [centerrequestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {

? ? ? ? ? ? if(granted) {

? ? ? ? ? ? ? ? // 點(diǎn)擊允許

? ? ? ? ? ? ? ? NSLog(@"注冊成功");

? ? ? ? ? ? ? ? [centergetNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

? ? ? ? ? ? ? ? ? ? NSLog(@"%@", settings);

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? // 點(diǎn)擊不允許

? ? ? ? ? ? ? ? NSLog(@"注冊失敗");

? ? ? ? ? ? }

? ? ? ? }];

? ? }else{

? ? ? ???[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

? ? }

? ? [[UIApplication sharedApplication] registerForRemoteNotifications];

}


#pragma mark Push methodsIniOS9

- (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings

{

? ? [application registerForRemoteNotifications];

}

/** APP已經(jīng)接收到“遠(yuǎn)程”通知(推送) - 透傳推送消息? */

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResultresult))completionHandler {

? ? NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);

? ? completionHandler(UIBackgroundFetchResultNewData);

}

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userinfo

{

NSLog(@"userInfo == %@",userInfo);

}

#pragma mark Push methodsIniOS10

- (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void(^)(UNNotificationPresentationOptionsoptions))completionHandler{

? ? completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);

}

//App通知的點(diǎn)擊事件

- (void)userNotificationCenter:(UNUserNotificationCenter*)center didReceiveNotificationResponse:(UNNotificationResponse*)response withCompletionHandler:(void(^)(void))completionHandler{

? ? //收到推送的請求

? ? UNNotificationRequest*request = response.notification.request;


? ? //收到推送的內(nèi)容

? ? UNNotificationContent*content = request.content;


? ? //收到用戶的基本信息

? ? NSDictionary*userInfo = content.userInfo;

? ? completionHandler();// 系統(tǒng)要求執(zhí)行這個方法

}

下面方法是返回 ANPs 蘋果推送服務(wù)器生成的唯一標(biāo)識

/** 接收服務(wù)器傳回的設(shè)備唯一標(biāo)識 token */

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken

{

? ? NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

? ?? // 第一次運(yùn)行獲取到DeviceToken時間會比較長殉农!

? ? // 將deviceToken轉(zhuǎn)換成字符串,以便后續(xù)使用

? ? NSString *token = [deviceToken description];

? ? NSLog(@"description %@", token);

}

/** 注冊推送服務(wù)失敗 */

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error

{

NSLog(@"注冊失敗 %@",error);

}

四局荚、測試

測試推送鏈路是否通暢的工具有很多超凳,大家自行選擇,比如個推等等耀态。轮傍。。需要注意的是推送是有丟失率的首装,不是100%每推必達(dá)4匆埂!仙逻!

Demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驰吓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子系奉,更是在濱河造成了極大的恐慌檬贰,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缺亮,死亡現(xiàn)場離奇詭異翁涤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萌踱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門葵礼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虫蝶,你說我怎么就攤上這事章咧。” “怎么了能真?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵赁严,是天一觀的道長。 經(jīng)常有香客問我粉铐,道長疼约,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任蝙泼,我火速辦了婚禮程剥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己织鲸,他們只是感情好舔腾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搂擦,像睡著了一般稳诚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瀑踢,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天扳还,我揣著相機(jī)與錄音,去河邊找鬼橱夭。 笑死氨距,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棘劣。 我是一名探鬼主播俏让,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼茬暇!你這毒婦竟也來了舆驶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤而钞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拘荡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臼节,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年珊皿,在試婚紗的時候發(fā)現(xiàn)自己被綠了网缝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟋定,死狀恐怖粉臊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驶兜,我是刑警寧澤扼仲,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站抄淑,受9級特大地震影響屠凶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肆资,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一矗愧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧郑原,春花似錦唉韭、人聲如沸夜涕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽女器。三九已至,卻和暖如春春塌,著一層夾襖步出監(jiān)牢的瞬間晓避,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工只壳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留俏拱,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓吼句,卻偏偏與公主長得像锅必,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惕艳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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

  • 極光推送: 1.JPush當(dāng)前版本是1.8.2搞隐,其SDK的開發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋果官方的步伐,SD...
    Isspace閱讀 6,704評論 10 16
  • 推送通知远搪,是現(xiàn)在的應(yīng)用必不可少的功能劣纲。那么在 iOS 中,我們是如何實(shí)現(xiàn)遠(yuǎn)程推送的呢谁鳍?iOS 的遠(yuǎn)程推送原理又是什...
    皮皮瑞閱讀 1,297評論 0 3
  • 概述 在多數(shù)移動應(yīng)用中任何時候都只能有一個應(yīng)用程序處于活躍狀態(tài)癞季,如果其他應(yīng)用此刻發(fā)生了一些用戶感興趣的那么通過通知...
    莫離_焱閱讀 6,498評論 1 8
  • 推送通知 注意:這里說的推送通知跟NSNotification有所區(qū)別 NSNotification是抽象的,不可...
    iOS開發(fā)攻城獅閱讀 4,211評論 1 13
  • 推送通知注意:這里說的推送通知跟NSNotification有所區(qū)別NSNotification是抽象的倘潜,不可見的...
    醉葉惜秋閱讀 1,509評論 0 3