iOS 10 推送通知

蘋果的推送通知從iOS3開始出現(xiàn), 每一年都會更新一些新的用法, 譬如:

  • iOS 7 出現(xiàn)的Silent remote notifications(遠程靜默推送)
  • iOS 8 出現(xiàn)的Category(分類, 也可稱之為快捷回復(fù))
  • iOS 9 出現(xiàn)的Text Input action(文本框快捷回復(fù)).

隨著iOS10的到來 , 蘋果對遠程通知和本地通知進行了大范圍的更新.
iOS10推出了全新的UserNotifications框架(iOS10之前從屬于UIKit框架).

新的推送通知框架, 整合了本地推送和遠程推送的點擊處理方法, 使得以前專門處理推送點擊的方法只能處理靜默推送了.

遠程推送的實現(xiàn)原理:



1 打開App時: 發(fā)送UDID和BundleID給APNs加密后返回deviceToken
2 獲取Token后啦辐,App調(diào)用接口,將用戶身份信息和deviceToken發(fā)給服務(wù)器蜈项,服務(wù)器記錄
3 當推送消息時, 服務(wù)器按照用戶身份信息找到存儲的deviceToken紧卒,將消息和deviceToken發(fā)送給APNs
4 蘋果的APNs通過deviceToken, 找到指定設(shè)備的指定程序, 并將消息推送給用戶

實現(xiàn)遠程推送功能的前提:



1 真機
2 調(diào)試階段的證書

  • iOS_development.cer 用于真機調(diào)試的證書
  • aps_development.cer 用于真機推送調(diào)試能的證書
  • xxx.mobileprovision 描述文件,記錄了能夠調(diào)試的手機轴总、電腦和程序

3 發(fā)布階段的證書

  • iOS_distribution.cer 用于發(fā)布app的證書
  • aps.cer 用于發(fā)布時,讓app有推送功能的證書
  • xxx.mobileprovision 描述文件怀樟,記錄了能夠發(fā)布app的電腦

iOS10 全新遠程通知Demo:


一. 注冊遠程推送并獲取DeviceToken

1.創(chuàng)建iOS的項目盆佣,并輸入項目名字
2.在AppDelegate中導(dǎo)入頭文件:

#import <UserNotifications/UserNotifications.h>

3.在application:didFinishLaunchingWithOptions方法中, 注冊遠程通知

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

    //請求通知權(quán)限, 本地和遠程共用
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

    [center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@"請求成功");
        } else {
            NSLog(@"請求失敗");
        }
    }];

    //注冊遠程通知
    [[UIApplication sharedApplication] registerForRemoteNotifications];

    //設(shè)置通知的代理
    center.delegate = self;

    return YES;
}

4.在接收遠程推送的DeviceToken方法中, 獲取Token

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    //將來需要將此Token上傳給后臺服務(wù)器
    NSLog(@"token:%@", deviceToken);
}

二. iOS10遠程推送通知的處理方法



當點擊了推送后, 如果你希望進行處理. 那么在iOS10中, 還需要設(shè)置UNUserNotificationCenter的delegate, 并遵守UNUserNotificationCenterDelegate協(xié)議.

以及實現(xiàn)下面實現(xiàn)3個方法, 用于處理點擊通知時的不同情況的處理

* userNotificationCenter:willPresentNotification:withCompletionHandler: 前臺運行

* userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: 后臺運行時點擊橫幅投蝉、消息欄消息

* application:didReceiveRemoteNotification:fetchCompletionHandler: 靜默推送征堪、App殺死后橫幅和消息欄消息點擊喚起App

//設(shè)置通知的代理
center.delegate = self;

1.前臺運行 會調(diào)用的方法
前臺運行: 指的是程序正在運行中, 用戶能看見程序的界面.
iOS10會出現(xiàn)通知橫幅, 而在以前的框架中, 前臺運行時, 不會出現(xiàn)通知的橫幅.

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    NSDictionary *userInfo = notification.request.content.userInfo;

    //前臺運行推送 顯示紅色Label
    [self showLabelWithUserInfo:userInfo color:[UIColor redColor]];

    //可以設(shè)置當收到通知后, 有哪些效果呈現(xiàn)(聲音/提醒/數(shù)字角標)
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}

