iOS 10推送使用總結(jié)

概述
現(xiàn)在市面上大多數(shù)app白粉,都有根據(jù)某種條件传泊,服務(wù)端主動向用戶推送消息的需求。面對這個需求鸭巴,首先想到的是長鏈接眷细,如果服務(wù)端集成了HTTP/2的話,還可以用Server Push鹃祖。安卓在處理類似業(yè)務(wù)時就是這么干的溪椎,美其名曰透傳消息。但是我們期望的是恬口,無論是app退后臺還是被結(jié)束進(jìn)程校读,都可以正常收到消息。這就需要用到系統(tǒng)集的推送祖能。而在iOS平臺或者說蘋果全系統(tǒng)平臺歉秫,就是偉大的Apple Push Notification service 簡稱APNs。

開啟app的推送通知能力

在工程的Capability標(biāo)簽下养铸,打開 Push Notifications 開關(guān)

avatar

然后它會在你的AppId下增加下圖的配置,你需要根據(jù)要求配置相關(guān)的推送證書(這塊就不說了)

image

以上就是配置推送環(huán)境的步驟雁芙,下面就可以寫代碼了

獲取推送權(quán)限

代碼如下,最好在 AppDelegatedidFinishLaunchingWithOptions 這個方法里面且做

if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
         center.delegate = self; // 注意這里 不設(shè)置代理不會走推送的兩個代理方法
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"iOS 10后 - 用戶授權(quán)通知權(quán)限");
            }else {
                NSLog(@"iOS 10后 - 用戶拒絕通知權(quán)限");
            }
        }];
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"%@", settings);
        }];
    }else {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }

注冊完成之后我們還需要執(zhí)行[[UIApplication sharedApplication] registerForRemoteNotifications];獲取推送的DeviceToken
系統(tǒng)就會去獲取揭厚,然后在didRegisterForRemoteNotificationsWithDeviceToken 這個代理方法中返回

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    if (@available(iOS 13.0, *)) {
        NSMutableString *deviceTokenString = [NSMutableString string];
        const char *bytes = deviceToken.bytes;
        NSInteger count = deviceToken.length;
        for (int i = 0; i < count; i++) {
            [deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
        }
        NSLog(@"iOS13 deviceToken:%@", deviceTokenString);
    } else {
        NSString *deviceTokenStr =  [[[[deviceToken description]
                                       stringByReplacingOccurrencesOfString:@"<" withString:@""]
                                      stringByReplacingOccurrencesOfString:@">" withString:@""]
                                     stringByReplacingOccurrencesOfString:@" " withString:@""];
        NSLog(@"iOS13-Pre deviceToken:%@", deviceTokenStr);
    }
    
}

獲取到token后給服務(wù)器却特,執(zhí)行推送指令扶供。
服務(wù)器推送格式:
注意:body和title必須要有一個才行筛圆,不然推送不彈窗。

 {
   "aps" : {
     "alert" : {
       "title" : "Test-Push",
       "body" : "Your message Here"
     },
   }
 }

這個時候我們還不能收到推送椿浓,因為我們還沒實現(xiàn) UNUserNotificationCenter的代理方法
代碼如下

/// 收到推送后太援,會先調(diào)用這個方法闽晦,它可以設(shè)置推送要顯示的方式是啥 常用的配置如代碼所示
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
    NSLog(@"willPresentNotification");
    UNNotificationPresentationOptions options = UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge;
    completionHandler(options);
}
// 上面的代理方法走了之后,會在用戶與你推送的通知進(jìn)行交互時被調(diào)用提岔,包括用戶通過通知打開了你的應(yīng)用仙蛉,或者點(diǎn)擊或者觸發(fā)了某個 action
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
{
    UNNotificationContent *content = response.notification.request.content;
    //NSLog(@"didReceiveNotificationResponse %@", content);
    NSDictionary *responseDict = content.userInfo;
    NSLog(@"didReceiveNotificationResponse %@", responseDict);
    completionHandler();
}

靜默推送

就是實現(xiàn)下面的代理方法

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

這里有個注意點(diǎn):如果你實現(xiàn)了這個方法且運(yùn)行在iOS10以下的設(shè)備的時候,所有的遠(yuǎn)程推送都是走這個方法的碱蒙,iOS10之前的didReceiveRemoteNotification這個代理方法是不會走的荠瘪。除非你沒實現(xiàn)上面的代理方法

