iOS本地通知(基于时间)

  • 工程结构


    iOS本地通知(基于时间)_第1张图片
    Snip20180302_4.png
  • 将本地通知的 identifier 的.h文件设置在pch文件中(pch文件设置方法)
    PrefixHeader.pch
#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#import "UINotification.h"

#endif /* PrefixHeader_pch */

UINotification.h

#ifndef UINotification_h
#define UINotification_h
//=================== 通知 identifier ===================
//第一种
#define UIUserNotificationCategoryIdentifier_1 @"UIUserNotificationCategoryIdentifier_1"
#define UIUserNotificationActionIdentifier_1_1 @"UIUserNotificationActionIdentifier_1_1"
#define UIUserNotificationActionIdentifier_1_2 @"UIUserNotificationActionIdentifier_1_2"
//第二种
#define UIUserNotificationCategoryIdentifier_2 @"UIUserNotificationCategoryIdentifier_2"
#define UIUserNotificationActionIdentifier_2_1 @"UIUserNotificationActionIdentifier_2_1"
//UIUserLocalNotification 的 Userinfo 字典的 key
#define LMLocalNotificationKey @"LMLocalNotificationKey"
//点击通知跳转的界面
#define UIUserNotificationClickKey @"UIUserNotificationClickKey"
#define UIUserNotificationClickValue @"UIUserNotificationClickValue"
#endif /* UINotification_h */
  • 本地通知处理代码
#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

