iOS 10 消息推送(UserNotifications)秘籍總結(jié)(二)

背景

上一篇博客iOS 10 消息推送(UserNotifications)秘籍總結(jié)(一)發(fā)布后被 簡書編輯推薦至首頁,這著實(shí)讓我受寵若驚啊缸剪√陕剩可是好事不長溉瓶,后面發(fā)生了讓我傷心欲絕的事,我的女朋友不要我了%>_<%重绷。剛剛放完國慶假期沸停,你們還沉浸在國慶的喜悅中沒回過神來,而我則迷失了前進(jìn)的方向不能自拔论寨,沒有了寄托和疼愛的那個(gè)人了星立!

愛情中最遺憾的事大概就是如此吧
我們曾愛的人到撕心裂肺,但時(shí)時(shí)刻刻都在互相傷害葬凳,誰也不懂退讓绰垂,也不會(huì)給對方寬容,相愛相殺演繹到了極致而分手火焰,因?yàn)槟菚r(shí)我們相愛太早了劲装,渾身帶刺,根本不能給對方想要的生活方式昌简,分道揚(yáng)鑣時(shí)是一種成全占业,更是一種解脫。但是多年的感情放手真的那么容易嗎纯赎?我相信地球是圓的谦疾,再經(jīng)過了多次輾轉(zhuǎn)之后再次重逢,那時(shí)候的我們會(huì)帶著打磨好的自己彼此欣賞犬金,不會(huì)再為了誰洗碗這樣的小事而爭吵念恍,不會(huì)再用言語傷害最愛的人六剥!

我希望有個(gè)如你一般的人。如這山間清晨一般明亮清爽的人峰伙,如奔赴古城道路上陽光一般的人疗疟,溫暖而不炙熱,覆蓋我所有肌膚瞳氓。由起點(diǎn)到夜晚策彤,由山野到書房,一切問題的答案都很簡單匣摘。我希望有個(gè)如你一般的人店诗,貫徹未來,數(shù)遍生命的公路牌恋沃。只要最后是你必搞,就好

孤獨(dú)的loser.jpg

晚點(diǎn)遇見你 余生都是你

有時(shí)候,露出笑臉囊咏,只是不想讓你擔(dān)心或難過恕洲。但其實(shí),我沒有你想象中那么堅(jiān)強(qiáng).jpeg

看完了樓主的一頓矯情一定很同情我梅割,但是我想說上面都是我瞎扯的霜第,程序猿怎么可能有女朋友,怎么可能户辞!下面請跟隨樓主腳步一起裝X泌类。

樓主又開始裝逼了.jpg

把快樂留給你們 ,把悲傷留給自己底燎,you happy jiu ok刃榨!

前言

這篇博客是根據(jù)上一篇博客代碼iOS 10 消息推送(UserNotifications)秘籍總結(jié)(一)繼續(xù)編寫的,后面我會(huì)把Demo地址發(fā)出來供大家學(xué)習(xí)測試双仍!
本篇代碼較多枢希,請做好心理準(zhǔn)備,如果看暈朱沃,本樓概不負(fù)責(zé)苞轿!

Notification Actions

早在iOS8和iOS9下,notification增加了一些新的特性:
iOS 8增加了下拉時(shí)的Action按鈕逗物,像微信一樣搬卒;
iOS 9增加了像信息一樣的可以下拉直接輸入;

iOS 10 中翎卓,可以允許推送添加交互操作 action契邀,這些 action 可以使得 App 在前臺(tái)或后臺(tái)執(zhí)行一些邏輯代碼。如:推出鍵盤進(jìn)行快捷回復(fù)失暴,該功能以往只在 iMessage 中可行蹂安。

在 iOS 10 中椭迎,這叫 category锐帜,是對推送功能的一個(gè)拓展田盈,可以通過 3D-Touch 觸發(fā),如果你的你的手機(jī)不支持3D-Touch也沒關(guān)系缴阎,右滑則會(huì)出現(xiàn)view和clear選項(xiàng)來觸發(fā)允瞧。

