iOS开发技术上海快风信息科技有限公司iOS推送技术

四、<iOS 远程推送> iOS 10 UNNoti

2017-07-28  本文已影响1959人  Dosun

之前一直在想苹果的 iOS10 远程推送能不能做得像其本地推送一模一样的效果,那样炫那样酷?答案是一定的。让我们欣赏一下 iOS10 本地推送。

iOS 10 本地推送

远程如何实现这些功能, iOS 10 提供 Notification Service Extension,就是用它了。那么 Extension 是如何用?如果用 Extension 时,该应用是否能安装在低于 iOS 10的手机上?Extension 是否能下载网上的资源?如果能,能下载多大的东东?能下载多长时间?为什么 iOS 10 推送那么酷,几乎没有一款应用使用它呢?

带着一列的问题,对 iOS 10 远程推送进行深入的研究,对于研究新的东西,我一般习惯是看它能做什么?能做成什么样子,自己再尝试着去实现它,完善它。

一、如何创建 推送 Extension

思考:若应用程序安装在手机上, Extension 会不会也在手机界面上显示 Extension 图标?
答案:Extension 不会也在手机界面上显示 Extension 图标,验证过。

二、UNNotificationServiceExtension API 的研读

在生成 Extension 后,系统会自动生成两个文件:NotificationService.h 和 NotificationService.m 。 NotificationService 是继续 UNNotificationServiceExtension,那么UNNotificationServiceExtension 是什么的干活??

如下图所示 APNs 是将消息首先推送给 ServiceExtension ,ServiceExtension 会处理好数据后再展示给用户一个优美的界面,ServiceExtension 就是一个厨师,收到原材料,给用户做成美味的食物一样,so sweat!



在展示用户推送内容前,UNNotificationServiceExtension 是修改远程推送携带的内容。UNNotificationServiceExtension 类 可以让开发者自定义推送展示的内容,Notification Service app extension 不会自己提供推送界面的,当将适当类型的推送传递给用户的设备时,它会按需启动。你可以用 extension 修改推送内容和下载推送相关的资源。你可以在extension 中解密和加密的数据或下载推送相关的图片。

你不需要自己创建 UNNotificationServiceExtension 实例,Xcode 已经帮我们创建好了。当满足如下两个条件,应用收到远程推送时,应用会加载 extension 和调用 didReceiveNotificationRequest:withContentHandler:
方法。

注意:不能修改静默推送或推送内容是声音或者应用的角标

在 didReceiveNotificationRequest:withContentHandler: 里面可以处理远程推送内容,修改远程推送内容的时间是有限的。如果修改内容任务没有完成,系统会调用 serviceExtensionTimeWillExpire
方法,给你提供最后一次提供修改内容的机会。如果你没有修改远程推送成功,系统将会展示远程推送最原始的内容。

三、修改远程推送内容代码实现

请欣赏下图 gif 动画,接受远程推送并下载图片。

远程推送.gif

关于如何注册通知和配置证书,请参考 三、<iOS 远程推送> 静默推送 ,其代码都是相同的,只是发送推送时内容不一样。

一、代码

在 NotificationService.m 中

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    // Modify the notification content here...
    //推送内容
    NSDictionary *dict = self.bestAttemptContent.userInfo;
    NSDictionary *noticeDict = dict[@"aps"];
    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@",noticeDict[@"title"]];
    self.bestAttemptContent.subtitle = [NSString stringWithFormat:@"%@",noticeDict[@"subtittle"]];
    self.bestAttemptContent.body = [NSString stringWithFormat:@"%@",noticeDict[@"boby"]];
    self.bestAttemptContent.categoryIdentifier = @"categoryIdentifier1";
    
    //取出文件类型
    NSString *fileType = [NSString stringWithFormat:@"%@",noticeDict[@"fileType"]];
    NSString *imgUrl = [NSString stringWithFormat:@"%@",noticeDict[@"imageAbsoluteString"]];
    NSLog(@"%@",imgUrl);
    if (!imgUrl.length) {
        self.contentHandler(self.bestAttemptContent);
    }
    
    NSLog(@"%@",imgUrl);
   [self loadAttachmentForUrlString:imgUrl withType:fileType completionHandle:^(UNNotificationAttachment *attach) {
       if (attach) {
           self.bestAttemptContent.attachments = [NSArray arrayWithObject:attach];
       }
       self.contentHandler(self.bestAttemptContent);
   }];
}

//此方法调时,是修改远程推送失败
- (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);
}

#pragma mark - 私有方法
//下载附件 并发送
- (void)loadAttachmentForUrlString:(NSString *)urlStr
                          withType:(NSString *)type
                  completionHandle:(void(^)(UNNotificationAttachment *attach))completionHandler{
    
    
    __block UNNotificationAttachment *attachment = nil;
    
    NSURL *attachmentURL = [NSURL URLWithString:urlStr];
    NSString *fileExt = [@"." stringByAppendingString: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]];
                        NSLog(@"%@",localURL);
                        [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];
}

@end
二、info.plist 配置

另外需要配置 info ,不然会报名如下图的错误


错误.png

两个文件中的 info.plist ,建议都要配置一下。


Snip20170728_57.png
配置的内容如下
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
三、推送的内容

提供一个强大的基于 MAC 的推送服务器,SmartPush。运行 Xcode 会出现如下图的弹框。

推送内容

{
     "aps": {
     "alert": "This is some fancy message.",
     "badge": 1,
     "sound": "default",
     "mutable-content": "1",
     "imageAbsoluteString":     "http://upload.univs.cn/2012/0104/1325645511371.jpg",
     "title" :"hello world",
     "subtittle":"tips",
     "boby":"may maker help us all",
      "fileType":"jpg"
     }
     }
四、注意点
Snip20170728_59.png
五、总结
git图 远程推送视频
上一篇 下一篇

猜你喜欢

热点阅读