ITPub博客

首页 > 应用开发 > IT综合 > iOS中的系统通知

iOS中的系统通知

IT综合 作者:gaohongfeng 时间:2014-01-28 23:36:25 0 删除 编辑

iOS系统可支持本地通知和远程通知,一个通知在客户端收到的时候可能是一个通知窗体,可能会播放一段通知声音,还有可能在程序图标上增加一个数字,还有可能三者皆有。

本文描述ios系统中计划local notification,注册 remote notification,以及处理 local和remote notification的步骤。本文中客户端API中notification推送指的就是remote notfication的推送

第一个知识点:准备个人定制音频作为提示音,

请注意下面四个小问题-----

1,
系统能播放的四种音频数据格式
Linear PCM
MA4 (IMA/ADPCM)
?Law
aLaw
对应的后缀名可以是aiff, wav, or caf file. Then, 
2, 可以用afconvert来转换音频,例如把16位的线性PCM系统音频格式文件 Submarine.aiff 转换成IMA4音频,存为.CAF文件。
在终端执行即可
afconvert /System/Library/Sounds/Submarine.aiff ~/Desktop/sub.caf -d ima4 -f caff -v
3, 如何确定音频格式呢。
打开QuickTime Player-> Movie menu->Show Movie Inspector 
4, 个人定制音频必须是30s以下。否则就播放默认的声音了。

第二个知识点:预定一个Local Notification
需要了解下面5个步骤
1, Allocate 和 initialize 一个 UILocalNotification对象。
2, fireDate属性赋值
3, 设置别的几个体型要素 提示框,提示音,图标上的提示数字。也可以带别的个性化数据:通过userInfo带出去。
4, 然后Schedule这个通知。通过UIApplication.scheduleLocalNotification来预定执行或者立马执行presentLocalNotificationNow:
5, 也可以取消这个通知。用这个方法:cancelLocalNotification和cancelAllLocalNotifications这个方法

看下代码
/

01 /如何创建设定一个Notification
02 - (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
03     NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
04     NSDateComponents *dateComps = [[NSDateComponents alloc] init];
05     [dateComps setDay:item.day];
06     [dateComps setMonth:item.month];
07     [dateComps setYear:item.year];
08     [dateComps setHour:item.hour];
09     [dateComps setMinute:item.minute];
10     NSDate *itemDate = [calendar dateFromComponents:dateComps];
11     [dateComps release];
12   
13     UILocalNotification *localNotif = [[UILocalNotification alloc] init];
14     if (localNotif == nil)
15         return;
16     localNotif.fireDate = [itemDate addTimeInterval:-(minutesBefore*60)];
17     localNotif.timeZone = [NSTimeZone defaultTimeZone];
18   
19     localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ in %i minutes.", nil),
20          item.eventName, minutesBefore];
21     localNotif.alertAction = NSLocalizedString(@"View Details", nil);
22   
23     localNotif.soundName = UILocalNotificationDefaultSoundName;
24     localNotif.applicationIconBadgeNumber = 1;
25   
26     NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
27     localNotif.userInfo = infoDict;
28   
29     [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
30     [localNotif release];
31 }
32  
33  
34  
35  
36 //程序运行在后台时候如何提交一个UILocalNotification。
37 - (void)applicationDidEnterBackground:(UIApplication *)application {
38     NSLog(@"Application entered background state.");
39     // bgTask is instance variable
40     NSAssert(self->bgTask == UIInvalidBackgroundTask, nil);
41   
42     bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
43         dispatch_async(dispatch_get_main_queue(), ^{
44             [application endBackgroundTask:self->bgTask];
45             self->bgTask = UIInvalidBackgroundTask;
46         });
47     }];
48   
49     dispatch_async(dispatch_get_main_queue(), ^{
50         while ([application backgroundTimeRemaining] > 1.0) {
51             NSString *friend = [self checkForIncomingChat];
52             if (friend) {
53                 UILocalNotification *localNotif = [[UILocalNotification alloc] init];
54                 if (localNotif) {
55                     localNotif.alertBody = [NSString stringWithFormat:
56                         NSLocalizedString(@"%@ has a message for you.", nil), friend];
57                     localNotif.alertAction = NSLocalizedString(@"Read Message", nil);
58                     localNotif.soundName = @"alarmsound.caf";
59                     localNotif.applicationIconBadgeNumber = 1;
60                     [application presentLocalNotificationNow:localNotif];
61                     [localNotif release];
62                     friend = nil;
63                     break;
64                 }
65             }
66         }
67         [application endBackgroundTask:self->bgTask];
68         self->bgTask = UIInvalidBackgroundTask;
69     });
70   
71 }