/**
 如果点击弹出的通知时,应用不在运行(被杀掉了),会走这个方法,通知的跳转需要在这个方法中跳转
 */
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //=================== 通知相关 ===================
    //=================== 1.通知的权限类型 ===================
    /**
     UIUserNotificationTypeNone    = 0,      // the application may not present any UI upon a notification being received
     UIUserNotificationTypeBadge   = 1 << 0, // the application may badge its icon upon a notification being received
     UIUserNotificationTypeSound   = 1 << 1, // the application may play a sound upon a notification being received
     UIUserNotificationTypeAlert   = 1 << 2, // the application may display an alert upon a notification being received
     */
    //=================== 2.通知的呈现类型 ===================
    UIMutableUserNotificationCategory *category_1 = [[UIMutableUserNotificationCategory alloc]init];
    category_1.identifier = UIUserNotificationCategoryIdentifier_1;
    UIMutableUserNotificationAction *action_1_1 = [[UIMutableUserNotificationAction alloc]init];
    action_1_1.identifier = UIUserNotificationActionIdentifier_1_1;
    action_1_1.title = @"今天去面试";
    /**
     UIUserNotificationActivationModeForeground, // activates the application in the foreground
     UIUserNotificationActivationModeBackground  // activates the application in the background, unless it's already
     */
    action_1_1.activationMode = UIUserNotificationActivationModeForeground;
    UIMutableUserNotificationAction *action_1_2 = [[UIMutableUserNotificationAction alloc]init];
    action_1_2.identifier = UIUserNotificationActionIdentifier_1_2;
    action_1_2.title = @"今天不想去面试";
    /**
     UIUserNotificationActivationModeForeground, // activates the application in the foreground
     UIUserNotificationActivationModeBackground  // activates the application in the background, unless it's already
     */
    action_1_2.activationMode = UIUserNotificationActivationModeBackground;
    /**
     UIUserNotificationActionContextDefault,  // the default context of a notification action
     UIUserNotificationActionContextMinimal   // the context of a notification action when space is limited
     */
    [category_1 setActions:@[action_1_1, action_1_2] forContext:UIUserNotificationActionContextDefault];
    
    NSMutableSet *categorySet = [NSMutableSet set];
    [categorySet addObject:category_1];
    
    UIUserNotificationSettings *userNotificationSetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:categorySet];
    [application registerUserNotificationSettings:userNotificationSetting];
    
    //=================== 如果应用是点击通知而启动的,则需要处理通知跳转的 action ===================
    /**
     多种方式拿到 keyWindow
     1.UIViewController -> view -> window
     2.UIApplication -> keyWindow
     3.AppDelegate -> window
     */
    NSLog(@"self.window = %@, application.keyWindow = %@", self.window, application.keyWindow);
    //根据 launchOptions 字典的 value 判断是如何启动程序的,从而判断是否需要跳转
    UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotification) {
        
        //localNotification 有值则是点击本地通知来启动程序的
        //跳转
        /**
         注意:UIApplication 下的 keyWindow
         This property holds the UIWindow object in the windows array that is most recently sent the makeKeyAndVisible message.
         keyWindow 在使用了 makeKeyAndVisible 这个方法后才有值,所以
         1.纯代码情况下:
            * 需要在执行 [self.window makeKeyAndVisible]; kwyWindow 之后才有值
         2.使用 UIStoryboard 情况下
            * 系统在当前方法走完之后才会自动调用 makeKeyAndVisible 这个方法,所以此时 UIApplication 下的 keyWindow 值为空,需要使用第三种方法拿到 kwyWindow
         */
        UITabBarController *tabBarC = (UITabBarController *)self.window.rootViewController;
        tabBarC.selectedIndex = 2;
    }
    
    return YES;
}
/**
 注册通知结果
 */
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    if (notificationSettings.types == (UIUserNotificationTypeSound|UIUserNotificationTypeBadge|UIUserNotificationTypeAlert)) {
        NSLog(@"成功获取到了用户的通知权限");
        return;
    }
    if ((notificationSettings.types & UIUserNotificationTypeSound) == 0) {
        NSLog(@"用户没有打开通知提示音权限");
    }
    if ((notificationSettings.types & UIUserNotificationTypeBadge) == 0) {
        NSLog(@"用户没有打开通知 badge 权限");
    }
    if ((notificationSettings.types & UIUserNotificationTypeAlert) == 0) {
        NSLog(@"用户没有打开通知 alert 权限");
    }
}
/**
 本地通知 点击了 category 上的 action 触发 iOS 8.0~10.0
 */
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
    NSLog(@"currentFunction ----------> %s", __FUNCTION__);
    NSLog(@"identifier = %@, notification = %@, ", identifier, notification);
    if ([identifier isEqualToString:UIUserNotificationActionIdentifier_1_1]) {
        NSLog(@"去面试");
        UITabBarController *tabBarC = (UITabBarController *)application.keyWindow.rootViewController;
        tabBarC.selectedIndex = 1;
    } else if ([identifier isEqualToString:UIUserNotificationActionIdentifier_1_2]) {
        NSLog(@"不想去面试");
    }
    //completionHandler 这个 block 需要处理完之后手动调用,不然控制台会报警告
    completionHandler();
}
/**
 本地通知 点击了 category 上的 action 触发 iOS 9.0~10.0
 */
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
    NSLog(@"currentFunction ----------> %s", __FUNCTION__);
    NSLog(@"identifier = %@, notification = %@, responseInfo = %@", identifier, notification, responseInfo);
    
    if ([identifier isEqualToString:UIUserNotificationActionIdentifier_1_1]) {
        NSLog(@"去面试");
        UITabBarController *tabBarC = (UITabBarController *)application.keyWindow.rootViewController;
        tabBarC.selectedIndex = 1;
    } else if ([identifier isEqualToString:UIUserNotificationActionIdentifier_1_2]) {
        NSLog(@"不想去面试");
    }
    //completionHandler 这个 block 需要处理完之后手动调用,不然控制台会报警告
    completionHandler();
}
/**
 1.应用处于前台时,通知来临时,会直接触此方法
 2.应用处于后台时,通知来临时,不会直接触此方法,需要用户点击通知后才会触发此方法
 */
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    NSLog(@"currentFunction ----------> %s", __FUNCTION__);
    NSLog(@"通知来了");
    NSLog(@"notification = %@", notification);
    //首先判断应用的激活状态
    if (application.applicationState == UIApplicationStateInactive) {
        //进行跳转
        if ([notification.userInfo[UIUserNotificationClickKey] isEqualToString:UIUserNotificationClickValue]) {
            NSLog(@"跳转");
            UITabBarController *tabBarC = (UITabBarController *)application.keyWindow.rootViewController;
            tabBarC.selectedIndex = 2;
        }
    }
    NSLog(@"界面不跳转");
    
}
@end