1、創(chuàng)建Action

    UNNotificationAction *lookAction = [UNNotificationAction actionWithIdentifier:@"action.join" title:@"接收邀請" options:UNNotificationActionOptionAuthenticationRequired];
    
    UNNotificationAction *joinAction = [UNNotificationAction actionWithIdentifier:@"action.look" title:@"查看邀請" options:UNNotificationActionOptionForeground];
    
    UNNotificationAction *cancelAction = [UNNotificationAction actionWithIdentifier:@"action.cancel" title:@"取消" options:UNNotificationActionOptionDestructive];

    UNTextInputNotificationAction *inputAction = [UNTextInputNotificationAction actionWithIdentifier:@"action.input" title:@"輸入" options:UNNotificationActionOptionForeground textInputButtonTitle:@"發(fā)送" textInputPlaceholder:@"tell me loudly"];

注意點(diǎn):

1. UNNotificationActionOptions是一個(gè)枚舉類型蛮拔,是用來標(biāo)識(shí)Action觸發(fā)的行為方式分別是:
需要解鎖顯示述暂,點(diǎn)擊不會(huì)進(jìn)app。
UNNotificationActionOptionAuthenticationRequired = (1 << 0),
紅色文字建炫。點(diǎn)擊不會(huì)進(jìn)app畦韭。    
UNNotificationActionOptionDestructive = (1 << 1),
黑色文字。點(diǎn)擊會(huì)進(jìn)app肛跌。    
UNNotificationActionOptionForeground = (1 << 2),

2. UNNotificationAction是按鈕action艺配,UNTextInputNotificationAction是輸入框Action

3. 創(chuàng)建 UNTextInputNotificationAction 比 UNNotificationAction 多了兩個(gè)參數(shù)
 buttonTitle 輸入框右邊的按鈕標(biāo)題
 placeholder 輸入框占位符

2、 創(chuàng)建category

 UNNotificationCategory *notificationCategory = [UNNotificationCategory categoryWithIdentifier:@"Dely_locationCategory" actions:@[lookAction, joinAction, cancelAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];

注意點(diǎn):

+ (instancetype)categoryWithIdentifier:(NSString *)identifier actions:(NSArray<UNNotificationAction *> *)actions intentIdentifiers:(NSArray<NSString *> *)intentIdentifiers options:(UNNotificationCategoryOptions)options;

方法中:
identifier 標(biāo)識(shí)符是這個(gè)category的唯一標(biāo)識(shí)衍慎,用來區(qū)分多個(gè)category,
這個(gè)id不管是Local Notification转唉,還是remote Notification,一定要有并且要保持一致 ,切記切記稳捆!下面注意看截圖

actions 是你創(chuàng)建action的操作數(shù)組
intentIdentifiers 意圖標(biāo)識(shí)符 可在 <Intents/INIntentIdentifiers.h> 中查看赠法,主要是針對電話、carplay 等開放的 API
options 通知選項(xiàng) 枚舉類型 也是為了支持 carplay

3乔夯、把category添加到通知中心

 // 將 category 添加到通知中心
 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
 [center setNotificationCategories:[NSSet setWithObject:notificationCategory]];

4砖织、完整Demo例子

  • 本地通知Local Notification
1、創(chuàng)建本地通知.png

其中[NotificationAction addNotificationAction];方法是我單獨(dú)來管理Action的類末荐,這樣Remote Notification就不會(huì)不知道寫哪里了侧纯。其實(shí)添加Action不一定非要寫在這里,因?yàn)槿绻荝emote Notification的push沒地方寫啊鞠评,其實(shí)可以統(tǒng)一寫在Appdelegate方法里茂蚓!