2.后臺運行點擊消息會調(diào)用的方法
后臺運行: 指的是程序已經(jīng)打開, 用戶看不見程序的界面, 如鎖屏和按Home鍵.
程序退出: 指的是程序沒有運行, 或者通過雙擊Home鍵,關(guān)閉了程序.

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler
{
    NSDictionary *userInfo = response.notification.request.content.userInfo;

    //后臺顯示綠色Label
    [self showLabelWithUserInfo:userInfo color:[UIColor greenColor]];

    completionHandler();
}

3.靜默推送通知 會調(diào)用的方法
靜默推送: iOS7以后出現(xiàn), 不會出現(xiàn)提醒及聲音.
要求:

  • 推送的payload中不能包含alert及sound字段
  • 需要添加content-available字段, 并設(shè)置值為1
  • 例如: {"aps":{"content-available":"1"},"PageKey”":"2"}
//如果是以前的舊框架, 此方法 前臺/后臺/退出/靜默推送都可以處理
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    //靜默推送 顯示藍色Label
    [self showLabelWithUserInfo:userInfo color:[UIColor blueColor]];

    completionHandler(UIBackgroundFetchResultNewData);
}

4.處理通知的公用方法
開發(fā)中, 點擊通知的邏輯應(yīng)當看自己程序的需求.
這里為了方便演示, 簡單的將通知的值, 通過UILabel顯示在主界面上

- (void)showLabelWithUserInfo:(NSDictionary *)userInfo color:(UIColor *)color
{
    UILabel *label = [UILabel new];
    label.backgroundColor = color;
    label.frame = CGRectMake(0, 250, [UIScreen mainScreen].bounds.size.width, 300);
    label.text = userInfo.description;
    label.numberOfLines = 0;
    [[UIApplication sharedApplication].keyWindow addSubview:label];
}

三. 測試遠程推送

PushMeBaby是一個簡單的模擬服務(wù)器的Mac小程序, 可以將內(nèi)容提交給蘋果的APNs服務(wù)器.
為了測試遠程通知, 我們需要安裝此程序.
請前往www.github.com, 搜索并下載PushMeBaby

使用時:

  1. 編譯該項目, 如果報錯, 則注釋報錯的代碼, 不影響實際使用.
  2. 進入蘋果開發(fā)者網(wǎng)站, 獲取真機調(diào)試用的遠程推送證書, 導(dǎo)入到項目中
  3. 將之前獲取到的DeviceToken, 及測試的文字, 填入該項目中的AppDelegate中的init方法中.
  4. 運行此項目, 會出現(xiàn)一個Mac小程序, 點擊Push即可發(fā)送遠程通知.
- (id)init {
    self = [super init];
    if(self != nil) {
        self.deviceToken = @"de20184c ef0461d5 12c76422 f5b78240 5f657e18 ebf91c9f 01d5560c e2913102";
        self.payload = @"{\"aps\":{\"alert\":{\"title\":\"傳智播客\",\"subtitle\":\"黑馬程序員\",\"body\":\"iOS10遠程&本地推送教程\"},\"badge\":1,\"sound\":\"default\"},\"PageKey\":\"1\"}";
        self.certificate = [[NSBundle mainBundle] pathForResource:@"aps_development" ofType:@"cer"];
    }
    return self;
}

四.補充

因為推送的回調(diào)Api方法過多, 初次接觸可能會有些頭大,雖然從iOS 10起,蘋果對于推送的授權(quán)(本地+遠程)方式有所調(diào)整, 而且采用了使用代理的方式. 而我們也可以采取的實現(xiàn)方式是:

1. 通過requestAuthorizationWithOptions:授權(quán)
2. 不設(shè)置UNUserNotificationCenter 的 delegate 
3. 這樣還會走之前iOS 9的回調(diào)方法

