代码改变世界

iOS 10.0以前以及以后本地通知注册实现方法

2018-07-27 11:50  菜鸟Alex  阅读(2047)  评论(0编辑  收藏  举报

以下是iOS8~iOS10注册本地通知方式

  • iOS8-10注册本地通知方式一样
  • 以下我在程序启动注册本地通知,iOS8模拟器上
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    // 判断系统版本号是否小于10.0
    NSString *version = [UIDevice currentDevice].systemVersion;
    if (version.doubleValue < 10.0) {
        // 参数5是触发时间单位秒
        [self registerLocalNotification:5];
    }else{
//        [self regisNoti];
    }
    
    return YES;
}

// 注册通知具体方法
- (void)registerLocalNotification:(NSInteger)alertTime {
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    // 设置触发通知的时间
    NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:alertTime];
    NSLog(@"fireDate=%@",fireDate);
    
    notification.fireDate = fireDate;
    // 时区
    notification.timeZone = [NSTimeZone defaultTimeZone];
    // 设置重复的间隔
    notification.repeatInterval = kCFCalendarUnitSecond;
    
    // 通知内容
    notification.alertBody =  @"该起床了...";
    notification.applicationIconBadgeNumber = 1;
    // 通知被触发时播放的声音
    notification.soundName = UILocalNotificationDefaultSoundName;
    // 通知参数
    NSDictionary *userDict = [NSDictionary dictionaryWithObject:@"开始学习iOS开发了" forKey:@"key"];
    notification.userInfo = userDict;
    
    // ios8后,需要添加这个注册,才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
                                                                                 categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        // 通知重复提示的单位,可以是天、周、月
        notification.repeatInterval = NSCalendarUnitDay;
    } else {
        // 通知重复提示的单位,可以是天、周、月
        notification.repeatInterval = NSCalendarUnitDay;
    }
    
    // 执行通知注册
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

  • - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { NSLog(@"noti:%@",notification) 此方法是在程序在前台接收到本地通知,或者在后台接收到通知并点击通知横幅会调用

#pragma mark - 本地通知回调
// 本地通知回调函数,当应用程序在前台接收到通知,或者后台点击通知调用
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    NSLog(@"noti:%@",notification);
    
    // 这里真实需要处理交互的地方
    // 获取通知所带的数据
    NSString *notMess = [notification.userInfo objectForKey:@"key"];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"本地通知(前台)"
                                                    message:notMess
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
    
    // 更新显示的badge个数
    NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badge--;
    badge = badge >= 0 ? badge : 0;
    [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
    
    // 在不需要再推送时,可以取消某一个推送(或者可以取消全部本地通知)
    [self cancelLocalNotificationWithKey:@"key"];
}



// 判断程序是在前台还是后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    //进入后台
    NSLog(@"后台");
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // app启动或者app从后台进入前台都会调用这个方法
    NSLog(@"前台");
    // 更新显示的badge个数,每次进入我都设置为0
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}



#pragma mark - 取消某个(或者全部)本地推送通知
- (void)cancelLocalNotificationWithKey:(NSString *)key {
    // 获取所有本地通知数组
    NSArray *localNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
    
    for (UILocalNotification *notification in localNotifications) {
        NSDictionary *userInfo = notification.userInfo;
        if (userInfo) {
            // 根据设置通知参数时指定的key来获取通知参数
            NSString *info = userInfo[key];
            
            // 如果找到需要取消的通知,则取消
            if (info != nil) {
                [[UIApplication sharedApplication] cancelLocalNotification:notification];
                // 取消所有本地通知
//                [[UIApplication sharedApplication] cancelAllLocalNotifications];
                break;
            }
        }
    }
}


以下是iOS10以后注册本地通知

  • 注册通知方法,另外需要设置代理 UNUserNotificationCenterDelegate以及导入头文件#import <UserNotifications/UserNotifications.h>

#pragma mark - iOS 10以上设置通知
-(void)regisNoti{
    // 使用 UNUserNotificationCenter 来管理通知
    if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        //监听回调事件
        center.delegate = self;
        //iOS 10 使用以下方法注册,才能得到授权,注册通知以后,会自动注册 deviceToken,如果获取不到 deviceToken,Xcode8下要注意开启 Capability->Push Notification。
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
                                  completionHandler:^(BOOL granted, NSError * _Nullable error) {
                                      // Enable or disable features based on authorization.
                                  }];
        //获取当前的通知设置,UNNotificationSettings 是只读对象,不能直接修改,只能通过以下方法获取
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        }];
        [self pushLocalNotifactionWithFireTime:5];
    }
}

// 发送通知具体方法
-(void)pushLocalNotifactionWithFireTime:(NSInteger)alerTime{
    // 使用 UNUserNotificationCenter 来管理通知
    if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
        //需创建一个包含待通知内容的 UNMutableNotificationContent 对象,注意不是 UNNotificationContent ,此对象为不可变对象。
        UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
        content.title = [NSString localizedUserNotificationStringForKey:@"Hello!" arguments:nil];
        content.body = [NSString localizedUserNotificationStringForKey:@"Hello_message_body"
                                                             arguments:nil];
        content.sound = [UNNotificationSound defaultSound];
        content.userInfo = @{
                             @"a":@"v",
                             @"c":@"d",
                             };
        // 在 alertTime 后推送本地推送
        UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
                                                      triggerWithTimeInterval:alerTime repeats:NO];
        
        UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"FiveSecond"
                                                                              content:content trigger:trigger];
        [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
            
        }];
        
    }
}

  • 实现iOS10本地通知代理方法
  • 与iOS8不同的是,iOS10本地通知在前台与在后台触发通知调用的代理方法不一样如下:


#pragma mark - delegate iOS10

// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
// 前台调用
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0){
    NSLog(@"1--title---%@", notification.request.content.title);
    NSLog(@"2--subtitle---%@", notification.request.content.subtitle);
    NSLog(@"3--userInfo---%@", notification.request.content.userInfo);
    NSLog(@"4--body---%@", notification.request.content.body);
}

// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
// 后台点击通知后调用
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED{
    NSLog(@"7--title---%@", response.notification.request.content.title);
    NSLog(@"8--subtitle---%@", response.notification.request.content.subtitle);
    NSLog(@"9--userInfo---%@", response.notification.request.content.userInfo);
    NSLog(@"10--body---%@", response.notification.request.content.body);
}