當(dāng)我們不請求推送權(quán)限,或者用戶拒絕或者主動關(guān)閉了推送權(quán)限赛惩,推送還是可以正常到達(dá)設(shè)備的哀墓。但是沒有橫幅也沒有聲音,是以靜默形式呈現(xiàn)喷兼。如果跟常規(guī)的推送混合著使用篮绰,場景會復(fù)雜一些。
必須打開后臺模式季惯,并勾選Remote notification吠各,我們之前介紹的那些方法才會被觸發(fā)。
我們在payload中不包含alert勉抓、sound贾漏、badge,無論app推送權(quán)限是否打開琳状,都屬于靜默推送磕瓷。
原則上,后臺模式的推送應(yīng)該是靜默推送念逞。在iOS13以后困食,需要在請求頭中apns-push-type字段設(shè)置為backgroud。而如果不是真正的靜默推送翎承,有被APNs丟棄的危險硕盹。

在服務(wù)推送的時候需要在payload中包含content-available并且值為1 這樣才會走上面的代理方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
這里補(bǔ)充下iOS10以下的設(shè)備如果實現(xiàn)了上面的代理方法,所有推送都會走那里不會走原來的- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo方法

遠(yuǎn)程推送格式為:(大小限制好像是5kb

 {
   "aps" : {
     "alert" : {
       "title" : "Test-Push",
       "body" : "Your message Here"
     },
     "content-available" : 1
   }
 }
image

靜默推送和UNUserNotificationCenter同時使用的情況下

注意:
fetchCompletionHandler 代表下面的代理方法

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

didReceiveNotificationResponse 代表下面的代理方法

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

推送模式如下圖表格所示:

設(shè)置 "content-available" = 1 是否實現(xiàn)代理方法 是否彈窗 是否需要點(diǎn)擊彈窗 執(zhí)行的方法
App前臺 fetchCompletionHandler
didReceiveNotificationResponse
fetchCompletionHandler
fetchCompletionHandler
App后臺 fetchCompletionHandler
didReceiveNotificationResponse
fetchCompletionHandler
fetchCompletionHandler
App殺死 fetchCompletionHandler
didReceiveNotificationResponse
fetchCompletionHandler
fetchCompletionHandler

iOS10以下設(shè)備的推送模式如下
// iOS 9 遠(yuǎn)程推送和后臺推送都走這里 app殺死的情況需要點(diǎn)擊彈窗 后臺模式也會彈窗(需要點(diǎn)擊)前臺不彈窗 直接執(zhí)行 走fetchCompletionHandler方法
// 前臺模式設(shè)置了"content-available" = 1; 與否 前臺不彈窗 直接執(zhí)行
// 后臺模式設(shè)置了"content-available" = 1; 彈窗 直接執(zhí)行 不設(shè)置 彈窗 需要點(diǎn)擊執(zhí)行
// App殺死設(shè)置了"content-available" = 1; 與否 彈窗 都需要點(diǎn)擊執(zhí)行

推送調(diào)試

image.png
  • didReceiveIncomingPushWithPayload這個代理方法中獲取的token 添加到 Easy APNs Provider
  • 選擇推送的證書
  • 點(diǎn)擊開始連接 gateway.sanbox.push.apple.com 對應(yīng)的是開發(fā)證書叨咖, gateway.push.apple.com 對應(yīng)的是生產(chǎn)證書
  • 然后就可以點(diǎn)擊發(fā)送推送即可

軟件不太好找 這里給你們分享下
鏈接: https://pan.baidu.com/s/16INLhg3V6CuVU5pJjDqptQ 提取碼: wc6h 復(fù)制這段內(nèi)容后打開百度網(wǎng)盤手機(jī)App瘩例,操作更方便哦

點(diǎn)個贊再走哦??
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市甸各,隨后出現(xiàn)的幾起案子垛贤,更是在濱河造成了極大的恐慌,老刑警劉巖趣倾,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聘惦,死亡現(xiàn)場離奇詭異,居然都是意外死亡儒恋,警方通過查閱死者的電腦和手機(jī)善绎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門黔漂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人禀酱,你說我怎么就攤上這事炬守。” “怎么了剂跟?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵减途,是天一觀的道長。 經(jīng)常有香客問我曹洽,道長观蜗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任衣洁,我火速辦了婚禮墓捻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坊夫。我一直安慰自己砖第,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布环凿。 她就那樣靜靜地躺著梧兼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪智听。 梳的紋絲不亂的頭發(fā)上羽杰,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音到推,去河邊找鬼考赛。 笑死,一個胖子當(dāng)著我的面吹牛莉测,可吹牛的內(nèi)容都是我干的颜骤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼捣卤,長吁一口氣:“原來是場噩夢啊……” “哼忍抽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起董朝,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鸠项,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后子姜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祟绊,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了久免。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡扭弧,死狀恐怖阎姥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸽捻,我是刑警寧澤呼巴,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站御蒲,受9級特大地震影響衣赶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厚满,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一府瞄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碘箍,春花似錦遵馆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至四濒,卻和暖如春换况,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗蟆。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工戈二, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喳资。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓挽拂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親骨饿。 傳聞我的和親對象是個殘疾皇子亏栈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359