无论使用远程通知或者本地通知,第一步肯定是获取用户权限,进行通知注册:
-(void)setupNotifition:(UIApplication *)application{
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
//iOS10特有
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
// 必须写代理,不然无法监听通知的接收与点击
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge |UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
// 点击允许
NSLog(@"注册成功");
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@", settings);
}];
} else {
// 点击不允许
NSLog(@"注册失败");
}
}];
}else if ([[UIDevice currentDevice].systemVersion floatValue] >8.0){
//iOS8 - iOS10
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:[self addNotiActionCategories]]];;
}else if ([[UIDevice currentDevice].systemVersion floatValue] < 8.0) {
//iOS8系统以下
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert |UIRemoteNotificationTypeSound];
}
// 注册获得device Token
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
触发通知的模式:1. 地理位置的一种通知
CLCircularRegion *circlarRegin = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(30.181484917534721, 120.27360649956597) radius:2000 identifier:@"locationIdentifier"];
UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:circlarRegin repeats:YES];
2.一定日期之后,重复或者不重复推送通知
// 周一早上 8:00 上班
// NSDateComponents *components = [[NSDateComponents alloc] init];
// // 注意,weekday是从周日开始的,如果想设置为从周一开始,大家可以自己想想~
// components.weekday = 2;
// components.hour = 8;
// UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTriggertriggerWithDateMatchingComponents:components repeats:YES];
3.一定时间之后,重复或者不重复推送通知
// UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:30000 repeats:YES];
因为Ios10 通知API发生了大的改动 所以,要做好适配权限。如果是远程通知的话需要打开一个远程PUSH开关:project---》target-------》capabilities------》PUSH notification
2.如果是集成极光推送的话 直接看官方文档 如果是自己服务集成的话;需要把这个token值传给后台:代理方法:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString* dt = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
NSString *token = [dt stringByReplacingOccurrencesOfString:@" " withString:@""];
[ParkUserDefaults setObject:token forKey:@"RemoteNotification_token"];
[ParkUserDefaults synchronize];
if ([ParkUserDefaults objectForKey:user_id]) {
NSString* urlStr = [NSString stringWithFormat:Regis_APNS_User,[OpenUDID value],[ParkUserDefaults objectForKey:user_id],token];
[ZHZ_GCD downloadWithUrlStr:urlStr andCallBack:^(NSData *data, NSError *error) {
if (error) {
LogPark(@"%@",error);
}else{
LogPark(@"发送成功");
}
}];
}
}
3.当然你必须要遵守一个代理
#import
#endif
为了适配8.0或者7.0之后的版本 你需要除了这两个方法执行之外 还需要吧原先的代理方法执行一遍。
#pragma mark-iOS10 通知代理方法-
//iOS10 前台收到通知的的方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
NSDictionary * userInfo = notification.request.content.userInfo;
UNNotificationRequest *request = notification.request; // 收到推送的请求
UNNotificationContent *content = request.content; // 收到推送的消息内容
NSNumber *badge = content.badge; // 推送消息的角标
NSString *body = content.body; // 推送消息体
UNNotificationSound *sound = content.sound; // 推送消息的声音
NSString *subtitle = content.subtitle; // 推送消息的副标题
NSString *title = content.title; // 推送消息的标题
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// [self logDic:userInfo];
}
else {
// 判断为本地通知
NSLog(@"iOS10 前台收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
}
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
// 后台通知的点击事件
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
NSDictionary *userInfo = response.notification.request.content.userInfo;
UNNotificationRequest *request = response.notification.request; // 收到推送的请求
UNNotificationContent *content = request.content; // 收到推送的消息内容
NSNumber *badge = content.badge; // 推送消息的角标
NSString *body = content.body; // 推送消息体
UNNotificationSound *sound = content.sound; // 推送消息的声音
NSString *subtitle = content.subtitle; // 推送消息的副标题
NSString *title = content.title; // 推送消息的标题
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
// [self logDic:userInfo];
}
else {
// 判断为本地通知
NSLog(@"iOS10 收到本地通知:{\\\\nbody:%@,\\\\ntitle:%@,\\\\nsubtitle:%@,\\\\nbadge:%@,\\\\nsound:%@,\\\\nuserInfo:%@\\\\n}",body,title,subtitle,badge,sound,userInfo);
}
// Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
completionHandler(); // 系统要求执行这个方法
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"iOS7及以上系统,收到通知:%@",userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
最后一点:如果是在程序被kill的情况下点击通知方法:需要在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
这个方法里面进行这个值得判断,
//远程通知
NSDictionary* pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
//本地通知
NSDictionary *localNotifitionkey = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (pushNotificationKey) {
//远程通知
}else if (localNotifitionkey){
//本地通知
}
4.这就是远程通知的大概使用方法 能满足大部分要求。
本地通知:详解
(1.)完成注册通知之后,如果想发送本地通知:
-(void)createNotifition{
// 1.创建通知内容
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"约停车测试通知";
content.subtitle = @"测试通知";
content.body = @"位置到达某个位置通知";
content.badge = @1;
content.categoryIdentifier = @"my_category";
NSError *error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:@"1" 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 = @"location_g";
// 2.设置声音
UNNotificationSound *sound = [UNNotificationSound defaultSound];
content.sound = sound;
// 3.触发模式
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:70 repeats:YES];
// 4.设置UNNotificationRequest
NSString *requestIdentifer = @"TestRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifer content:content trigger:trigger];
//5.把通知加到UNUserNotificationCenter, 到指定触发点会被触发
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
}
(1.1)首先创建通知内容,可变和不可变,
(1.2)再者是创建附件内容,这一块有个坑就是在创建附件内容的时候在小屏手机上面显示不出来,注:即使是添加的notificationaction也是默认显示两个的,6 7p亲测可使的。
(1.3)然后就是把通知加到到系统的通知中心了!
(2)添加action
/*
UNNotificationActionOptionAuthenticationRequired = (1 << 0),
UNNotificationActionOptionDestructive = (1 << 1), 取消
UNNotificationActionOptionForeground = (1 << 2), 启动程序
*/
UNTextInputNotificationAction *textAction = [UNTextInputNotificationAction actionWithIdentifier:@"my_text" title:@"文本输入" options:UNNotificationActionOptionAuthenticationRequired textInputButtonTitle:@"输入" textInputPlaceholder:@"默认文字"];
UNNotificationAction *action = [UNNotificationAction actionWithIdentifier:@"my_action" title:@"测试1" options:UNNotificationActionOptionNone];
UNNotificationAction *action_1 = [UNNotificationAction actionWithIdentifier:@"my_action_1" title:@"测试2" options:UNNotificationActionOptionNone];
/*
UNNotificationCategoryOptionNone = (0),
UNNotificationCategoryOptionCustomDismissAction = (1 << 0),
UNNotificationCategoryOptionAllowInCarPlay = (2 << 0),
*/
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"my_category" actions:@[textAction,action,action_1] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *setting = [NSSet setWithObjects:category, nil];
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:setting];
(3)处理相应事件:
#pragma mark 当应用未在前台,收到本地通知后,左划通知,显示按钮对应的点击动作处理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler {
if ([identifier isEqualToString:@"TestRequest"]) {
NSLog(@"You chose TestRequest");
}
else if ([identifier isEqualToString:@"my_text"]) {
NSLog(@"You chose my_text.");
}else if ([identifier isEqualToString:@"my_action_1"]){
NSLog(@"You chose my_action_1.");
}else if ([identifier isEqualToString:@"my_action"]){
NSLog(@"You chose my_action.");
}
if (completionHandler) {
completionHandler();
}
}
#pragma mark 当应用未在前台,收到远程通知后,左划通知 通知滑动后的动作选项处理接口
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
if ([identifier isEqualToString:@"TestRequest"]) {
NSLog(@"You chose TestRequest");
}
else if ([identifier isEqualToString:@"my_text"]) {
NSLog(@"You chose my_text.");
}else if ([identifier isEqualToString:@"my_action_1"]){
NSLog(@"You chose my_action_1.");
}else if ([identifier isEqualToString:@"my_action"]){
NSLog(@"You chose my_action.");
}
if (completionHandler) {
completionHandler();
}
}