Actions添加位置.png
  • 遠(yuǎn)端推送Remote Notification
    一定要保證里面包含category鍵值對一致
{
  "aps" : {
    "alert" : {
      "title" : "iOS遠(yuǎn)程消息,我是主標(biāo)題剃幌!-title",
      "subtitle" : "iOS遠(yuǎn)程消息聋涨,我是主標(biāo)題!-Subtitle",
      "body" : "Dely,why am i so handsome -body"
    },
    "category" : "Dely_locationCategory",
    "badge" : "2"
  }
}

下面就是創(chuàng)建按鈕Action的完整代碼

+ (void)addNotificationAction{

    //創(chuàng)建按鈕Action
    UNNotificationAction *lookAction = [UNNotificationAction actionWithIdentifier:@"action.join" title:@"接收邀請" options:UNNotificationActionOptionAuthenticationRequired];
    
    UNNotificationAction *joinAction = [UNNotificationAction actionWithIdentifier:@"action.look" title:@"查看邀請" options:UNNotificationActionOptionForeground];
    
    UNNotificationAction *cancelAction = [UNNotificationAction actionWithIdentifier:@"action.cancel" title:@"取消" options:UNNotificationActionOptionDestructive];
    

    // 注冊 category
    // * identifier 標(biāo)識(shí)符
    // * actions 操作數(shù)組
    // * intentIdentifiers 意圖標(biāo)識(shí)符 可在 <Intents/INIntentIdentifiers.h> 中查看负乡,主要是針對電話牍白、carplay 等開放的 API。
    // * options 通知選項(xiàng) 枚舉類型 也是為了支持 carplay
    UNNotificationCategory *notificationCategory = [UNNotificationCategory categoryWithIdentifier:@"Dely_locationCategory" actions:@[lookAction, joinAction, cancelAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    
    // 將 category 添加到通知中心
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center setNotificationCategories:[NSSet setWithObject:notificationCategory]];
}

收到消息如下:

按鈕Action.jpg

下面就是創(chuàng)建輸入Action的完整代碼

+ (void)addNotificationAction2{
    
    // 創(chuàng)建 UNTextInputNotificationAction 比 UNNotificationAction 多了兩個(gè)參數(shù)
    // * buttonTitle 輸入框右邊的按鈕標(biāo)題
    // * placeholder 輸入框占位符
    UNTextInputNotificationAction *inputAction = [UNTextInputNotificationAction actionWithIdentifier:@"action.input" title:@"輸入" options:UNNotificationActionOptionForeground textInputButtonTitle:@"發(fā)送" textInputPlaceholder:@"tell me loudly"];
    // 注冊 category
    UNNotificationCategory *notificationCategory = [UNNotificationCategory categoryWithIdentifier:@"Dely_locationCategory" actions:@[inputAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center setNotificationCategories:[NSSet setWithObject:notificationCategory]];

}

收到消息如下:

輸入Action.jpg

遠(yuǎn)端消息如下:

遠(yuǎn)端按鈕Action.jpg

5抖棘、事件的操作

現(xiàn)在我們能收到消息了茂腥,你以為就結(jié)束了嘛狸涌。錯(cuò)!因?yàn)槲覀円僮鬟@個(gè)消息的最岗,如果只是做到這里就結(jié)束了話帕胆,那我點(diǎn)擊那個(gè)按鈕都不知道,或者我輸入什么文字也不知道般渡,那要這個(gè)功能何用懒豹,那老板會(huì)對你說到財(cái)務(wù)領(lǐng)工資吧,明天別來了驯用!我們所有的學(xué)習(xí)都是為了更好為老板掙錢的不是嘛脸秽!這就是我們程序猿的價(jià)值膀燃印讹堤!需要我們做獲取操作事件,那就繼續(xù)往下看:

我上一篇博客說過所有的push(不管遠(yuǎn)端或者本地)點(diǎn)擊都會(huì)走到下面的代理方法

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;

那我們點(diǎn)擊某一個(gè)按鈕或者輸入什么文字肯定也在這里操作了:

//App通知的點(diǎn)擊事件
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
    
    //點(diǎn)擊或輸入action
    NSString* actionIdentifierStr = response.actionIdentifier;
     //輸入
    if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) {

        NSString* userSayStr = [(UNTextInputNotificationResponse *)response userText];
        NSLog(@"actionid = %@\n  userSayStr = %@",actionIdentifierStr, userSayStr);
        //此處省略一萬行需求代碼粗恢。薇正。片酝。。
    }

     //點(diǎn)擊
    if ([actionIdentifierStr isEqualToString:@"action.join"]) {

        //此處省略一萬行需求代碼
         NSLog(@"actionid = %@\n",actionIdentifierStr);
    }else if ([actionIdentifierStr isEqualToString:@"action.look"]){
        
        //此處省略一萬行需求代碼
        NSLog(@"actionid = %@\n",actionIdentifierStr);

   //下面代碼就不放進(jìn)來了铝穷,具體看Demo
 }

