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这个方法
看下代码
//如何创建设定一个Notification
- (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
[dateComps setDay:item.day];
[dateComps setMonth:item.month];
[dateComps setYear:item.year];
[dateComps setHour:item.hour];
[dateComps setMinute:item.minute];
NSDate *itemDate = [calendar dateFromComponents:dateComps];
[dateComps release];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [itemDate addTimeInterval:-(minutesBefore*60)];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ in %i minutes.", nil),
item.eventName, minutesBefore];
localNotif.alertAction = NSLocalizedString(@"View Details", nil);
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
//程序运行在后台时候如何提交一个UILocalNotification。
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"Application entered background state.");
// bgTask is instance variable
NSAssert(self->bgTask == UIInvalidBackgroundTask, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIInvalidBackgroundTask;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
while ([application backgroundTimeRemaining] > 1.0) {
NSString *friend = [self checkForIncomingChat];
if (friend) {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = [NSString stringWithFormat:
NSLocalizedString(@"%@ has a message for you.", nil), friend];
localNotif.alertAction = NSLocalizedString(@"Read Message", nil);
localNotif.soundName = @"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
[localNotif release];
friend = nil;
break;
}
}
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIInvalidBackgroundTask;
});
}
第三个知识点:注册 Remote Notifications
}
第四个知识点:处理 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收到远程消息时,
看下代码
//Handling a local notification when an application is launched
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
[viewController displayItem:itemName]; // custom method
application.applicationIconBadgeNumber = localNotif.applicationIconBadgeNumber-1;
}
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
这里可以通过UIApplicationLaunchOptionsRemoteNotificationKey来获取通知传递过来的自定义数据
之后即可从provider方下数据了。
- (void)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {
// check launchOptions for notification payload and custom data, set UI context
[self startDownloadingDataFromProvider]; // custom method
app.applicationIconBadgeNumber = 0;
// other setup tasks here....
}
Listing 2-6 Handling a local notification when an application is already running
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
NSString *itemName = [notif.userInfo objectForKey:ToDoItemKey]
[viewController displayItem:itemName]; // custom method
application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
}
本文为意译,原文地址:https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/IPhoneOSClientImp/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103-SW1