第三个知识点:注册 Remote Notifications



需要注册Apple Push Notification service ,有三步 
1,调用 registerForRemoteNotificationTypes:方法 
2,通过实现application:didRegisterForRemoteNotificationsWithDeviceToken:这个delegate来接受从APNs传过来的device token。这个token是个binary的值 
3,程序启动即需调用theregisterForRemoteNotificationTypes: 方法来注册推送。后期可以调用enabledRemoteNotificationTypes这个方法来改通知类型。 
需要注意的事情: 
如果网络不通,application:didRegisterForRemoteNotificationsWithDeviceToken这个方法和 application:didFailToRegisterForRemoteNotificationsWithError:都不会被调用哦。 Wifi的时候,通过5223端口链接APNs通常连不上哟因为网管把端口封掉了哟。 
  建议每次程序启动的时候都调用registerForRemoteNotificationTypes来重新获取设备相关的token,而不要缓存token. 
这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。 
那通知就收不到了呗。 

看下代码: 
01 Listing 2-3  Registering for remote notifications
02 - (void)applicationDidFinishLaunching:(UIApplication *)app {
03    // other setup tasks here....
04     [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
05 }
06   
07 // Delegation methods
08 - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
09     const void *devTokenBytes = [devToken bytes];
10     self.registered = YES;
11     [self sendProviderDeviceToken:devTokenBytes]; // custom method
12 }
13   
14 - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
15     NSLog(@"Error in registration. Error: %@", err);
16  
17 }



第四个知识点:处理 Local and Remote Notifications
一般通知来时,程序有两种状态。
1,后台运行发送,需要窗体,声音和数字
点击窗体,启动程序。程序启动了在application:didFinishLaunchingWithOptions: 方法里面获取传递的数据
notification payload (for remote notifications) or 
local-notification object (for local notifications).

点击图标,启动程序。同样调用application:didFinishLaunchingWithOptions,但是传参将不会有远程消息的任何信息


2,程序在前台跑着呢。
程序直接就调用application:didReceiveRemoteNotification:  (for remote notifications)这个方法了
 application:didReceiveLocalNotification: method (for local notifications)


总之要实现UIApplicationDelegate协议
实现application:didFinishLaunchingWithOptions:方法
实现application:didReceiveRemoteNotification:方法
或者实现application:didReceiveLocalNotification:方法


3,那如何判断区别前台还是后台这两种状况呢。


用这个属性applicationState来判断。
若为UIApplicationStateInactive就是用户点击通知框按钮进来的。
若为UIApplicationStateActive,就是前台正跑着呢。


当iOS收到远程消息时,

看下代码

01 //Handling a local notification when an application is launched
02 - (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
03     UILocalNotification *localNotif =
04         [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
05     if (localNotif) {
06         NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
07         [viewController displayItem:itemName];  // custom method
08         application.applicationIconBadgeNumber = localNotif.applicationIconBadgeNumber-1;
09     }
10     [window addSubview:viewController.view];
11     [window makeKeyAndVisible];
12     return YES;
13 }




这里可以通过UIApplicationLaunchOptionsRemoteNotificationKey来获取通知传递过来的自定义数据




之后即可从provider方下数据了。
01 - (void)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {
02     // check launchOptions for notification payload and custom data, set UI context
03     [self startDownloadingDataFromProvider];  // custom method
04     app.applicationIconBadgeNumber = 0;
05     // other setup tasks here....
06 }
07  
08  
09 Listing 2-6  Handling a local notification when an application is already running
10 - (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
11     NSString *itemName = [notif.userInfo objectForKey:ToDoItemKey]
12     [viewController displayItem:itemName];  // custom method
13     application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
14 }


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12231606/viewspace-1076359/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-01-25

  • 博文量
    38
  • 访问量
    256509