这段时间项目要求做一个类似的闹钟提醒功能,对通知不太熟悉的我,决定先用到xcode自带的本地通知试试,最终成功的实现了功能,特整理分享下。
它的表现特点:
app关闭的时候也能接收和显示通知。
app处于后台的时候能接收通知也能显示。
app处于前台的时候能接收,但不能显示,但是会走应用程序delegate中的方法
具体的创建方法:
-》创建一个本地通知对象UILocalNotification
-》设置fireDate,AlertBody,AlertAction,soundName,applicationBadgeNumber,repeatInterval,alertLanuchImage属性
-》配置通知参数,userInfo。及通知的内容。我们可以在接收通知的方法中获取该对象。
-》调用通知,使用UIApplication的单例对象scheduleLocalNotificaiton按照计划启动通知
此处需要注意的是自从iOS8之后需要征求用户的通知,如果同意则创建UIUerNotificationSettings,然后 registerUserNotificationSettings。对本地通知的数量限制,iOS最多允许最近本地通知数量是64个,超过限制的本地通知将被iOS忽略。
下面就是详细的代码:
1.注册通知 ,同样也适用于iOS10
在appdelegate的application:didFinishLaunchingWithOptions:中调用下面的方法
2.本地通知的定义和使用
在需要使用本地通知的控制器定义,这里为了简便直接定义一个5s之后的闹钟,可以改成任意一个时间点的,转换成NSDate类型替换[NSDate dateWithTimeIntervalSinceNow:5]即可。
为了区分不同的本地通知,可以在定义的同时定义下面的属性
//设置通知的相关信息,这个很重要,可以添加一些标记性内容,方便以后区分和获取通知的信息
NSDictionary *infoDic = [NSDictionary dictionaryWithObjectsAndKeys:LOCAL_NOTIFY_SCHEDULE_ID,@"id", nil];
localNotification.userInfo = infoDic;
3.取消本地通知
注意::在每次不需要或者重新刷新所有的本地通知之前必须先取消所有的本地通知,不然会有重复的相同的通知。
//取消某一个通知
NSArray *notificaitons = [[UIApplication sharedApplication] scheduledLocalNotifications];
//获取当前所有的本地通知
if (!notificaitons || notificaitons.count <= 0) {
return;
}
for (UILocalNotification *notify in notificaitons) {
if ([[notify.userInfo objectForKey:@"id"] isEqualToString:LOCAL_NOTIFY_SCHEDULE_ID]) {
//取消一个特定的通知
[[UIApplication sharedApplication] cancelLocalNotification:notify];
break;
}
}
//取消所有的本地通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
4.本地通知的响应
如果已经注册了本地通知,当客户端响应通知时:
a、应用程序在后台的时候,本地通知会给设备送达一个和远程通知一样的提醒
b、应用程序正在运行中,则设备不会收到提醒,但是会走应用程序delegate中的方法:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
}
如果你想实现程序在后台时候的那种提醒效果,可以在上面这个方法中添加相关代码
if ([[notification.userInfo objectForKey:@"id"] isEqualToString:@"affair.schedule"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"test" message:notification.alertBody delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:notification.alertAction, nil nil];
[alert show];
}
需要注意的是,在情况a中,如果用户点击提醒进入应用程序,也会执行收到本地通知的回调方法,这种情况下如果你添加了上面那段代码,则会出现连续出现两次提示,为了解决这个问题,修改代码如下:
if ([[notification.userInfo objectForKey:@"id"] isEqualToString:@"affair.schedule"]) {
//判断应用程序当前的运行状态,如果是激活状态,则进行提醒,否则不提醒
if (application.applicationState == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:notification.alertBody delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:nil, nil];
[alert show];
}
}