五. 回調(diào)API

  • application: didReceiveRemoteNotification: fetchCompletionHandler:前臺收到推送消息時,不會有彈框提醒
  • userNotificationCenter: willPresentNotification: withCompletionHandler:可以通過設(shè)置回調(diào)參數(shù),根據(jù)回調(diào)參數(shù)內(nèi)是否傳入UNNotificationPresentationOptionAlert,如果有,則在前臺收到推送時,也會有彈框提醒,在系統(tǒng)通知欄內(nèi)可見推送消息,如果不傳入,則不會有彈框提醒,系統(tǒng)通知欄不可見
    completionHandler( UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound );

對于收到推送后, 通知消息的獲取與進入App的方式有關(guān):

    1. App未運行時:
      1.1 點擊通知消息進入, 會執(zhí)行didFinishLaunchWithOptions:方法,通過options獲取通知消息
      1.2 點擊應(yīng)用圖標進入,會執(zhí)行didFinishLaunchWithOptions方法,但options中不包含notification信息
  • 2.App后臺運行:
    2.1 點擊通知消息進入,會執(zhí)行didReceiveRemoteNotification:方法(不同iOS版本的后臺方法),從而獲取推送消息
    2.2 點擊應(yīng)用圖標進入,會執(zhí)行didReceiveRemoteNotification方法不會被調(diào)用,無法獲取到推送消息

  • 對于1.2和2.2場景, 可以通過后臺協(xié)助, 每次點擊應(yīng)用圖標進入后,向后臺請求是否有新的未讀推送,通過請求的方式獲取推送信息.

  • 對于1.1&1.2場景, 如果遠程通知到達時應(yīng)用程序未運行,則application: didReceiveRemoteNotification: fetchCompletionHandler:該方法將啟動應(yīng)用程序并在啟動選項字典中提供適當?shù)男畔ⅰ?/p>

if the app is not running when a remote notification arrives, 
the method launches the app and provides the appropriate information in the launch options dictionary. 
The app does not call this method to handle that remote notification. 
Instead, your implementation of the 
application:willFinishLaunchingWithOptions: 
or 
application:didFinishLaunchingWithOptions: 
method needs to get the remote notification payload data and respond appropriately.
關(guān)于角標:
App當前角標 收到推送 變化
角標為0 推送badge > 0 角標 = badge
角標為0 推送badge = 0 不顯示角標
角標不為0 推送badge > 0 角標 = badge (最后一條推送中的badge)
角標不為0 推送badge = 0 角標 = 0 , 同時在通知欄清空之前的推送記錄
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剧包,隨后出現(xiàn)的幾起案子往果,更是在濱河造成了極大的恐慌,老刑警劉巖堕油,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掉缺,死亡現(xiàn)場離奇詭異戈擒,居然都是意外死亡,警方通過查閱死者的電腦和手機赘来,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗦篱,“玉大人灸促,你說我怎么就攤上這事≡≡裕” “怎么了典鸡?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵萝玷,是天一觀的道長昆婿。 經(jīng)常有香客問我蜓斧,道長,這世上最難降的妖魔是什么看疙? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任能庆,我火速辦了婚禮帮碰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丰涉。我一直安慰自己斯碌,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布投慈。 她就那樣靜靜地躺著冠骄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抱既。 梳的紋絲不亂的頭發(fā)上扁誓,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天蝗敢,我揣著相機與錄音,去河邊找鬼锁右。 笑死,一個胖子當著我的面吹牛贱纠,可吹牛的內(nèi)容都是我干的响蕴。 我是一名探鬼主播妹孙,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼惫企,長吁一口氣:“原來是場噩夢啊……” “哼罐孝!你這毒婦竟也來了莲兢?” 一聲冷哼從身側(cè)響起续膳,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谒兄,沒想到半個月后社付,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸥咖,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了熙兔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片住涉。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钠绍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情媳握,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布娩脾,位于F島的核電站打毛,受9級特大地震影響幻枉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胰挑,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一椿肩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蘸朋,春花似錦扣唱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽局义。三九已至,卻和暖如春檩帐,著一層夾襖步出監(jiān)牢的瞬間另萤,已是汗流浹背诅挑。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工泛源, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留达箍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓兜畸,卻偏偏與公主長得像碘梢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肛鹏,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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