zoukankan      html  css  js  c++  java
  • iOS 10 UserNotification框架解析 – 本地通知

    iOS 10以前的通知比较杂乱,把本地通知和远程通知分开了,诞生了许多功能类似的API,很容易让初学者犯迷糊。而iOS 10的通知把API做了统一,利用独立的UserNotifications.framework框架来管理通知;并且,还增加了撤销单条通知、更新已展示通知、中途修改通知内容等等,以及在通知中展示图片视频,自定义通知UI等一系列新功能;总之,iOS 10的通知功能十分强大。

    的通知之前,有必要了解一下通知的历史现状。由于通知可以方便的提示用户应用的状态、传递重要的信息,所以自从iOS 3引入通知以来,几乎每个新的版本,Apple都会增强通知的功能。

    一、发展历程:

    iOS 3 - 引入推送通知

    UIApplication 的 registerForRemoteNotificationTypesUIApplicationDelegateapplication(_:didRegisterForRemoteNotificationsWithDeviceToken:)application(_:didReceiveRemoteNotification:)

    iOS 4 - 引入本地通知

    scheduleLocalNotificationpresentLocalNotificationNow:application(_:didReceive:)

    iOS 5 - 加入通知中心页面

    iOS 6 - 通知中心页面与 iCloud 同步

    iOS 7 - 后台静默推送

    application(_:didReceiveRemoteNotification:fetchCompletionHandle:)

    iOS 8 - 重新设计notification权限请求,加入交互式通知

    Actionable 通知 registerUserNotificationSettings(_:),UIUserNotificationAction UIUserNotificationCategoryapplication(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)

    iOS 9 - Text Input action

    基于 HTTP/2 的推送请求 UIUserNotificationActionBehavior,全新的 Provider API 等

    二、通知应用

    申请权限

    	// 获取通知中心对象
    	UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        
        // 申请通知权限
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"通知开启");
            } else {
                NSLog(@"关闭通知");
            }
        }];
        
        // 获取授权的通知权限
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"%@", settings);
        }];
    

    requestAuthorizationWithOptions:

    申请通知的权限,iOS 10不再区分远程通知和本地通知的权限申请,统一用该方法做权限申请

    添加通知

    	// 创建通知对象
    	UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init]];
    	// 设置通知标题
    	noticeContent.title = @"iOS10通知";
    	// 设置通知子标题
        noticeContent.subtitle = @"新通知学习笔记";
        // 设置通知内容
        noticeContent.body = @"新通知变化很大,之前本地通知和远程推送是两个类,现在合成一个了。";
        // 添加通知的声音
        UNNotificationSound *sound = [UNNotificationSound soundNamed:@"caodi.m4a"];
        noticeContent.sound = sound;
    

    UNMutableNotificationContent

    通知的内容,可以设置通知的标题、副标题、具体内容,以及通知的图片、视频、声音和交互信息等等

    UNNotificationSound

    应用在后台时收到通知时的提示音

    触发机制

    	// 如果repeats为YES,那么triggerWithTimeInterval的值要大于60s
        UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3 repeats:NO];
        
        NSString *requestIdentifier = @"requestIdentifier";
        
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:trigger1];
    

    UNTimeIntervalNotificationTrigger

    设置通知触发的条件,分为以下几类:

    • 1.UNPushNotificaitonTrigger

    推送服务的Trigger,由系统创建

    • 2.UNTimeIntervalNotificaitonTrigger

    时间触发器,可以设置多长时间后触发通知,repeats参数为是否重复触发,如果设置YES,那么triggerWithTimeInterval的时间必须大于60s

    • 3.UNCalendarNotificaitonTrigger

    日期触发器,可以设置特定日期触发

    • 4.UNLocationNotificaitonTrigger

    位置触发器,用于到达特定位置后才触发通知,需要设置CLRegion的具体区域

    发送通知

    	[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
            NSLog(@"发送通知出错: %@", error);
        }];
    

    addNotificationRequest:withCompletionHandler:

    把通知添加到通知中心,就可以发送通知了

    扩展通知

    我们可以在通知中添加声音、图片和视频,来丰富通知的内容,在支持3D-touch的手机上,重压之后会全面显示;另外,我们也可以添加交互式通知,进一步提高用户体验

    文件大小

    UNNotificationationAttachment

    通知的附近,我们可以在附近中添加图片、音频或视频。

    添加图片

    	UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
        
        NSString *imageFile = [[NSBundle mainBundle] pathForResource:@"sport" ofType:@"png"];
        UNNotificationAttachment *imageAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"imageAttachment" URL:[NSURL fileURLWithPath:imageFile] options:nil error:nil];
        NSAssert(imageAttachment != nil, @"imageAttach 不能为空");
        noticeContent.attachments = @[imageAttachment];
    

    添加视频

    	UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
        
        NSString *movieFile = [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"mp4"];
        UNNotificationAttachment *movieAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"movieAttachment" URL:[NSURL fileURLWithPath:movieFile] options:nil error:nil];
        NSAssert(movieAttachment != nil, @"movieAttach 不能为空");
        noticeContent.attachments = @[movieAttachment];
    

    添加交互式通知

    添加交互式通知

    	UNMutableNotificationContent *noticeContent = [[UNMutableNotificationContent alloc] init];
        
        // 文字action
        UNTextInputNotificationAction *action1 = [UNTextInputNotificationAction actionWithIdentifier:@"replyAction" title:@"文字回复" options:UNNotificationActionOptionNone];
        // 进入应用action
        UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"enterAction" title:@"进入应用" options:UNNotificationActionOptionForeground];
        // 取消action
        UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"cancelAction" title:@"取消" options:UNNotificationActionOptionDestructive];
        
        UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"Categroy" actions:@[action1, action2, action3] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
        
        [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:category]];
        
        noticeContent.categoryIdentifier = @"Categroy";
    

    获取交互动作

    	- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
    {
        NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;
        
        if ([categoryIdentifier isEqualToString:@"Categroy"]) {
            if ([response.actionIdentifier isEqualToString:@"replyAction"]) {
                UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse*)response;
                
                NSString *userText = textResponse.userText;
                
                NSLog(@"您输入的内容:%@", userText);
                
            } else if ([response.actionIdentifier isEqualToString:@"enterAction"]) {
                NSLog(@"点击进入了应用");
            } else {
                NSLog(@"点击了取消");
            }
        }
        
        completionHandler();
    }
    

    iOS 10把接收通知的方法做了统一,不再区分接收本地和远程的通知,只分前台和后台时受到的通知。

    接收通知的步骤:

    1.设置通知的代理,一般设置在AppDelegate

    [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];

    2.实现代理方法

    	// 应用在前台收到通知的处理方法
    	- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
    	
    	// 应用在后台收到通知的处理方法
    	- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
    

    自定义通知样式

    iOS 10可以设置通知的UI样式,更加方便给用户定制化。必须用iPhone7或iPhone7 Plus,iPhone6s及以下硬件,即使升级到iOS 10也无法显示自定义通知的样式

    1.创建自定义通知UI文件,在XcodeFile->New->Targe会出现下面的视图

    图1

    其中,与通知相关的扩展有两个:Notification ContentNotification Service Extension,前者是自定义通知的类型,后者是我们收到远程通知后,在展示之前对通知的修改。所以,我们采用前者

    2.修改通知视图的控制器,自定义通知样式

    • NotificationViewController文件:

    - (void)didReceiveNotification:(UNNotification *)notification可以设置UI显示的数据

    • MainInterface.storyboard文件

    我们可以通过这个storyboard来具体定制通知的样式

    3.应用自定义通知样式

    修改NotificationViewControllerinfo.plist文件

    图2

    • UNNotificationExtensionCategory

    UNNotificationCategory的标识,需要设置为我们的通知的标识

    • UNNotificationExtensionInitialContentSizeRatio

    通知内容显示的比例大小,默认为1

    • UNNotificationExtensionDefaultContentHidden

    是否隐藏默认通知,设置为YES后,默认通知会隐藏

    移除通知

    [[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[@"requestIdentifier"]];
    

    至此,iOS 10本地通知已经解析完毕,下一篇是远程通知,......

    实例项目

    https://github.com/BirdandLion/UNNotificationDemo.git

    参考资料

    https://developer.apple.com/reference/usernotifications

    https://onevcat.com/2016/08/notification/

    http://www.jianshu.com/p/5713fa2bfece

  • 相关阅读:
    简单小过一个crc
    BUUCTF-RE-babymips
    为IDA插件findcrypt添加更多规则
    2020网鼎杯第一场青龙组re部分wp
    HexionCTF2020 部分wp
    TGhack2020 re&misc
    java反射总结
    BUUCTF-RE-CrackMe
    青年大学习直接出图片的软件出了bug,用frida干他
    小玩具Teensy
  • 原文地址:https://www.cnblogs.com/fishbay/p/7206827.html
Copyright © 2011-2022 走看看