本地推送服务 UILocalNotification

jopen 9年前

原文 http://www.cnblogs.com/coltfoal/p/4591699.html

前言

之前接触过iOS上的推送服务,当时做的是在线推送,虽然已经有很多开发商提供集成的推送服务,但作为了解原理的方式也是一个不错的过程。

最近打算应用本地通推送的功能,本来以为会和在线推送一样麻烦,又要弄证书,又要提交验证,所以一直没动手。今天稍微了解后,发现本地推送就是很简单的一件事。

介绍

本地推送是什么

在线推送一般是通过服务器发送消息到对应设备,并由对应设备做出响应通知用户。而本地推送则是直接在本地由程序控制发送消息通知用户。由于减少了服务器以及验证设备的过程,所以本地推送其实就是一个简单的通知服务。

本地推送能做什么

GTD应用一般需要根据设定在规定时间通知用户完成某个任务。GTD的事务在本地基本都有备份,也当然是通过本地来通知用户何时应用完成任务。在这里,本地推送服务的作用就突显出来了。

某些游戏,比如升级建筑装备等,一般都需要时间去完成,玩家不可能在游戏前一直等待。当升级结束,游戏在本地把通知推送给玩家,玩家响应并再次进入游戏,不仅节约玩家的时间,也给游戏的激活带来更多的流量。

虽然本地推送不如在线推送的使用频率那么高,但还是很有用途的。

如何实现本地推送

添加通知

本地推送的实现很简单,更多的是自定义的过程。来看看下面的代码:

UILocalNotification *notification = [[UILocalNotification alloc] init]; // ARC环境  notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:3]; // 推送时间  notification.timeZone = [NSTimeZone defaultTimeZone];    notification.repeatInterval = 0; // 推送间隔  notification.soundName = UILocalNotificationDefaultSoundName; // 推送声音  notification.alertBody = @"Push Notification"; // 推送内容  notification.applicationIconBadgeNumber = 1; // 消息个数  notification.userInfo = [NSDictionary dictionaryWithObject:@"value" forKey:@"key"];    [[UIApplication sharedApplication] scheduleLocalNotification:notification];

实例化一个`UILocalNotification`对象,并根据具体的要求设置这个对象的属性。

`fireDate`表示推送的时间。`timeZone`是对应的时区。

`repeatInterval`表示推送的重复间隔,它的类型是`NSCalendarUnit`,可以用这个枚举值来赋值,表示每天、每周或每月等。如果为0则表示不重复推送。

`soundName`是推送的声音,可以写上bundle资源里已有的音乐文件名称,这样就可以自定义推送的声音了。

`alertBody`是推送的内容。

`applicationIconBadgeNumber`表示显示在该应用图标上的消息个数。在接受消息后需要把这个属性重置。

`userInfo`可以存放通知的相关信息。

最后,通过调用`scheduleLocalNotification`达到推送通知的目的。

接收通知

接收推送通知更加容易,在`AppDelegate`的`didReceiveLocalNotification`方法中就可以接收了。

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification*)notification  {  NSLog(@"Notification : %@", notification.alertBody); // 输出推送信息  application.applicationIconBadgeNumber = 0; // 消息数置为0 }

上面在`didReceiveLocalNotification`方法中打印出了推送消息的内容,并把消息数置为0。当然也可以通过判断`notification`的具体信息显示弹窗、修改消息数等。

取消通知

NSArray *array = [[UIApplication sharedApplication] scheduledLocalNotifications]; // 获取本地推送数组 [[UIApplication sharedApplication] cancelLocalNotification:notification]; // 取消某个推送 [[UIApplication sharedApplication] cancelAllLocalNotifications]; // 取消所有推送

上面这段代码展示了几个API,但其中没有必然的调用关系。

`scheduledLocalNotifications`可以获取本地的推送数组,其中的每个成员都是UILocalNotification,可以根据它们的userInfo区分推送的类型。

`cancelLocalNotification`可以取消某个具体的推送通知。比如取消通过`scheduledLocalNotifications`获取的某个通知。

`cancelAllLocalNotifications`则可以一次性取消所有的通知。

本地推送会有哪些坑

iOS8

在iOS8之后,要使用本地推送都需要为本地注册通知类型,否则无法接收到通知。具体的做法是在`AppDelegate`的`didFinishLaunchingWithOptions`中注册。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]]; return YES;  }

音乐

推送通知可以自定义音乐,但并不是所有音乐都可以调用。目前只支持30秒的音乐,因为推送最多只能维持30秒。

声音

如果手机置为静音,则音乐无法播放。

如果在手机打开的时候显示通知,也不会播放音乐,甚至也不会震动。

applicationIconBadgeNumber

如果是从通知栏点击通知进入应用,会响应通知的回调,同时在回调中奖消息数置为0。

而如果是在有消息的情况下直接打开应用,并不会走通知回调的流程。

可以根据需要接入这部分逻辑。

总结

本地通知的处理还是比较简单的。

闹钟的实现原理也是利用了本地通知,但是如果要考虑震动等问题,则会更加复杂。有需要再慢慢研究。