IOS本地通知:UILocalNotification使用记录
2016-01-19 16:38
344 查看
第一次接触IOS的本地通知的使用,看到别人写的一个比较详细的记录,自己整理过来,方便以后再次使用和拓展:
1.创建一个本地通知,添加到系统:
repeatInterval表示通知的重复间隔,在SDK中定义如下:
这里比较不好的一点是该值不能自定义(很遗憾,NSCalendarUnit是个枚举类型),例如你不能塞个10.0给它从而希望它每十秒重复一次。所以如果你想每20分钟发送一次通知,一小时内发送3次,那么只能同时设定三个通知了。
2.收到通知后委托内的自定义实现:
3.如何取消(删除本地通知)
有一点需要注意,如果我们的应用程序给系统发送的本地通知是周期性的,那么即使把程序删了重装,之前的本地通知在重装时依然存在(没有从系统中移除)。
因此我们需要取消通知的方法,当然该对象也会在scheduledLocalNotifications数组中移除。
取消方法分为两种。
第一种比较暴力,直接取消所有的本地通知:
这个适合在App重装时第一次启动的时候,或还原程序默认设置等场合下使用。
第二种方法是针对某个特定通知的:
4.如何标识一个本地通知
需要通知有一个标识,这样我们才能定位是哪一个通知。可以在notification的userInfo(一个字典)中指定。
例如:
当然使用上述本地通知的前提是,应用获取到了系统的通知权限,需要注册通知:
注册之前有两个前提条件必须准备好:
开发配置文件(provisioning profile,也就是.mobileprovision后缀的文件)的App ID不能使用通配ID必须使用指定APP ID并且生成配置文件中选择Push Notifications服务,一般的开发配置文件无法完成注册;
应用 程序的Bundle Identifier必须和生成配置文件使用的APP ID完全一致
注:
在使用通知之前必须注册通知类型,如果用户不允许应用程序发送通知,则以后就无法发送通知,除非用户手动到iOS设置中打开通知。
本地通知是有操作系统统一调度的,只有在应用退出到后台或者关闭才能收到通知。(注意:这一点对于后面的推送通知也是完全适用的。 )
通知的声音是由iOS系统播放的,格式必须是Linear PCM、MA4(IMA/ADPCM)、µLaw、aLaw中的一种,并且播放时间必须在30s内,否则将被系统声音替换,同时自定义声音文件必须放到boundle中。
本地通知的数量是有限制的,最近的本地通知最多只能有64个,超过这个数量将被系统忽略。
如果想要移除本地通知可以调用UIApplication的cancelLocalNotification:或cancelAllLocalNotifications移除指定通知或所有通知。
从上面的程序可以看到userInfo这个属性我们设置了参数,那么这个参数如何接收呢?
在iOS中如果点击一个弹出通知(或者锁屏界面滑动查看通知),默认会自动打开当前应用。由于通知由系统调度那么此时进入应用有两种情况:
如果应用程序已经完全退出那么此时会调用- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法;
如果此时应用程序还在运行(无论是在前台还是在后台)则会调用-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification方法接收消息参数。
当然如果是后者自然不必多说,因为参数中已经可以拿到notification对象,只要读取userInfo属性即可。如果是前者的话则可以访问launchOptions中键为UIApplicationLaunchOptionsLocalNotificationKey的对象,这个对象就是发送的通知,由此对象再去访问userInfo。为了演示这个过程在下面的程序中将userInfo的内容写入文件以便模拟关闭程序后再通过点击通知打开应用获取userInfo的过程。
上面的程序可以分为两种情况去运行:
一种是启动程序关闭程序,等到接收到通知之后点击通知重新进入程序;
另一种是启动程序后,进入后台(其实在前台也可以,但是为了明显的体验这个过程建议进入后台),接收到通知后点击通知进入应用。
两种情况会分别按照前面说的情况调用不同的方法接收到userInfo写入本地文件系统。有了userInfo一般来说就可以根据这个信息进行一些处理,例如可以根据不同的参数信息导航到不同的界面,假设是更新的通知则可以导航到更新内容界面等。
1.创建一个本地通知,添加到系统:
// 初始化本地通知对象 UILocalNotification *notification = [[UILocalNotification alloc] init]; if (notification) { // 设置通知的提醒时间 NSDate *currentDate = [NSDate date]; notification.timeZone = [NSTimeZone defaultTimeZone]; // 使用本地时区 notification.fireDate = [currentDate dateByAddingTimeInterval:5.0]; // 设置重复间隔 notification.repeatInterval = kCFCalendarUnitDay; // 设置提醒的文字内容 notification.alertBody = @"Wake up, man"; notification.alertAction = NSLocalizedString(@"起床了", nil); // 通知提示音 使用默认的 notification.soundName= UILocalNotificationDefaultSoundName; // 设置应用程序右上角的提醒个数 notification.applicationIconBadgeNumber++; // 设定通知的userInfo,用来标识该通知 NSMutableDictionary *aUserInfo = [[NSMutableDictionary alloc] init]; 24 aUserInfo[kLocalNotificationID] = @"LocalNotificationID"; 25 notification.userInfo = aUserInfo; // 将通知添加到系统中 [[UIApplication sharedApplication] scheduleLocalNotification:notification]; }
repeatInterval表示通知的重复间隔,在SDK中定义如下:
typedef CF_OPTIONS(CFOptionFlags, CFCalendarUnit) { kCFCalendarUnitEra = (1UL << 1), kCFCalendarUnitYear = (1UL << 2), kCFCalendarUnitMonth = (1UL << 3), kCFCalendarUnitDay = (1UL << 4), kCFCalendarUnitHour = (1UL << 5), kCFCalendarUnitMinute = (1UL << 6), kCFCalendarUnitSecond = (1UL << 7), kCFCalendarUnitWeek CF_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0) = (1UL << 8), kCFCalendarUnitWeekday = (1UL << 9), kCFCalendarUnitWeekdayOrdinal = (1UL << 10), kCFCalendarUnitQuarter CF_ENUM_AVAILABLE(10_6, 4_0) = (1UL << 11), kCFCalendarUnitWeekOfMonth CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 12), kCFCalendarUnitWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 13), kCFCalendarUnitYearForWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 14), };
这里比较不好的一点是该值不能自定义(很遗憾,NSCalendarUnit是个枚举类型),例如你不能塞个10.0给它从而希望它每十秒重复一次。所以如果你想每20分钟发送一次通知,一小时内发送3次,那么只能同时设定三个通知了。
2.收到通知后委托内的自定义实现:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ NSLog(@"Application did receive local notifications"); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; }
3.如何取消(删除本地通知)
有一点需要注意,如果我们的应用程序给系统发送的本地通知是周期性的,那么即使把程序删了重装,之前的本地通知在重装时依然存在(没有从系统中移除)。
因此我们需要取消通知的方法,当然该对象也会在scheduledLocalNotifications数组中移除。
取消方法分为两种。
第一种比较暴力,直接取消所有的本地通知:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
这个适合在App重装时第一次启动的时候,或还原程序默认设置等场合下使用。
第二种方法是针对某个特定通知的:
- (void)cancelLocalNotification:(UILocalNotification *)notification
4.如何标识一个本地通知
需要通知有一个标识,这样我们才能定位是哪一个通知。可以在notification的userInfo(一个字典)中指定。
例如:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ NSLog(@"Application did receive local notifications"); // 取消某个特定的本地通知 for (UILocalNotification *noti in [[UIApplication sharedApplication] scheduledLocalNotifications]) { NSString *notiID = noti.userInfo[kLocalNotificationID]; 7 NSString *receiveNotiID = notification.userInfo[kLocalNotificationID]; if ([notiID isEqualToString:receiveNotiID]) { [[UIApplication sharedApplication] cancelLocalNotification:notification]; return; } } UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"welcome" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; }
当然使用上述本地通知的前提是,应用获取到了系统的通知权限,需要注册通知:
注册之前有两个前提条件必须准备好:
开发配置文件(provisioning profile,也就是.mobileprovision后缀的文件)的App ID不能使用通配ID必须使用指定APP ID并且生成配置文件中选择Push Notifications服务,一般的开发配置文件无法完成注册;
应用 程序的Bundle Identifier必须和生成配置文件使用的APP ID完全一致
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UIDevice *device = [UIDevice currentDevice]; float sysVersion = [device.systemVersion floatValue]; if (sysVersion >= 8.0f) { UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings]; if (UIUserNotificationTypeNone != setting.types) { [self addLocalNotification]; NSLog(@"已经允许了通知"); }else{ [[UIApplication sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } }else{ UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if(UIRemoteNotificationTypeNone != type){ NSLog(@"已经允许了通知"); }else{ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)]; } } //[self registerRemoteNotification]; return YES; } #pragma mark 调用过用户注册通知方法之后执行(也就是调用完registerUserNotificationSettings:方法之后执行) -(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{ if (notificationSettings.types!=UIUserNotificationTypeNone) { //[self addLocalNotification]; NSLog(@"允许了通知"); } } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"注册成功"); } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"注册失败"); }
注:
在使用通知之前必须注册通知类型,如果用户不允许应用程序发送通知,则以后就无法发送通知,除非用户手动到iOS设置中打开通知。
本地通知是有操作系统统一调度的,只有在应用退出到后台或者关闭才能收到通知。(注意:这一点对于后面的推送通知也是完全适用的。 )
通知的声音是由iOS系统播放的,格式必须是Linear PCM、MA4(IMA/ADPCM)、µLaw、aLaw中的一种,并且播放时间必须在30s内,否则将被系统声音替换,同时自定义声音文件必须放到boundle中。
本地通知的数量是有限制的,最近的本地通知最多只能有64个,超过这个数量将被系统忽略。
如果想要移除本地通知可以调用UIApplication的cancelLocalNotification:或cancelAllLocalNotifications移除指定通知或所有通知。
从上面的程序可以看到userInfo这个属性我们设置了参数,那么这个参数如何接收呢?
在iOS中如果点击一个弹出通知(或者锁屏界面滑动查看通知),默认会自动打开当前应用。由于通知由系统调度那么此时进入应用有两种情况:
如果应用程序已经完全退出那么此时会调用- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法;
如果此时应用程序还在运行(无论是在前台还是在后台)则会调用-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification方法接收消息参数。
当然如果是后者自然不必多说,因为参数中已经可以拿到notification对象,只要读取userInfo属性即可。如果是前者的话则可以访问launchOptions中键为UIApplicationLaunchOptionsLocalNotificationKey的对象,这个对象就是发送的通知,由此对象再去访问userInfo。为了演示这个过程在下面的程序中将userInfo的内容写入文件以便模拟关闭程序后再通过点击通知打开应用获取userInfo的过程。
#pragma mark - 应用代理方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //添加通知 [self addLocalNotification]; //接收通知参数 UILocalNotification *notification=[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey]; NSDictionary *userInfo= notification.userInfo; [userInfo writeToFile:@"/Users/kenshincui/Desktop/didFinishLaunchingWithOptions.txt" atomically:YES]; NSLog(@"didFinishLaunchingWithOptions:The userInfo is %@.",userInfo); return YES; }
上面的程序可以分为两种情况去运行:
一种是启动程序关闭程序,等到接收到通知之后点击通知重新进入程序;
另一种是启动程序后,进入后台(其实在前台也可以,但是为了明显的体验这个过程建议进入后台),接收到通知后点击通知进入应用。
两种情况会分别按照前面说的情况调用不同的方法接收到userInfo写入本地文件系统。有了userInfo一般来说就可以根据这个信息进行一些处理,例如可以根据不同的参数信息导航到不同的界面,假设是更新的通知则可以导航到更新内容界面等。
相关文章推荐
- 借鉴drawable文件夹,values使用dimens控制字体大小、边距大小。适配Android不同机型,不同屏幕
- 1月19号 UIImageView
- MySQL学习10_使用chown更改/var/lib所有者导致Starting MySQL. ERROR! The server quit without updating PID file错误
- iOS UIScrollview 和侧滑手势冲突解决方法
- iOS--UINavigationBar使用总结
- request各个方法,获取各种路径
- Request.QueryString[""] 与 Request[""] 、 Request.QueryString[""].Tostring()
- iOS小技巧–用runtime 解决UIButton 重复点击问题
- UITextField
- *** does not contain bitcode. You must rebuild it with bitcode enabled
- UIPageControll - 图片格式
- 结束while(cin >> value)
- 酷炫的android开源UI
- 9.Which statement is true regarding the INTERSECT operator?
- AlertDialog.Builder用法
- Django用户认证系统 authentication system----登陆访问限制@login_required
- UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
- iOS UI界面之间传值方式的整理总结(2)单例方法
- ios UI控件关联
- <iOS Human Interface Guidelines>(iOS人机交互手册)读书笔记