远程推送
添加新的框架 UserNotifications.framework
#import <UserNotifications/UserNotifications.h>
#pragma mark 注册推送
-(void)registerPushServer
{
if (IOS10) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
//点击允许
NSLog(@"注册通知成功");
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@", settings);
}];
} else {
//点击不允许
NSLog(@"注册通知失败");
}
}];
//注册推送(同iOS8)
[[UIApplication sharedApplication] registerForRemoteNotifications];
}else if (IOS8_TO_10){//iOS8到iOS10
//1.创建消息上面要添加的动作(按钮的形式显示出来)
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
action.identifier = @"action";//按钮的标示
action.title=@"Accept";//按钮的标题
action.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
// action.authenticationRequired = YES;
// action.destructive = YES;
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
action2.identifier = @"action2";
action2.title=@"Reject";
action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
action.authenticationRequired = YES;//需要解锁才能处理,如果action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
action.destructive = YES;
//2.创建动作(按钮)的类别集合
UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init];
categorys.identifier = @"alert";//这组动作的唯一标示,推送通知的时候也是根据这个来区分
[categorys setActions:@[action,action2] forContext:(UIUserNotificationActionContextMinimal)];
//3.创建UIUserNotificationSettings,并设置消息的显示类类型
UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:[NSSet setWithObjects:categorys, nil nil]];//categories设置为nil则推送无动作
//会执行代理函数- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
// 获取type
// UIUserNotificationSettings *settings = [application currentUserNotificationSettings];
// UIUserNotificationType types = [settings types];
[application registerForRemoteNotifications];
} else {//iOS8以下
[application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
}
}
获取deviceToken
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
//转换为设备字符串
NSString *deviceTokenStr=[NSString stringWithFormat:@"%@",deviceToken];
deviceTokenStr=[deviceTokenStr stringByReplacingOccurrencesOfRegex:@"[<>\\s]" withString:@""];
//操作deviceToken
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"register RemoteNotifications fail:%@",[error localizedDescription]);
}
<UNUserNotificationCenterDelegate>
iOS10收到通知不再是在application: didReceiveRemoteNotification:方法去处理
推出新的代理方法,接收和处理各类通知(本地或者远程)
#pragma mark - iOS10 推送代理
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
//应用在前台收到通知
NSLog(@"========%@", notification);
//如果需要在应用在前台也展示通知
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
//点击通知进入应用
NSLog(@"response:%@", response);
}
#pragma mark - iOS8_10推送代理
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
if ([identifier isEqualToString:@"XXX"]) {
}
completionHandler();
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler
{
}
//点击本地推送
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
}
//点击远程推送
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
}
设置处理通知的action 和 category
在iOS8以前是没有category这个属性的;
在iOS8注册推送,获取授权的时候,可以一并设置category, 注册的方法直接带有这个参数;(见推送注册)
在iOS10,需要调用一个方法setNotificationCategories:来为管理推送的UNUserNotificationCenter实例设置category, category又可以对应设置action;
//设置category
//UNNotificationActionOptionAuthenticationRequired 需要解锁
//UNNotificationActionOptionDestructive 显示为红色
//UNNotificationActionOptionForeground 点击打开app
UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"action1" title:@"策略1行为1" options:UNNotificationActionOptionForeground];
UNTextInputNotificationAction *action2 = [UNTextInputNotificationAction actionWithIdentifier:@"action2" title:@"策略1行为2" options:UNNotificationActionOptionDestructive textInputButtonTitle:@"comment" textInputPlaceholder:@"reply"];
//UNNotificationCategoryOptionNone
//UNNotificationCategoryOptionCustomDismissAction 清除通知被触发会走通知的代理方法
//UNNotificationCategoryOptionAllowInCarPlay 适用于行车模式
UNNotificationCategory *category1 = [UNNotificationCategory categoryWithIdentifier:@"category1" actions:@[action2,action1] minimalActions:@[action2,action1] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"action3" title:@"策略2行为1" options:UNNotificationActionOptionForeground];
UNNotificationAction *action4 = [UNNotificationAction actionWithIdentifier:@"action4" title:@"策略2行为2" options:UNNotificationActionOptionForeground];
UNNotificationCategory *category2 = [UNNotificationCategory categoryWithIdentifier:@"category2" actions:@[action3,action4] minimalActions:@[action3,action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:category1,category2, nil]];
设置通知内容
iOS10远程通知与本地通知统一起来了,通知内容属性是一致的,远程推送需要在payload进行设置
官网上明确说明了,我们是不能直接创建UNNotificationContent的实例的,我们需要用到UNMutableNotificationContent
attachments //附件
badge //徽标
body //推送内容body
categoryIdentifier //category标识
launchImageName //点击通知进入应用的启动图
sound //声音
subtitle //推送内容子标题
title //推送内容标题
userInfo //远程通知内容
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"Test";
content.subtitle = @"1234567890";
content.body = @"Copyright © 2016年 jpush. All rights reserved.";
content.badge = @1;
NSError *error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:@"718835727" ofType:@"png"];
UNNotificationAttachment *att = [UNNotificationAttachment attachmentWithIdentifier:@"att1" URL:[NSURL fileURLWithPath:path] options:nil error:&error];
if (error) {
NSLog(@"attachment error %@", error);
}
content.attachments = @[att];
content.categoryIdentifier = @"category1"; //这里设置category1, 是与之前设置的category对应
content.launchImageName = @"1-Eb_0OvtcxJXHZ7-IOoBsaQ";
UNNotificationSound *sound = [UNNotificationSound defaultSound];
content.sound = sound;
通知触发器
UNNotificationTrigger iOS10 触发器有4种
UNPushNotificationTrigger 触发APNS服务,系统自动设置(这是区分本地通知和远程通知的标识)UNTimeIntervalNotificationTrigger 一段时间后触发
UNCalendarNotificationTrigger 指定日期触发
UNLocationNotificationTrigger 根据位置触发,支持进入某地或者离开某地或者都有
//十秒后
UNTimeIntervalNotificationTrigger *trigger1 =[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:10 repeats:NO];
//每周日早上8:00
NSDateComponents *component = [[NSDateComponents alloc] init];
component.weekday = 1;
UNCalendarNotificationTrigger *trigger2 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:component repeats:YES];
//圆形区域,进入时候进行通知
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:cen radius:500.0 identifier:@“center"];
region.notifyOnEntry = YES; //进入的时候
region.notifyOnExit = NO; //出去的时候
UNLocationNotificationTrigger *trigger3 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
添加通知 / 更新通知
1.创建一个UNNotificationRequest类的实例,一定要为它设置identifier(不能是空字符串@”“), 在后面的查找,更新, 删除通知,这个标识是可以用来区分这个通知与其他通知
2.把request加到UNUserNotificationCenter, 并设置触发器,等待触发
如果另一个request具有和之前request相同的标识,不同的内容, 可以达到更新通知的目的
NSString *requestIdentifer = @"TestRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger1];
//把通知加到UNUserNotificationCenter, 到指定触发点会被触发
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
//在另外需要更新通知的地方
UNMutableNotificationContent *newContent = [[UNMutableNotificationContent alloc] init];
newContent.title = @"Update";
newContent.subtitle = @"XXXXXXXXX";
newContent.body = @"Copyright © 2016年 jpush. All rights reserved.";
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3 repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"TestRequest" content:newContent trigger:trigger1];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
获取和删除通知
- Pending 等待触发的通知
- Delivered 已经触发展示在通知中心的通知
//获取未触发的通知
[[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
NSLog(@"pending: %@", requests);
}];
//获取通知中心列表的通知
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSLog(@"Delivered: %@", notifications);
}];
//清除某一个未触发的通知
[[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[@"TestRequest1"]];
//清除某一个通知中心的通知
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[@"TestRequest2"]];
//对应的删除所有通知
[[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
[[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
本地推送
#pragma mark 初始化本地通知
-(void)initLocalNotification
{
if (IOS10) {
//对应的删除所有通知
[[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
[[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
if ([[_facade getSendNewsProxy] isExistFailueNews])
{
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.body = NSLocalizedString(@"NEWS_CENTER_FAILNEWS", @"你有一条动态发送失败");
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"TestRequest" content:content trigger:nil];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
}
UNMutableNotificationContent * notifC = [[UNMutableNotificationContent alloc] init];
notifC.body = NSLocalizedString(@"COMMON_THREE_DAYS_NOT_LOGINED",@"你10秒没点击我了!");
//3天不登录则进行提醒
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3 repeats:NO];
UNNotificationRequest *request1 = [UNNotificationRequest requestWithIdentifier:@"TestRequest1" content:notifC trigger:trigger1];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request1 withCompletionHandler:^(NSError * _Nullable error) {
}];
}else {
//取消所有之前的本地通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
if ([[_facade getSendNewsProxy] isExistFailueNews])
{
UILocalNotification *localNoti = [[UILocalNotification alloc] init];
if (localNoti)
{
localNoti.alertBody = NSLocalizedString(@"NEWS_CENTER_FAILNEWS", @"你有一条动态发送失败");
[[UIApplication sharedApplication] scheduleLocalNotification:localNoti];
}
}
UILocalNotification *localNotif=[[UILocalNotification alloc] init];
if (localNotif)
{
//3天不登录则进行提醒
localNotif.fireDate=[[NSDate date] dateByAddingTimeInterval:3600*24*3];
localNotif.timeZone=[NSTimeZone defaultTimeZone];
localNotif.alertBody=NSLocalizedString(@"COMMON_THREE_DAYS_NOT_LOGINED",@"你10秒没点击我了!");
localNotif.applicationIconBadgeNumber++;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
}
}