你如果把上面的程序运行在iOS8上,会爆出如下错误
预习01-本地推送通知[掌握][615:7847] Attempting to schedule a local notification {fire date = Monday, July 13, 2015 at 9:02:25 AM China Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Monday, July 13, 2015 at 9:02:25 AM China Standard Time, user info = { pageKey = friend; }} with an alert but haven't received permission from the user to display alerts
也就是在iOS8上要发送本地通知需要 请求用户权限 如何请求用户权限呢?一般在新版有变化的地方,在头文件中都会有相应的说明,所以点击到scheduleLocalNotification:方法中,看看有没有我们需要信息
点击进去,我们看到
意思就是说:在iOS8.0以后,在调度通知之前你需要使用UIApplication的对象方法registerUseNotificationSetting:来请求用户授权.
这种请求权限的代码一般放在didFinishLaunchingWithOptions:方法中,在用户不卸载的情况下,只需要请求一次,下次在运行就不用请求了!
// 1.如果是iOS8请求用户权限
if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
/*
UIUserNotificationType:
UIUserNotificationTypeBadge = 1 << 0, // 接收到通知可更改程序的应用图标
UIUserNotificationTypeSound = 1 << 1, // 接收到通知可播放声音
UIUserNotificationTypeAlert = 1 << 2, // 接收到通知课提示内容
如果你需要使用多个类型,可以使用 "|" 来连接
*/
// 向用户请求通知权限
// categories暂时传入nil
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:setting];
}
运行程序
测试点击通知,进入应用,也没问题
接下来,我们说说-[UIUserNotificationSettings settingsForTypes:categories:] 中的 categories
注册分类,并在分类中添加不同的行为 由于注册用户通知设置代码量比较大我们实现一个新的方法registerUserNotification
- (void) registerUserNotification
{
// 向用户请求通知权限
/*
UIUserNotificationType:用户通知的类型
UIUserNotificationTypeBadge = 1 << 0, // 接收到通知可更改程序的应用图标
UIUserNotificationTypeSound = 1 << 1, // 接收到通知可播放声音
UIUserNotificationTypeAlert = 1 << 2, // 接收到通知课提示内容
如果你需要使用多个类型,可以使用 "|" 来连接
*/
// 1.设置用户通知权限类型
UIUserNotificationType types = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
// 2.创建通知的行为按钮
// 2.1创建第一个行为
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
// 2.1.1 设置行为的唯一标示
action1.identifier = UIMutableUserNotificationActionBackground;
// 2.1.2 设置通知按钮的的标题
action1.title = @"后台";
// 以什么样模式运行应用
// UIUserNotificationActivationModeForeground, // 当应用在前台的时候触发
// UIUserNotificationActivationModeBackground // 即使应用不在前台也触发
action1.activationMode = UIUserNotificationActivationModeBackground;
// 2.1.3 是否只有锁屏的锁屏状态下才能显示
action1.authenticationRequired = NO;
// 2.1.4 按钮的性质
action1.destructive = NO;
// 2.1创建第一个行为
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
// 2.1.1 设置行为的唯一标示
action2.identifier =UIMutableUserNotificationActionForeground;
// 2.1.2 设置通知按钮的的标题
action2.title = @"前台";
// 以什么样模式运行应用
// UIUserNotificationActivationModeForeground, // 当应用在前台的时候触发
// UIUserNotificationActivationModeBackground // 即使应用不在前台也触发
action2.activationMode = UIUserNotificationActivationModeForeground;
// 2.1.3 用户必须输入密码才能执行
action2.authenticationRequired = YES;
// 2.1.4 按钮的性质(没有效果)
action2.destructive = YES;
// 3.创建用户通知分类
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
// 3.1 设置类别的唯一标识
category.identifier = @"myCategory";
// 3.2 设置通知的按钮
// Context:
// UIUserNotificationActionContextDefault, //默认上下文(情景)下的英文(通常都是)
// UIUserNotificationActionContextMinimal //通知内容区域受限情况下内容
[category setActions:@[action1,action2] forContext:UIUserNotificationActionContextDefault];
// 4.创建用户通知的设置信息
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:types categories:[NSSet setWithObject:category]];
// 注册设置
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
}
// 9.设置通知的类别
ln.category = @"myCategory";
/**
* 当用户点击通知上定制的按钮执行的行为(注意:不点击行为按钮,不会进入该方法)
*
* @param application 应用
* @param identifier 行为标识符
* @param notification 本地通知
* @param completionHandler 完成回调
*/
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
// 处理不同行为
if ([identifier isEqualToString:UIMutableUserNotificationActionBackground]) {
NSLog(@"后台运行程序");
}else if ([identifier isEqualToString:UIMutableUserNotificationActionForeground]){
NSLog(@"前台运行程序");
}else{
NSLog(@"其他");
}
/**
You should call the completion handler as soon as you've finished handling the action.
当任务处理完毕时候,你应该尽快的调用completion的block.
*/
// 在当任务完成的时候,调用任务完成的block
completionHandler();
}