ViewController.m

#import "ViewController.h"

NSString * const LMLocalNotificationValue_min = @"min";
NSString * const LMLocalNotificationValue_day = @"day";
@interface ViewController ()
//通知调度池显示
@property (weak, nonatomic) IBOutlet UITextView *notificationShowView;

@end

@implementation ViewController
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [UIApplication sharedApplication].applicationIconBadgeNumber -= 1;
}
/**
 添加每分钟通知
 */
- (IBAction)addNotification:(id)sender {
    NSLog(@"开启本地通知");
    //=================== 本地通知 ===================
    //创建本地通知
    UILocalNotification *localNotification = [[UILocalNotification alloc]init];
    if (@available(iOS 8.2, *)) {
        localNotification.alertTitle = @"每分钟通知:该找工作了";
    }
    localNotification.alertBody = @"现在不找工作什么时候去找工作呢?2018.03.05 去拜拜拿离职证明吧";
    //使用系统提示音
//    localNotification.soundName = UILocalNotificationDefaultSoundName;
    localNotification.soundName = @"RGBLBSYLSN.mp3";
    localNotification.applicationIconBadgeNumber = 1;
    //设置 userinfo
    localNotification.userInfo = @{
                                   LMLocalNotificationKey: LMLocalNotificationValue_min,
                                   UIUserNotificationClickKey: UIUserNotificationClickValue
                                   
                                   };
    localNotification.category = UIUserNotificationCategoryIdentifier_1;
    //设置触发条件
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
    //每隔一分钟触发一次本地通知 间隔至少是分钟,秒会出问题
    localNotification.repeatInterval = NSCalendarUnitMinute;
    //开启本地通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
/**
 添加每天通知
 */
- (IBAction)addDayNotification:(id)sender {
    //=================== 本地通知 ===================
    //创建本地通知
    UILocalNotification *localNotification = [[UILocalNotification alloc]init];
    if (@available(iOS 8.2, *)) {
        localNotification.alertTitle = @"每天通知:该找工作了";
    }
    localNotification.alertBody = @"现在不找工作什么时候去找工作呢?2018.03.05 去拜拜拿离职证明吧";
    //使用系统提示音
    //    localNotification.soundName = UILocalNotificationDefaultSoundName;
    localNotification.soundName = @"BPWLL.mp3";
    localNotification.applicationIconBadgeNumber = 1;
    //设置 userinfo
    localNotification.userInfo = @{
                                   LMLocalNotificationKey: LMLocalNotificationValue_day
                                   };
    //设置触发条件
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
    //每隔一分钟触发一次本地通知 间隔至少是分钟,秒会出问题
    localNotification.repeatInterval = NSCalendarUnitDay;
    //开启本地通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
- (IBAction)showNotifications:(id)sender {
    NSArray *scheduledLocalNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
    NSLog(@"scheduledLocalNotifications = %@", scheduledLocalNotifications);
    self.notificationShowView.text = [NSString stringWithFormat:@"通知调度池:%@", scheduledLocalNotifications];
}
/**
 移除指定通知
 */
- (IBAction)cancelSpecifiedNotification:(id)sender {
    NSArray *scheduledLocalNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
    for (UILocalNotification *local in scheduledLocalNotifications) {
        if ([local.userInfo[LMLocalNotificationKey] isEqualToString:LMLocalNotificationValue_min]) {
            [[UIApplication sharedApplication] cancelLocalNotification:local];
        }
    }
    [self showNotifications:nil];
}
/**
 移除所有通知
 */
- (IBAction)cancelAllNotifications:(id)sender {
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
    [self showNotifications:nil];
}
@end

注意:通知提示音需要拖进文件夹中


iOS本地通知(基于时间)_第2张图片
Snip20180302_9.png

你可能感兴趣的:(iOS本地通知(基于时间))