优秀是一种习惯
iOS10.0发布已经有一段时间了,一直没有系统的学习总结新的变化,只是去了解了一下,最近有时间就深入的了解一下,网上的文章有很多但并不是自己的所以自己写了一下
前言
为什么是[通知]而不是[推送]
先来看一下iOS10通知相关的第一个更新点就是新加了一个框架User Notification Framework,从字面翻译来看应该翻译成“用户通知框架”,而通常大家所了解的“推送”翻译成英文应该是“Push”,“Push”其实只是[通知]触发的一种方式,而[通知]其实是操作系统层面的一种UI展示。
在苹果的官方文档中Notification分为两类:
Remote(远程,也就是之前所说的Push的方式)
Local(本地,通知由本地的事件触发,iOS10中有三种不同的触发‘Trigger’方式,稍后会进行详细说明)
所以,[推送]只是[通知]的一种触发方式
从iOS迭代更新的历史特征中看,[通知]应该是是被苹果作为一个重点内容来延展的。(从最初的单纯展示和简单回调,到Backgroud的支持,再后来整体的Payload的长度由256字节扩展到2K再到4K,再看这次的独立框架还有丰富的特性更新)
来看一下更新的地方
由User Notification Framework 整合通知相关方法看特性变化
通知相关的方法由之前一直存在在UIKit Framework中到独立出来,官方确实做了很多,但是也尽量做到让开发者可以平滑的过度。
原文:
1. Familiar API with feature parity
2. Expanded content
3. Same code path for local and remote notification handling
4. Simplified delegate methods
5. Better notification management
6. In-app presentation option
7. Schedule and handle notifications in extensions
8. Notification Extensions
释义:
1. 相同的特性使用类似的API(之前的功能API使用方法类似但是还是稍有改变)
2. 内容扩展(支持附件和展示更多内容)
3. 本地通知和远程通知操作代码在相同调用路径(合并代理方法)
4. 简化代理方法
5. 更好的通知管理(支持通知查、改、删;增强本地通知管理,增加日历与地理位置事件的触发)
6. 应用内通知展示(之前App在前台的情况下收到通知不会UI展示)
7. 在Extensions中规划和操作通知(使更新通知内容和删除误发或过期的通知内容成为可能,另一个重要场景为端到端加密)
8. 引入通知Extensions
首先我们看一下之前的本地通知是什么样的?
//发送本地推送
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date];//本次开启立即执行的周期
notification.repeatInterval = kCFCalendarUnitDay;//循环通知的周期
notification.alertAction = @"签到提醒";
notification.alertBody = @"签到";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
// iOS8到iOS9后,需要添加这个注册,才能得到授权
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationType type = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
//发送通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
iOS9.0之前的交互通知
/*
identifier:行为标识符,用于调用代理方法时识别是哪种行为。
title:行为名称。
UIUserNotificationActivationMode:即行为是否打开APP。
authenticationRequired:是否需要解锁。
destructive:这个决定按钮显示颜色,YES的话按钮会是红色。
behavior:点击按钮文字输入,是否弹出键盘
*/
UIMutableUserNotificationAction * action1 = [[UIMutableUserNotificationAction alloc] init];
action1.identifier = @"action1";
action1.title=@"策略1行为1";
action1.activationMode = UIUserNotificationActivationModeForeground;
action1.destructive = YES;
UIMutableUserNotificationAction * action2 = [[UIMutableUserNotificationAction alloc] init];
action2.identifier = @"action2";
action2.title=@"策略1行为2";
action2.activationMode = UIUserNotificationActivationModeBackground;
action2.authenticationRequired = NO;
action2.destructive = NO;
action2.behavior = UIUserNotificationActionBehaviorTextInput;//点击按钮文字输入,是否弹出键盘
UIMutableUserNotificationCategory * category1 = [[UIMutableUserNotificationCategory alloc] init];
category1.identifier = @"Category1";
[category1 setActions:@[action2,action1] forContext:(UIUserNotificationActionContextDefault)];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:[NSSet setWithObjects: category1, nil]];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
self.notification.fireDate=[NSDate dateWithTimeIntervalSinceNow:5];
self.notification.timeZone=[NSTimeZone defaultTimeZone];
self.notification.alertBody=@"测试推送的快捷回复";
self.notification.category = @"Category1";
[[UIApplication sharedApplication] scheduleLocalNotification:self.notification];
//解除本地推送
- (void)removeUILocalNotification:(NSString *)notifation userkey:(NSString*)key
{
// 获得 UIApplication
UIApplication *app = [UIApplication sharedApplication];
//获取本地推送数组
NSArray *localArray = [app scheduledLocalNotifications];
//声明本地通知对象
UILocalNotification *localNotification;
if (localArray) {
for (UILocalNotification *noti in localArray) {
NSDictionary *dict = noti.userInfo;
if (dict) {
NSString *inKey = [dict objectForKey:notifation];
if ([inKey isEqualToString:key]) {
if (localNotification){
localNotification = nil;
}
localNotification = noti;
break;
}
}
}
//判断是否找到已经存在的相同key的推送
if (!localNotification) {
//不存在初始化
localNotification = [[UILocalNotification alloc] init];
}
if (localNotification) {
//不推送 取消推送
[app cancelLocalNotification:localNotification];
return;
}
}
}
下面我们看一下iOS10.0通知的变化
UNMutableNotificationContent * content = [[UNMutableNotificationContent alloc] init];
//引入代理
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
content.title = @"iOS10通知";
content.subtitle = @"新通知学习笔记";
content.body = @"新通知变化很大,之前本地通知和远程推送是两个类,现在合成一个了。";
content.badge = @1;
// UNNotificationSound *sound = [UNNotificationSound soundNamed:@"caodi.m4a"];
// content.sound = sound;
NSString *imageFile = [[NSBundle mainBundle] pathForResource:@"sport" ofType:@"png"];
UNNotificationAttachment *imageAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"iamgeAttachment" URL:[NSURL fileURLWithPath:imageFile] options:nil error:nil];
content.attachments = @[imageAttachment];
//重复提醒,时间间隔要大于60s
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
NSString *requertIdentifier = @"RequestIdentifier";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requertIdentifier content:content trigger:trigger1];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
NSLog(@"Error:%@",error);
}];
UNTextInputNotificationAction *action1 = [UNTextInputNotificationAction actionWithIdentifier:@"replyAction" title:@"文字回复" options:UNNotificationActionOptionNone];
UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"enterAction" title:@"进入应用" options:UNNotificationActionOptionForeground];
UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"cancelAction" title:@"取消" options:UNNotificationActionOptionDestructive];
UNNotificationCategory *categroy = [UNNotificationCategory categoryWithIdentifier:@"Categroy" actions:@[action1,action2,action3] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:categroy]];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
- UNPushNotificationTrigger,远程推送触发器,一般是远程推送推过来的通知带有这类触发器
- UNTimeIntervalNotificationTrigger,时间间隔触发器,定时或者是重复,在本地推送设置中有用
- UNCalendarNotificationTrigger,日历触发器,指定日期进行通知
- UNLocationNotificationTrigger,地理位置触发器,指定触发通知的条件是地理位置CLRegion这个类型。
触发器和内容最后形成UNNotificationRequest,一个通知请求,本地通知的请求,直接交给通知中心进行发送,发送成功后,该通知会按照触发器的触发条件进行触发,并且会显示到通知中心上,用户可与指定的category交互方式与通知进行交互
这里只整理了基础知识,希望起到抛砖引玉的作用