你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS10推送必看UNNotificationServiceExtension

iOS10推送必看UNNotificationServiceExtension

編輯:IOS開發基礎

如果大家還沒有看我的這兩篇文章,建議還是先閱讀一下,循序漸進麼~文章鏈接如下:

iOS開發 iOS10推送必看(基礎篇)
iOS開發 iOS10推送必看(高階1)
這次的最後,終於有demo咯~

在這篇文章,我會給大家講一講更高級一點的,定制化更高的遠程通知。其中會補充我之前沒講的遠程推送(多媒體)通知,以及UNNotificationServiceExtension,UNNotificationContentExtension,UNNotificationAction的相關類。相信大家看了這篇文章,雖不能說對蘋果的遠程推送了如指掌,但是也可以做一些基本的擴展咯~

1、UNNotificationServiceExtension

1.1 UNNotificationServiceExtension簡介

UNNotificationServiceExtension是iOS10推出後的一個新特性,先看這張圖:

Extension01.png

從這張圖上,我們可以看到,原先直接從APNs推送到用戶手機的消息,中間添加了ServiceExtension處理的一個步驟(當然你也可以不處理),通過這個ServiceExtension,我們可以把即將給用戶展示的通知內容,做各種自定義的處理,最終,給用戶呈現一個更為豐富的通知,當然,如果網絡不好,或者附件過大,可能在給定的時間內,我們沒能將通知重新編輯,那麼,則會顯示發過來的原版通知內容。

那麼ServiceExtension可以做什麼呢?它的意義是什麼呢?我總結了幾點:

  • 1、安全
    安全總是擺在第一位的,從iOS9開始,蘋果鼓勵我們使用更為安全的https協議可以看的出來,蘋果公司是對安全很重視的一家公司,為什麼在這裡我會提到安全呢?是因為之前我們的推送內容,不管是通過第三方,還是通過蘋果自帶的通知處理,如果讓有心人對數據做一次攔截,抓個包啥的,我們推送的內容就會完全暴露,當然有的同學說,我可以加密啊~但是不知道大家有沒有想過,如果數據加密,那通知欄會怎麼展示呢?(你千萬別跟我說你把所有的遠程推送變成本地通知。。)通過此次這次增加的UNNotificationServiceExtension的類,便可以更好的幫助我們實現數據的加密。
    它的原理便是在收到通知後的最多30s內,你可以把你的通知內容,解密後,在重新展示在用戶的通知攔上。

  • 2、內容的豐富
    之前的通知展示內容比較少,以至於被各種廣告提醒占據了。這次蘋果新添加的附件通知,結合上通知拓展類,便可以給用戶展現出一個有著豐富內容的通知。比如,一個小短片的某一秒的畫面啊(這裡要強烈鄙視各大平台的某些電影預覽圖),又或者是配上一些小圖片啊(通過服務器傳來的imaUrl)等方式來吸引用戶,誘導用戶點開你的通知,促使用戶會使用你的App。其實推送這個功能,雖然有的人會關閉,但是大部分的人還是開啟的,所以說推送這個市場還是很大的喲~靈活利用推送,會讓你的程序擁有無限的可能。

1.2、如何新建一個UNNotificationServiceExtension

首先,我們不能通過創建UNNotificationServiceExtension的類來使用服務擴展,我們應當創建一個Target,這個Target自帶一個模板,其中有2個方法是系統會自己調用的,如下:

//  你需要通過重寫這個方法,來重寫你的通知內容,也可以在這裡下載附件內容
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler;

//  如果處理時間太長,等不及處理了,就會把收到的apns直接展示出來
- (void)serviceExtensionTimeWillExpire;

開始跟著我創建一個UNNotificationServiceExtension吧。

新建Target

QQ20160927-3.png



選擇如圖所示:

QQ20160927-4.png



然後寫名字,下一步,即可
此時我們的目錄結構裡面,已經多出了一個文件夾了。

QQ20160927-5.png


QQ20160927-6.png


都多了一個myTest。

22172ED.png


注意看上圖,這裡的bundleID是你的工程名字的bundleID加上.名稱。
不要修改,系統創建的時候就創建好了,不過我還是給大家說一下這個格式
如果你的工程的BundleID是coderxu.pushDemo,則這個擴展的BundleID就是coderxu.pushDemo.mytest,最後的後綴,是看咱們創建服務擴展時候的名字。其他的小細節,大家可以看看。
到這一步,我們就新建了一個服務通知類的擴展。

1.3、如何使用以及相關Demo

在使用這個類的時候,我重寫了以下代碼,大家可以先看下:
(1). 這是處理通知內容重寫的方法:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    // copy發來的通知,開始做一些處理
    self.bestAttemptContent = [request.content mutableCopy];
    // Modify the notification content here...
    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];

    // 重寫一些東西
    self.bestAttemptContent.title = @"我是標題";
    self.bestAttemptContent.subtitle = @"我是子標題";
    self.bestAttemptContent.body = @"來自徐不同";

    // 附件
    NSDictionary *dict =  self.bestAttemptContent.userInfo;
    NSDictionary *notiDict = dict[@"aps"];
    NSString *imgUrl = [NSString stringWithFormat:@"%@",notiDict[@"imageAbsoluteString"]];

    if (!imgUrl.length) {
        self.contentHandler(self.bestAttemptContent);
    }

    [self loadAttachmentForUrlString:imgUrl withType:@"png" completionHandle:^(UNNotificationAttachment *attach) {

        if (attach) {
            self.bestAttemptContent.attachments = [NSArray arrayWithObject:attach];
        }
        self.contentHandler(self.bestAttemptContent);

    }];
}