小結(jié):上面介紹了category钠怯,到這里功能才算完整。IOS 10的category其實(shí)是獨(dú)立出來的不要和創(chuàng)建push混為一談曙聂,它只是一個(gè)擴(kuò)展功能晦炊,可加可不加的!

Media Attachments和自定義推送界面

本地推送和遠(yuǎn)程推送同時(shí)都可支持附帶Media Attachments宁脊。不過遠(yuǎn)程通知需要實(shí)現(xiàn)通知服務(wù)擴(kuò)展UNNotificationServiceExtension断国,在service extension里面去下載attachment,但是需要注意榆苞,service extension會(huì)限制下載的時(shí)間(30s)稳衬,并且下載的文件大小也會(huì)同樣被限制。這里畢竟是一個(gè)推送坐漏,而不是把所有的內(nèi)容都推送給用戶薄疚。所以你應(yīng)該去推送一些縮小比例之后的版本。比如圖片赊琳,推送里面附帶縮略圖街夭,當(dāng)用戶打開app之后,再去下載完整的高清圖躏筏。視頻就附帶視頻的關(guān)鍵幀或者開頭的幾秒板丽,當(dāng)用戶打開app之后再去下載完整視頻。

attachment支持圖片趁尼,音頻埃碱,視頻猖辫,附件支持的類型及大小

附件類型和大小.png

系統(tǒng)會(huì)在通知注冊前校驗(yàn)附件,如果附件出問題砚殿,通知注冊失斂性鳌;校驗(yàn)成功后瓮具,附件會(huì)轉(zhuǎn)入attachment data store荧飞;如果附件是在app bundle,則是會(huì)被copy來取代move
media attachments可以利用3d touch進(jìn)行預(yù)覽和操作
attachment data store的位置?利用代碼測試 獲取在磁盤上的圖片文件作為attachment名党,會(huì)發(fā)現(xiàn)注冊完通知后,圖片文件被移除挠轴,在app的沙盒中找不到該文件在哪里传睹; 想要獲取已存在的附件內(nèi)容,文檔中提及可以通過UNUserNotificationCenter中方法岸晦,但目前文檔中這2個(gè)方法還是灰的,見蘋果開發(fā)者文檔

Apple developer.png
//就是這兩個(gè)方法
getDataForAttachment:withCompletionHandler:
getReadFileHandleForAttachment:withCompletionHandler:

1欧啤、準(zhǔn)備工作
附件限定https協(xié)議,所以我們現(xiàn)在找一個(gè)支持https的圖床用來測試启上,我之前能測試的圖床現(xiàn)在不能用了邢隧。你們可以自行g(shù)oogole,這是我之前上傳的圖片鏈接:https://p1.bpimg.com/524586/475bc82ff016054ds.jpg
具體附件格式可以查看蘋果開發(fā)文檔

2冈在、添加新的Targe--> Notification Service
先在Xcode 打開你的工程倒慧,F(xiàn)ile-->New-->Targe然后添加這個(gè)Notification Service:

Notification Service.png

這樣在你工程里能看到下面目錄:

Notification Service.png

然后會(huì)自動(dòng)創(chuàng)建一個(gè) UNNotificationServiceExtension 的子類 NotificationService,通過完善這個(gè)子類包券,來實(shí)現(xiàn)你的需求纫谅。

點(diǎn)開 NotificationService.m 會(huì)看到 2 個(gè)方法:

// Call contentHandler with the modified notification content to deliver. If the handler is not called before the service's time expires then the unmodified notification will be delivered.
// You are expected to override this method to implement push notification modification.
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler;

// Will be called just before this extension is terminated by the system. You may choose whether to override this method.
- (void)serviceExtensionTimeWillExpire;

didReceiveNotificationRequest讓你可以在后臺(tái)處理接收到的推送,傳遞最終的內(nèi)容給 contentHandler
serviceExtensionTimeWillExpire 在你獲得的一小段運(yùn)行代碼的時(shí)間即將結(jié)束的時(shí)候溅固,如果仍然沒有成功的傳入內(nèi)容付秕,會(huì)走到這個(gè)方法,可以在這里傳肯定不會(huì)出錯(cuò)的內(nèi)容侍郭,或者他會(huì)默認(rèn)傳遞原始的推送內(nèi)容

主要的思路就是在這里把附件下載下來询吴,然后才能展示渲染,下面是下載保存的相關(guān)方法:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {

    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    NSString * attchUrl = [request.content.userInfo objectForKey:@"image"];
    //下載圖片,放到本地
    UIImage * imageFromUrl = [self getImageFromURL:attchUrl];
    
    //獲取documents目錄
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectoryPath = [paths firstObject];
    
    NSString * localPath = [self saveImage:imageFromUrl withFileName:@"MyImage" ofType:@"png" inDirectory:documentsDirectoryPath];
    if (localPath && ![localPath isEqualToString:@""]) {
        UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"photo" URL:[NSURL URLWithString:[@"file://" stringByAppendingString:localPath]] options:nil error:nil];
        if (attachment) {
            self.bestAttemptContent.attachments = @[attachment];
        }
    }
    self.contentHandler(self.bestAttemptContent);
}

- (UIImage *) getImageFromURL:(NSString *)fileURL {
    NSLog(@"執(zhí)行圖片下載函數(shù)");
    UIImage * result;
    //dataWithContentsOfURL方法需要https連接
    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
    result = [UIImage imageWithData:data];
    
    return result;
}

//將所下載的圖片保存到本地
- (NSString *) saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath {
    NSString *urlStr = @"";
    if ([[extension lowercaseString] isEqualToString:@"png"]){
        urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]];
        [UIImagePNGRepresentation(image) writeToFile:urlStr options:NSAtomicWrite error:nil];
        
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] ||
               [[extension lowercaseString] isEqualToString:@"jpeg"]){
        urlStr = [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]];
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:urlStr options:NSAtomicWrite error:nil];
        
    } else{
        NSLog(@"extension error");
    }
    return urlStr;
}



- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    self.contentHandler(self.bestAttemptContent);
}

apes如下:

{
   "aps":{
        "alert" : {
             "title" : "iOS遠(yuǎn)程消息亮元,我是主標(biāo)題猛计!-title",
              "subtitle" : "iOS遠(yuǎn)程消息,我是主標(biāo)題苹粟!-Subtitle",
              "body" : "Dely,why am i so handsome -body"
            },
        "sound" : "default",
        "badge" : "1",
        "mutable-content" : "1",
        "category" : "Dely_category"
    },
    "image" : "https://p1.bpimg.com/524586/475bc82ff016054ds.jpg",
    "type" : "scene",
    "id" : "1007"
}

注意

  • Notification Service Extension在使用時(shí)需要配置相關(guān)證書
  • mutable-content這個(gè)鍵值為1有滑,這意味著此條推送可以被 Service Extension 進(jìn)行更改,也就是說要用Service Extension需要加上這個(gè)鍵值為1.

特別說明:
有很多朋友經(jīng)常會(huì)問我加斷點(diǎn)調(diào)試怎么不走相應(yīng)方法嵌削,我這里統(tǒng)一回復(fù)下毛好。你要選擇相應(yīng)的target來運(yùn)行工程:

斷點(diǎn)調(diào)試

補(bǔ)充說明:
在最新的Xcode9.2中望艺,斷點(diǎn)也是不會(huì)走的,一個(gè)朋友找了很長時(shí)間的原因發(fā)現(xiàn)是xcode的問題肌访,在xcode8.0上就可以跑到斷點(diǎn)找默。希望蘋果盡快修復(fù)這個(gè)bug,這個(gè)朋友的學(xué)習(xí)熱情很值得我們學(xué)習(xí)吼驶。

3惩激、添加新的Targe--> Notification Content

先在Xcode 打開你的工程,F(xiàn)ile-->New-->Targe然后添加這個(gè) Notification Content:


Notification Content.png

這樣你在工程里同樣看到下面的目錄:

Notification Content.png

點(diǎn)開 NotificationViewController.m 會(huì)看到 2 個(gè)方法:

- (void)viewDidLoad;
- (void)didReceiveNotification:(UNNotification *)notification;

前者渲染UI蟹演,后者獲取通知信息风钻,更新UI控件中的數(shù)據(jù)。

在MainInterface.storyboard中自定你的UI頁面酒请,可以隨意發(fā)揮骡技,但是這個(gè)UI見面只能用于展示,并不能響應(yīng)點(diǎn)擊或者手勢其他事件羞反,只能通過category來實(shí)現(xiàn)布朦,下面自己添加view和約束

MainInterface.storyboard.png

然后把view拉到.m文件中,代碼如下:

#import "NotificationViewController.h"
#import <UserNotifications/UserNotifications.h>
#import <UserNotificationsUI/UserNotificationsUI.h>

@interface NotificationViewController () <UNNotificationContentExtension>

@property IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation NotificationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any required interface initialization here.
    
//    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
//    [self.view addSubview:view];
//    view.backgroundColor = [UIColor redColor];
}

- (void)didReceiveNotification:(UNNotification *)notification {

    self.label.text = notification.request.content.body;
    UNNotificationContent * content = notification.request.content;
    UNNotificationAttachment * attachment = content.attachments.firstObject;
    if (attachment.URL.startAccessingSecurityScopedResource) {
        self.imageView.image = [UIImage imageWithContentsOfFile:attachment.URL.path];
    }
}

@end

有人要有疑問了昼窗,可不可以不用storyboard來自定義界面是趴?當(dāng)然可以了!
只需要在Notifications Content 的info.plist中把NSExtensionMainStoryboard替換為NSExtensionPrincipalClass澄惊,并且value對應(yīng)你的類名唆途!
然后在viewDidLoad里用純代碼布局就可以了

純代碼自定義通知界面.png

4、發(fā)送推送

完成上面的工作的時(shí)候基本上可以了缤削!然后運(yùn)行工程窘哈,
上面的json數(shù)據(jù)放到APNS Pusher里面點(diǎn)擊send:


68BFC911-791F-410D-8849-1F06A135B04E.png

稍等片刻應(yīng)該能收到消息:


遠(yuǎn)端消息.jpg

長按或者右滑查看:

遠(yuǎn)端消息2.jpg

注意 注意 注意:
如果你添加了category,需要在Notification content的info.plist添加一個(gè)鍵值對UNNotificationExtensionCategory的value值和category Action的category值保持一致就行亭敢。

UNNotificationExtensionCategory.png

