美文网首页
iOS【NotificationContent】

iOS【NotificationContent】

作者: NJ_墨 | 来源:发表于2020-12-18 20:22 被阅读0次

    =======================================================
    如需通知项目B里拿到主项目A里的数据,可以使用共享
    iOS【NotificationContent-App Group共享】
    通知送达率检查:通过NotificationContent 可以埋点数据,通知送达上报
    =======================================================

    App配置了通知服务扩展程序后,每个通知都会执行以下过程:

    1、App收到通知。
    2、系统创建扩展类的实例对象并在后台启动它。
    3、你的扩展程序会执行内容编辑和/或下载某些内容操作。
    4、如果你的扩展程序执行太长时间而不能完成它的工作,将会收到通知并被立即终止。
    5、通知显示给用户。

    NotificationContent:新建的通知项目就当一个新的项目,需要创建对应的id、开发证书、发布证书;

    1、创建Service Extension

    使用Xcode打开项目,选中File -> New -> Target...,在出现的弹窗中选择Notification Service Extension模板

    截屏2020-12-19 下午4.23.58.png
    2、创建对应的id、开发证书、发布证书
    截屏2020-12-18 下午8.05.53.png 截屏2020-12-18 下午8.06.18.png
    3、使推送走NotificationService的处理:

    服务端设置"mutable-content":1 ,这样推送过来就会走NotificationService的处理逻辑

    {
      "aps":{
        "alert":{
          "title":"iOS 10 title",
          "subtitle":"iOS 10 subtitle",
          "body":"iOS 10 body"
        },
        "my-attachment":"http://img01.xxx.jpg",
        "mutable-content":1,
        "category":"myNotificationCategory1",
        "sound":"default",
        "badge":3
      }
    }
    
    #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];
            
        
        NSDictionary *userInfo = request.content.userInfo;
        
       // 统计远程推送到达率
        [self postDisplaydata:userInfo];
    
        NSString *soundName = nil;
        NSString *title = nil;
        NSString *body = nil;
        NSString *subtitle = nil;
        NSString *imagePath = userInfo[@"image"];
        
        NSDictionary *apsDic = userInfo[@"aps"];
        if ([apsDic isKindOfClass:[NSDictionary class]]) {
            soundName = apsDic[@"sound"];
            
            NSDictionary *alertDic = apsDic[@"alert"];
            if ([alertDic isKindOfClass:[NSDictionary class]]) {
                title = alertDic[@"title"];
                subtitle = alertDic[@"subtitle"];
                body = alertDic[@"body"];
                
                if (apsDic[@"image"]) {
                    imagePath = apsDic[@"image"];
                }
            }
        }
        
        if ([body isKindOfClass:[NSString class]] && body.length>0) {
            self.bestAttemptContent.body = body;
        }
        if ([title isKindOfClass:[NSString class]] && title.length>0) {
            self.bestAttemptContent.title = title;
        }
        if ([subtitle isKindOfClass:[NSString class]] && subtitle.length>0) {
            self.bestAttemptContent.subtitle = subtitle;
        }
        //self.bestAttemptContent.launchImageName = @"startLaunchImage";
    
        if ([soundName isKindOfClass:[NSString class]] && soundName.length>0) {
            self.bestAttemptContent.sound = [UNNotificationSound soundNamed:soundName];
        }
        
        if (![imagePath isKindOfClass:[NSString class]] || imagePath.length==0) {
            self.contentHandler(self.bestAttemptContent);
            return;
        }
        
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSURL *imageURL = [NSURL URLWithString:imagePath];
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
            
            NSString *userDocument = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
            NSString *path = [NSString stringWithFormat:@"%@/notifications.jpg", userDocument];
            
            // 一定要先删除老的图片
            [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
            [imageData writeToFile:path atomically:YES];
            
            NSURL *url = [NSURL fileURLWithPath:path];
            UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment" URL:url options:nil error:nil];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                if (attachment) {
                    self.bestAttemptContent.attachments = @[attachment];
                }
                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);
    }
    
    - (void)postDisplaydata:(NSDictionary *)userInfo  {
    
        NSString *postUrl = @"http://abc.com";
        NSDictionary *dict =  @{@"key"         : @"app_receive_push",
                                @"Token"       : @"abcdexxxToken",
                            @"deviceType"      : @"iOS",
                        @"af_push_id"          : STLNotifyToString(@"pushId"),};
        [STLNotificationRequestManager POST:postUrl parameters:dict];
    }
    @end
    
    //封装请求类
    
    @implementation STLNotificationRequestManager
    
    /**
     统计远程推送达到率
    
     @param URL 统计地址
     @param dic 上报数据
     */
    + (void)POST:(NSString *)URL parameters:(NSDictionary *)dic {
        if (![dic isKindOfClass:[NSDictionary class]]) return;
        if (![URL isKindOfClass:[NSString class]]) return;
        
        //创建配置信息
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        //设置请求超时时间:7秒
        configuration.timeoutIntervalForRequest = 7;
        //创建会话
        NSURLSession *session = [NSURLSession sessionWithConfiguration: configuration delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
        NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: URL]];
        //设置请求方式:POST
        [request setHTTPMethod:@"POST"];
        [request setValue:@"application/json" forHTTPHeaderField:@"content-Type"];
        [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Accept"];
          
        NSDictionary *requestParams = [[NSDictionary alloc] initWithDictionary:dic];
        
        STLLog(@"GGGGG request params: %@",requestParams);
        //data的字典形式转化为data
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:requestParams options:NSJSONWritingPrettyPrinted error:nil];
        //设置请求体
        [request setHTTPBody:jsonData];
        
        NSURLSessionDataTask * dataTask =[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            STLLog(@"GGGGGURL:---%@",URL);
    
            if (error == nil) {
                NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                STLLog(@"GGGGGGGREQ success:%@ 11",responseObject);
            }else{
                STLLog(@"GGGGGGGREQ error:%@",error);
            }
        }];
        [dataTask resume];
    }
    
    
    
    本地测试
    - (void)testNotificationContent {
        // 1.创建通知内容
        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        content.title = @"occc通知";
        content.subtitle = @"occc subtitle";
        content.body = @"occc body";
        content.badge = @1;
        NSError *error = nil;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"logoTitle60@2x" ofType:@"png"];
        // 2.设置通知附件内容
        UNNotificationAttachment *att = [UNNotificationAttachment attachmentWithIdentifier:@"att1" URL:[NSURL fileURLWithPath:path] options:nil error:&error];
        if (error) {
            NSLog(@"attachment error %@", error);
        }
        content.attachments = @[att];
        content.launchImageName = @"logoTitleShow@2x";
        // 2.设置声音
        UNNotificationSound *sound = [UNNotificationSound defaultSound];
        content.sound = sound;
        
        // 3.触发模式
        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
        
        // 4.设置UNNotificationRequest
        NSString *requestIdentifer = @"TestRequest";
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger];
        
        //5.把通知加到UNUserNotificationCenter, 到指定触发点会被触发
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        }];
    }
    
    DEBUG 调试

    target选择自己创建的NotificationServiceExtension,
    点击运行,发送推送,推送消息收到了,
    "mutable-content": 1,也有放到推送消息里,如果还是没有走断点,
    选择点击Attach to Process by PID or Name..
    如果是http请求,需要在plist里开启支持http请求。

    截屏2020-12-19 下午5.26.27.png 截屏2020-12-19 下午5.30.51.png

    调试推送,没有走didReceiveNotificationRequest的几个可能的原因:

    1、调试时,target选择不对(停止运行按钮旁边那个)
    2、推送的数据没有带上"mutable-content": 1
    3、推送的target设置的系统版本要求高于真机系统。

    消息字段说明

    // 1.附件数组,存放UNNotificationAttachment类
    @property (NS_NONATOMIC_IOSONLY, copy) NSArray <UNNotificationAttachment *> *attachments ;

    // 2.应用程序角标,0或者不传,意味着角标消失
    @property (NS_NONATOMIC_IOSONLY, copy, nullable) NSNumber *badge;

    // 3.主体内容
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *body ;

    // 4.app通知下拉预览时候展示的图
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *launchImageName;

    // 5.UNNotificationSound类,可以设置默认声音,或者指定名称的声音
    @property (NS_NONATOMIC_IOSONLY, copy, nullable) UNNotificationSound *sound ;

    // 6.推送内容的子标题
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *subtitle ;

    // 7.通知线程的标识
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *threadIdentifier;

    // 8.推送内容的标题
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *title ;

    // 9.远程通知推送内容
    @property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *userInfo;

    // 10.category标识
    @property (NS_NONATOMIC_IOSONLY, copy) NSString *categoryIdentifier;

    UNTimeIntervalNotificationTrigger (通知触发模式)

    UNTimeIntervalNotificationTrigger *triggerOne = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];

    NSDateComponents *components = [[NSDateComponents alloc] init];
    // 注意,weekday是从周日开始的,
    // 周一早上 7:00 上班
    components.weekday = 2;
    components.hour = 7;
    UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger >triggerWithDateMatchingComponents:components repeats:YES];

    UNLocationNotificationTrigger (本地通知)
    地理位置的一种通知,使用这个通知,你需要导入

    import<CoreLocation/CoreLocation.h>这个系统类库。

    1、如果用户进入或者走出某个区域会调用下面两个方法

    • (void)locationManager:(CLLocationManager *)manager
      didEnterRegion:(CLRegion *)region
    • (void)locationManager:(CLLocationManager *)manager
      didExitRegion:(CLRegion *)region代理方法反馈相关信息

    2、一到某个经纬度就通知,判断包含某一点么

    // 不建议使用!!!!!!CLRegion *region = [[CLRegion alloc] init];// 不建议使用!!!!!!
    CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] init];
    [circlarRegin containsCoordinate:(CLLocationCoordinate2D)];
    UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:NO];

    UNNotificationAttachment (附件内容通知)

    在UNNotificationContent类中,有个附件数组的属性,
    这就是包含UNNotificationAttachment类的数组了。

    UNNotificationAttachment(附件通知)
    是指可以包含音频,图像或视频内容,并且可以将其内容显示出来的通知。
    使用本地通知时可以在通知创建时,将附件加入即可。
    对于远程通知则必须实现使用UNNotificationServiceExtension类通知服务扩展。

    创建附件的方法是attachmentWithIdentifier:URL:options:error:
    使用时须指定使用文件附件的内容,并且文件格式必须是支持的类型之一。
    创建后,将其分配给内容对象的附件属性。
    附件通知支持的类型如下图:

    QQ20160918-3.png-45.5kB

    UNNotificationAttachmentOptionsThumbnailHiddenKey,是一个BOOL值,为YES时候,缩略图将隐藏,默认为YES;
    UNNotificationAttachmentOptionsThumbnailClippingRectKey剪贴矩形的缩略图;
    UNNotificationAttachmentOptionsThumbnailTimeKey,一般影片附件会用到,指的是用影片中的某一秒来做这个缩略图;

    相关文章

      网友评论

          本文标题:iOS【NotificationContent】

          本文链接:https://www.haomeiwen.com/subject/zczigktx.html