本地通知
先判断用户是否允许该软件接受通知
//如果已经获得发送通知的授权则创建本地通知,否则请求授权(注意:如果不请求授权在设置中是没有对应的通知设置项的,也就是说如果从来没有发送过请求,即使通过设置也打不开消息允许设置
if ([[UIApplication sharedApplication] currentUserNotificationSettings].types != UIUserNotificationTypeNone) {
[self addLocalNotification];
} else {
if ([[UIDevice currentDevice].systemVersion doubleValue] < 8.0) {// iOS 8.0以下的方法
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
} else { // iOS 8.0及以上的方法
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
}
- (void)addLocalNotification
{
// 定义本地通知对象
UILocalNotification *notification = [[UILocalNotification alloc] init];
// 设置调用时间,10秒之后
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5.0];
// 通知重复次数
notification.repeatInterval = kCFCalendarUnitMinute;
// 设置通知属性,通知主题
notification.alertBody = @"有了新的特性,快过来看看";
// 应用程序图片右上角显示的消息数
notification.applicationIconBadgeNumber = 1;
notification.repeatInterval = NSCalendarUnitDay; // 日历单位天
// 待机界面的活动动作提示
notification.alertAction = @"打开应用";
// 通过点击通知打开应用时的启动图片,这里使用程序启动图片
notification.alertLaunchImage = @"Default";
// 设置用户信息
notification.userInfo = @{@"id":@1,@"user":@"Reiko"};
// 调用通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
// 移除所有本地通知
- (void)removeNotification
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// [[UIApplication sharedApplication] cancelLocalNotification:aLocalNoti]; // 可根据通知的userInfo,移除一条通知
}
// 软件运行时,接受本地通知时候触发
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSString *message = notification.alertBody;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:message
delegate:nil
cancelButtonTitle:@"我知道了"
otherButtonTitles:nil];
[alert show];
application.applicationIconBadgeNumber -= 1;
}
// 调用过用户注册通知方法后执行,调用完registerUserNotificationSettings执行
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if (notificationSettings.types != UIUserNotificationTypeNone){
[self addLocalNotification];
}
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// 进入前台取消应用消息图标
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
下面我们说明一下通知触发的情况,通知触发的情况有两种,一种是程序没有运行,另外一种是程序已经在运行,这种情况有分为两种情况,一种情况是在后天运行时触发,另一种情况是在前天运行时触发,我们先来说在程序没有启动,如果程序没有启动,本地通知触发了,这个时候程序将执行:
-(BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
我们可以在此函数中获取本地通知的参数。我们判断UIApplicationLaunchOptionsLocalNotificationKey是否存在,判断方法如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { application.applicationIconBadgeNumber=0; UILocalNotification *uinfo=[launchOptions objectForKey:@"UIApplicationLaunchOptionsLocalNotificationKey"]; if(uinfo!=nil){ NSDictionary *dic=uinfo.userInfo//就使本地通知中传递过的NSDictionary,我们可以获取其中的参数。 } }
另外一种是程序已经在运行,这个时候有前天运行与后台运行,如果在后台运行,这个时候如果通知的时间到了,不会自动触发didReceiveLocalNOtification,用户点击了,通知中心的通知使用触发此函数,我们可以在里面通过上面的方法得当其中的参数,然后执行相应的操作。如程序在前天运行,这个时候就有一种情况,就是时间到了会触发didReceiveLocalNotification,点击通知中心的通知也会触发此函数,这个我们没有办法区分是谁触发了didRecieveLocalNotification,(如当我点击的时候我希望跳转到指定的页面,而时间到了的触发不让跳转,这就没有办法区分了),我们在这儿使用一个小技巧来区分这两种情况。要求我们在通知的时候,通过userInfo传递一下通知时间的格式,如上面的代码,我们通知的时候传递了触发时间的格式,但触发了didReceiveLoalNotification时,我们获取一下日期的格式,使用当前时间与触发的时间比较,如果在某一个非常小的范围内我们就认为是时间到了触发了,而不去触发,否则我们认为是点击触发了,我们执行相应的操作。代码如下:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ NSDictionary *userInfo=notification.userInfo; NSString *sfiredateformat=[NSMutableString stringWithString:[userInfo objectForKey:@"firedateformat"]]; NSDateFormatter *formatter=[[[NSDateFormatter alloc] init] autorelease]; [formatter setDateFormat:sfiredateformat]; if([[formatter dateFromString:[formatter stringFromDate:[NSDate date]]] timeIntervalSinceDate:notification.fireDate]>0.5){ //用户点击了, }else{ //时间到了触发的 } }
这样我们就区分开了两种情况。