同時(shí)在推送json中添加category鍵值對也要和上面兩個(gè)地方保持一致:

pusher.png

就變成了下面:

遠(yuǎn)端消息3.jpg

上面介紹了遠(yuǎn)端需要Service Extension 的遠(yuǎn)端推送
iOS 10附件通知(圖片滚婉、gif、音頻帅刀、視頻)让腹。不過對圖片和視頻的大小做了一些限制(圖片不能超過 10M,視頻不能超過 50M)扣溺,而且附件資源必須存在本地骇窍,如果是遠(yuǎn)程推送的網(wǎng)絡(luò)資源需要提前下載到本地。
如果是本地的就簡單了只需要在Service Extension的NotificationService.m的- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler拿到資源添加到Notification Content锥余,在Notification Content的控制器取到資源自己來做需求處理和展示

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    
    
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    // 資源路徑
    NSURL *videoURL = [[NSBundle mainBundle] URLForResource:@"video" withExtension:@"mp4"];
    // 創(chuàng)建附件資源
    // * identifier 資源標(biāo)識(shí)符
    // * URL 資源路徑
    // * options 資源可選操作 比如隱藏縮略圖之類的
    // * error 異常處理
    UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"video.attachment" URL:videoURL options:nil error:nil];
    // 將附件資源添加到 UNMutableNotificationContent 中
    if (attachment) {
        self.bestAttemptContent.attachments = @[attachment];
    }
    
    self.contentHandler(self.bestAttemptContent);
}
Notification.png

上圖如果你想把default 隱藏掉腹纳,只需要在Notification Content 的info.plist中添加一個(gè)鍵值UNNotificationExtensionDefaultContentHidden設(shè)置為YES就可以了:

hiddenDefaultContent.png

總結(jié):到這里基本上Notification相關(guān)知識(shí)就寫完了,了解這些,在做推送的開發(fā)需求會(huì)簡單點(diǎn)嘲恍,再看某盟的消息sdk會(huì)很簡單了足画。中間如果有什么錯(cuò)誤,還請大家批評(píng)指出佃牛。是不是還沒看過癮淹辞,那就期待下篇博客吧!

Demo代碼地址:
https://coding.net/u/Dely/p/UserNotificationsDemo/git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俘侠,一起剝皮案震驚了整個(gè)濱河市象缀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爷速,老刑警劉巖央星,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異遍希,居然都是意外死亡等曼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門凿蒜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胁黑,你說我怎么就攤上這事废封。” “怎么了丧蘸?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵漂洋,是天一觀的道長。 經(jīng)常有香客問我力喷,道長刽漂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任弟孟,我火速辦了婚禮贝咙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拂募。我一直安慰自己庭猩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布陈症。 她就那樣靜靜地躺著蔼水,像睡著了一般。 火紅的嫁衣襯著肌膚如雪录肯。 梳的紋絲不亂的頭發(fā)上趴腋,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼优炬。 笑死颁井,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的穿剖。 我是一名探鬼主播蚤蔓,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糊余!你這毒婦竟也來了秀又?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對情侶失蹤贬芥,失蹤者是張志新(化名)和其女友劉穎吐辙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蘸劈,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昏苏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了威沫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贤惯。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖棒掠,靈堂內(nèi)的尸體忽然破棺而出孵构,到底是詐尸還是另有隱情,我是刑警寧澤烟很,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布颈墅,位于F島的核電站,受9級(jí)特大地震影響雾袱,放射性物質(zhì)發(fā)生泄漏恤筛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一芹橡、第九天 我趴在偏房一處隱蔽的房頂上張望毒坛。 院中可真熱鬧,春花似錦僻族、人聲如沸粘驰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝌数。三九已至,卻和暖如春度秘,著一層夾襖步出監(jiān)牢的瞬間顶伞,已是汗流浹背饵撑。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唆貌,地道東北人滑潘。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像锨咙,于是被迫代替她去往敵國和親语卤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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