IOS 10 新特性以及介紹-Notifications

<pre>上一篇中講到Message中的一些特性,本次主要講下Notification的特性</pre>

iOS10相對(duì)于之前的版本,主要是開發(fā)者可以使用Extension的形式修改和展示內(nèi)容,主要是<code>UNNotificationServiceExtension</code>和<code>UNNotificationContentExtension</code>。同時(shí)也添加了其他方面的支持,例如<code>UNNotificationTrigger</code>、<code>UNNotificationAttachment</code>、<code>UNNotificationAction</code>。本次講的主要有以下幾點(diǎn):

  • UNNotificationTrigger(通知觸發(fā)條件設(shè)定)
  • UNNotificationAttachment (通知附件)
  • UNNotificationContentExtension (通知內(nèi)容擴(kuò)展)
  • UNNotificationServiceExtension (通知服務(wù)擴(kuò)展)
  • UNNotificationAction (通知響應(yīng)事件)

1、UNNotificationTrigger(通知觸發(fā)條件設(shè)定)

主要是針對(duì)本地通知觸發(fā)時(shí)機(jī)的設(shè)置,可以使用下面方式設(shè)置:

  1. UNPushNotificationTrigger:這個(gè)是蘋果通知服務(wù)的 Trigger,對(duì)外沒有暴露任何接口屬性,不需要開發(fā)者創(chuàng)建,由系統(tǒng)創(chuàng)建。
  2. UNTimeIntervalNotificationTrigger(時(shí)間觸發(fā)器):通過初始化方法設(shè)置通知的timeInterval(觸發(fā)間隔)
    和repeats(是否重復(fù)觸發(fā)),若 repeats 設(shè)置為 false,通知將在 timeInterval 之后被推送。
  3. UNCalendarNotificationTrigger(日期觸發(fā)器):類似 UNTimeIntervalNotificationTrigger,也是時(shí)間觸發(fā)器,只不過初始化時(shí)第一個(gè)參數(shù)為 DateComponents類型,可設(shè)置具體的觸發(fā)時(shí)間比如8:00 AM等,也可設(shè)置是否重復(fù)觸發(fā)。
  4. UNLocationNotificationTrigger(位置觸發(fā)器):通過設(shè)置 CLRegion類型參數(shù)設(shè)置位置信息,當(dāng)用戶處于某一區(qū)域時(shí),自動(dòng)推送通知。

使用:

  //設(shè)置Notification內(nèi)容
  UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
  content.title = [NSString localizedUserNotificationStringForKey:@"title!" arguments:nil];
  content.body = [NSString localizedUserNotificationStringForKey:@"body" arguments:nil];
  content.subtitle = [NSString localizedUserNotificationStringForKey:@"subtitle" arguments:nil];
  content.sound = [UNNotificationSound defaultSound];
  
  //初始化時(shí)間觸發(fā)器
  UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:10 repeats:NO];
  UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"Identifier"
                                                                        content:content
                                                                        trigger:trigger];
  
  // 請(qǐng)求計(jì)劃推送
  [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
      if(error)
      {
          NSLog(@"%@",error);
      }
  }];

2、UNNotificationAttachment(通知附件)

蘋果所支持的推送附件類型包含視頻,音頻,圖片,蘋果的文檔中對(duì)文件的類型和大小做了如下限制:傳送門
使用說明:

  • 本地通知:

設(shè)置<code>UNMutableNotificationContent</code>如下屬性

@property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments```

  • 遠(yuǎn)程通知:

通過URL地址下載資源,然后將資源設(shè)置到request.content.attachments

示例代碼:

- (void)handlerImageWith:(NSString *)attachUrl{
   
   [self downloadFileAndSave:[NSURL URLWithString:attachUrl] handler:^(NSURL *localUrl) {
       if (localUrl){
           UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"image_download" URL:localUrl options:nil error:nil];
           self.bestAttemptContent.attachments = @[attachment];
       }
       self.contentHandler(self.bestAttemptContent);
   }];

}

- (void)downloadFileAndSave:(NSURL *)url handler:(void (^)(NSURL *))handler{
   NSURLSession *session = [NSURLSession sharedSession];
   
   NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url
                                                       completionHandler:^(NSURL * _Nullable location,
                                                                           NSURLResponse * _Nullable response,
                                                                           NSError * _Nullable error) {
                                                           NSURL *localURL = nil;
                                                           if(!error){
                                                               NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
                                                               // response.suggestedFilename : 建議使用的文件名,一般跟服務(wù)器端的文件名一致
                                                               NSString *file = [caches stringByAppendingPathComponent:response.suggestedFilename];
                                                               
                                                               // 將臨時(shí)文件剪切或者復(fù)制Caches文件夾
                                                               NSFileManager *mgr = [NSFileManager defaultManager];
                                                               
                                                               // AtPath : 剪切前的文件路徑
                                                               // ToPath : 剪切后的文件路徑
                                                               [mgr moveItemAtPath:location.path toPath:file error:nil];
                                                               
                                                               if (file && ![file  isEqualToString: @""])
                                                               {
                                                                   localURL = [NSURL URLWithString:[@"file://" stringByAppendingString:file]];
                                                               }
                                                           }
                                                           handler(localURL);
                                                       }];
   [downloadTask resume];
} 

注意事項(xiàng):

  • UNNotificationContent 的 attachments雖然是一個(gè)數(shù)組,但是系統(tǒng)只會(huì)展示第一個(gè) attachment 對(duì)象的內(nèi)容。不過你依然可以發(fā)送多個(gè) attachments,然后在要展示的時(shí)候再重新安排它們的順序,以顯示最符合情景的圖片或者視頻。另外,你也可能會(huì)在自定義通知展示 UI 時(shí)用到多個(gè) attachment。
  • 在當(dāng)前 beta (iOS 10 beta 4) 中,serviceExtensionTimeWillExpire被調(diào)用之前,你有 30 秒時(shí)間來處理和更改通知內(nèi)容。對(duì)于一般的圖片來說,這個(gè)時(shí)間是足夠的。但是如果你推送的是體積較大的視頻內(nèi)容,用戶又恰巧處在糟糕的網(wǎng)絡(luò)環(huán)境的話,很有可能無法及時(shí)下載完成。
  • 如果你想在遠(yuǎn)程推送來的通知中顯示應(yīng)用 bundle 內(nèi)的資源的話,要注意 extension 的 bundle 和 app main bundle 并不是一回事兒。你可以選擇將圖片資源放到 extension bundle 中,也可以選擇放在 main bundle 里??傊?,你需要保證能夠獲取到正確的,并且你具有讀取權(quán)限的 url。關(guān)于從 extension 中訪問 main bundle,可以參看這篇回答
  • 系統(tǒng)在創(chuàng)建 attachement 時(shí)會(huì)根據(jù)提供的 url 后綴確定文件類型,如果沒有后綴,或者后綴無法不正確的話,你可以在創(chuàng)建時(shí)通過 UNNotificationAttachmentOptionsTypeHintKey
    指定資源類型。
  • 如果使用的圖片和視頻文件不在你的 bundle 內(nèi)部,它們將被移動(dòng)到系統(tǒng)的負(fù)責(zé)通知的文件夾下,然后在當(dāng)通知被移除后刪除。如果媒體文件在 bundle 內(nèi)部,它們將被復(fù)制到通知文件夾下。每個(gè)應(yīng)用能使用的媒體文件的文件大小總和是有限制,超過限制后創(chuàng)建 attachment 時(shí)將拋出異常??赡艿乃绣e(cuò)誤可以在 UNError中找到。
  • 你可以訪問一個(gè)已經(jīng)創(chuàng)建的 attachment 的內(nèi)容,但是要注意權(quán)限問題。可以使用 startAccessingSecurityScopedResource來暫時(shí)獲取以創(chuàng)建的 attachment 的訪問權(quán)限。比如:
if(notification.request.content.attachments && notification.request.content.attachments.count > 0){
        NSURL *imageUrl = notification.request.content.attachments[0].URL;
        if([imageUrl startAccessingSecurityScopedResource]){
            NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
            UIImage *image = [[UIImage alloc] initWithData:imageData];
            self.imageView.image = image;
            [imageUrl stopAccessingSecurityScopedResource];
        }
    }

3、UNNotificationContentExtension(通知內(nèi)容擴(kuò)展)

通知內(nèi)容擴(kuò)展需要新建一個(gè) UNNotificationContentExtension Target,之后只需在 viewcontroller 的中實(shí)現(xiàn)相應(yīng)的接口,即可以對(duì) app 的通知頁面進(jìn)行自定義擴(kuò)展,擴(kuò)展主要用于自定義 UI。擴(kuò)展頁面樣式可以在 plist 中配置,字段說明如下:

  • UNNotificationExtensionCategory: 要讓通知支持內(nèi)容擴(kuò)展,需要將通知的 categoryIdentifier(類型標(biāo)示) 加入此處。
  • UNNotificationExtensionDefaultContentHidden: 默認(rèn)內(nèi)容隱藏,如果設(shè)為 YES,則最下面通知 content 部分會(huì)隱藏。
  • UNNotificationExtensionIntialContentSizeRation: 初始內(nèi)容 Size 的比例。也可以在 viewDidLoad 中使用 self.preferredContentSize 直接設(shè)置 Size。

使用說明:
遠(yuǎn)程和本地通知最終都可以使用此擴(kuò)展自定義 UI,只需將通知的 categoryIdentifier(類型標(biāo)示) 加入到 plist 中即可。

  • 本地推送時(shí),確保設(shè)置的 content.categoryIdentifier(通知內(nèi)容類型標(biāo)示) 已加入 plist 中。
  • 遠(yuǎn)程推送,需要設(shè)置 category 字段,且確保值也已加入 plist 中。

4、UNNotificationServiceExtension (通知服務(wù)擴(kuò)展)

UNNotificationServiceExtension 提供在遠(yuǎn)程推送將要被 push 出來前,處理推送顯示內(nèi)容的機(jī)會(huì)。此時(shí)可以對(duì)通知的 request.content 進(jìn)行內(nèi)容添加,如添加附件,userInfo 等。服務(wù)器推送實(shí)例:

{
  "aps" : {
    "alert" : {
      "title" : "title",
      "body" : "Your message Here"      
    },
     // 開啟可變內(nèi)容
    "mutable-content" : "1",   
    // 加入自定義數(shù)據(jù),圖片 url 路徑
    "image":"http://....jpg"               
  }
}

示例代碼:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    NSDictionary *apsDic = [request.content.userInfo objectForKey:@"aps"];
    NSString *attachUrl = [apsDic objectForKey:@"image"];
    if(attachUrl){
        [self handlerImageWith:attachUrl];
    }
}

5、UNNotificationAction(通知響應(yīng)事件)

代表一個(gè)響應(yīng)通知的事件??梢詾槊總€(gè)通知設(shè)置不同的交互事件。下拉推送通知或處在鎖屏界面?zhèn)然ㄖ獣r(shí),會(huì)出現(xiàn)交互按鍵。
交互事件主要分為以下兩類:

  • UNNotificationAction:
    普通點(diǎn)擊按鍵,可設(shè)置 identifier、 title 及 點(diǎn)擊后的響應(yīng),例如:foreground 前臺(tái)響應(yīng),destructive 點(diǎn)擊后銷毀通知,authenticationRequired 響應(yīng)前是否需要解鎖。甚至可以使用 UNNotificationAction + accessoryInputView 結(jié)合,達(dá)到加入自定義輔助輸入控件的效果
  • UNTextInputNotificationAction:
    當(dāng)然也可以直接使用系統(tǒng)類 UNTextInputNotificationAction 創(chuàng)建輸入框,但是風(fēng)格比較固定。

示例代碼:

- (void)registerNotificationCategory{
    UNTextInputNotificationAction *inputAction = [UNTextInputNotificationAction actionWithIdentifier:@"action_reply" title:@"回復(fù)" options:UNNotificationActionOptionForeground];
    UNNotificationAction *cancelAction = [UNNotificationAction actionWithIdentifier:@"action_cancel" title:@"取消" options:UNNotificationActionOptionDestructive];
    
    UNNotificationCategory *saySomething = [UNNotificationCategory categoryWithIdentifier:saySomethingCategory actions:@[inputAction,cancelAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:saySomething]];
}

響應(yīng)處理:

  • 若處于 UNNotificationContentExtension 通知擴(kuò)展界面時(shí),點(diǎn)擊 【回復(fù)】按鍵會(huì)回調(diào) UNNotificationContentExtension 擴(kuò)展接口的方法:
// If implemented, the method will be called when the user taps on one
// of the notification actions. The completion handler can be called
// after handling the action to dismiss the notification and forward the
// action to the app if necessary.
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption option))completion;{
    
}
  • 如果不支持 UNNotificationContentExtension則點(diǎn)擊【回復(fù)】回調(diào) UNUserNotificationCenterDelegate 中的方法:
// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from applicationDidFinishLaunching:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{

}

補(bǔ)充:iOS10中可以在前臺(tái)中收到通知了,需要添加一下代碼:

\\ notificationHandler實(shí)現(xiàn)UNUserNotificationCenterDelegate
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self.notificationHandler];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容