(2). 這是下載附件通知的方法:

- (void)loadAttachmentForUrlString:(NSString *)urlStr
                          withType:(NSString *)type
                 completionHandle:(void(^)(UNNotificationAttachment *attach))completionHandler{
    __block UNNotificationAttachment *attachment = nil;
    NSURL *attachmentURL = [NSURL URLWithString:urlStr];
    NSString *fileExt = [self fileExtensionForMediaType:type];

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    [[session downloadTaskWithURL:attachmentURL
                completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
                    if (error != nil) {
                        NSLog(@"%@", error.localizedDescription);
                    } else {
                        NSFileManager *fileManager = [NSFileManager defaultManager];
                        NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:fileExt]];
                        [fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error];

                        NSError *attachmentError = nil;
                        attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:localURL options:nil error:&attachmentError];
                        if (attachmentError) {
                            NSLog(@"%@", attachmentError.localizedDescription);
                        }
                    }
                     completionHandler(attachment);
               }] resume];

}

(3)判斷文件類型的方法

- (NSString *)fileExtensionForMediaType:(NSString *)type {
    NSString *ext = type;
    if ([type isEqualToString:@"image"]) {
        ext = @"jpg";
    }
    if ([type isEqualToString:@"video"]) {
        ext = @"mp4";
    }
    if ([type isEqualToString:@"audio"]) {
        ext = @"mp3";
    }
    return [@"." stringByAppendingString:ext];
}

第一段代碼主要講通知內容的重組,邏輯就是有附件的url,我就下載,如果沒有url我就直接展示通知。
第二段代碼主要講的是,用系統自帶類,下載圖,存圖,找到filePath,創建通知的附件內容。(創建附件的url,必須是一個文件路徑,也就是說,必須下載下,才能獲取文件路徑,開頭是file://)
第三段的代碼主要講判斷文件的後綴類型,然後前端好處理。這裡我的代碼是寫死了,因為我就測試一張圖。最好的方式是服務器返回的 推送內容中,帶有附件的類型。我的iOS開發 iOS10推送必看(高階1)一文中,有講多媒體附件的類型,以及相關的大小限制。

這裡強烈建議,處理推送內容的時候,讓服務器帶上文件類型。重要的事情說三遍
這裡強烈建議,處理推送內容的時候,讓服務器帶上文件類型。重要的事情說三遍
這裡強烈建議,處理推送內容的時候,讓服務器帶上文件類型。重要的事情說三遍

在補充一些問題

  • 1.在這個推送服務的擴展類中,為什麼我使用了系統自帶類下載,沒有使用AFN?
    答:不知道為什麼,導入AFN後總是出現各種編譯報錯啊。主要涉及這幾個情況
    1.用cocoapods導入AFN,在類引入AFN,編譯報錯!!
    2.手動拖拽AFN進工程(不勾選),在類引入AFN,編譯報錯!!
    3.手動拖拽AFN進工程(勾選),直接編譯報錯!!
    4.下載用通知回調的方式(慢,線程不確定)
    最後我就選擇這個block回調,系統類下載的方式,來下載通知中的附件。

以下是一些錯誤的截圖:(可以不看)

QQ20160927-0.png


QQ20160927-1.png

QQ20160927-2.png


  • 2.如果調試這個通知擴展類,為什麼我跑程序的時候,打斷點無反應?
    答:這是因為你跑的target不對,正確的做法是,跑正確的target,具體如下圖:


  • QQ20160927-7.png

選擇你的程序Target

QQ20160927-8.png

這個時候,大家在打斷點,就可以啦~

最後,在附上推送的內容格式。
推送內容格式如下:

{
    "aps": {
        "alert": "This is some fancy message.",
        "badge": 1,
        "sound": "default",
        "mutable-content": "1",
        "imageAbsoluteString": "http://upload.univs.cn/2012/0104/1325645511371.jpg"

    }
}

這裡我們要注意一定要有"mutable-content": "1",以及一定要有Alert的字段,否則可能會攔截通知失敗。(蘋果文檔說的)。除此之外,我們還可以添加自定義字段,比如,圖片地址,圖片類型,大家慢慢摸索下吧~有問題可以留言喲~

這一章的最後,附上成功推送的展示圖:

QQ20160927-9.png


稍後補充以下內容~

# 2、UNNotificationContentExtension
## 2.1、UNNotificationContentExtension簡介
## 2.2、如何新建一個UNNotificationContentExtension
## 2.3、如何使用以及相關Demo
# 3、UNNotificationAction
## 3.1、UNNotificationAction簡介
## 3.2、如何新建一個UNNotificationAction
## 3.3、如何使用以及相關Demo

如果你喜歡我的文章,不要忘記關注我,謝謝大家了~
另外如果你要轉載,希望可以注明出處,我會寫出更多更好的文章,來回饋大家~

重要的事情說三遍,demo地址
重要的事情說三遍,demo地址
重要的事情說三遍,demo地址



文章轉自 徐不同的簡書
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved