-
工程结构
- 将本地通知的 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
注意:通知提示音需要拖进文件夹中