:fa-exclamation-triangle:注意本地通知/推送和[广播通知NSNotificationCenter/key-value 观察通知]没有关系
1.本地通知
本地通知是由本地应用触发的,是一种基于时间行为的通知
|-例如:闹钟定时,待办事项提醒
1.1 请求授权(IOS8之后才会有)
如果没有授权即使添加通知也无效
-(void)registLocalNotification{
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
//UIMutableUserNotificationAction用来添加自定义按钮
UIMutableUserNotificationAction * responseAction = [[UIMutableUserNotificationAction alloc] init];
responseAction.identifier = @"response";
responseAction.title = @"回复";
responseAction.activationMode = UIUserNotificationActivationModeForeground; //点击的时候启动程序
UIMutableUserNotificationAction *deleteAction = [[UIMutableUserNotificationAction alloc] init];
deleteAction.identifier = @"delete";
deleteAction.title = @"删除";
deleteAction.activationMode = UIUserNotificationActivationModeBackground; //点击的时候不启动程序,后台处理
deleteAction.authenticationRequired = YES;//需要解锁权限
deleteAction.destructive = YES; //YES为红色,NO为蓝色
UIMutableUserNotificationCategory *category = [[UIMutableUserNotificationCategory alloc] init];
category.identifier = @"alert";
//UIUserNotificationActionContextDefault:默认添加可以添加两个自定义按钮
//UIUserNotificationActionContextMinimal:四个自定义按钮
[category setActions:@[responseAction, deleteAction]
forContext:UIUserNotificationActionContextDefault];
//通知类型
UIUserNotificationType type = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
//通知设定
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:type categories:[NSSet setWithObject:category]];
//注册通知方法是在IOS8之后才开始有的
[[UIApplication sharedApplication] registerUserNotificationSettings:setting];
}
}
注册完了后,触发该代理方法
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
1.2添加通知
:fa-location-arrow:创建一个本地通知通畅需要以下几步:
1 创建UILocalNotification对象
2 设置处理通知时间fireDate
3 配置通知内容:通知主体,声音,图标数字等
4 配置通知传递的自定义数据参数userInfo(可选)
5 调用通知
-(void)addLocalNotification{
UILocalNotification *notification = [[UILocalNotification alloc] init];
//设置时区
notification.timeZone = [NSTimeZone defaultTimeZone];
//设定推送时间
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
//通知内容
notification.alertBody = @"最近添加了许多功能,是否体验?";
//锁屏状态下的左下角滑动动作提示
notification.alertAction = @"打开应用";
//打开程序时的加载画面
notification.alertLaunchImage = @"Default";
//用来显示锁屏时,滑动显示自定义按钮,名字与注册时的category的identifier一致
notification.category = @"alert";
//icon右上角数字
NSInteger number = [UIApplication sharedApplication].applicationIconBadgeNumber;
notification.applicationIconBadgeNumber = number+1;
//设置提示声音
notification.soundName = UILocalNotificationDefaultSoundName;
//设置重复次数
notification.repeatInterval = 2;
notification.userInfo = @{@"id":@1, @"user":@"yanxiaoyu"};
//执行注册通知
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
1.3响应通知
===IOS4===
:fa-bomb:程序未退出状态:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
:fa-bomb:程序退出状态:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
}
===IOS8===
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler{
if ([identifier isEqualToString:@"deleteAction"]) {
}
completionHandler();
}
===IOS9===
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler;
1.4删除通知
-(void)cancelLocalNotification{
//获取本地通知数组
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
//删除指定通知
[[UIApplication sharedApplication] cancelLocalNotification:notifications[0]];
//删除所有通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
:fa-exclamation-triangle:本地通知最多只能有64个,超过会被系统忽略
:fa-exclamation-triangle:通知的声音格式必须是Linear PCM,MA4(IMA/ADPCM),uLaw,alaw中的一种,而且时间必须在30秒内,声音文件必须放到main boundle中
:fa-exclamation-triangle:本地通知是操作系统统一调度的,只有在退出后台或关闭才能收到通知
###2.远程推送
:fa-location-arrow:推送通知的过程分为三步
1 应用服务器提供商将服务器端要发送的**消息和设备令牌(device token)**发送给苹果的消息推送服务器APNS
2 APNS根据设备令牌在已注册的设备中查找对应设备,并将消息发送给响应设备
3 客户端接将接收到的消息传递给应用程序,应用程序根据用户设置弹出消息通知
更加详细的流程图参照下图:
1.APP注册远程推送APNS
___a:[application registerUserNotificationSettings:];
___b:①准备开发配置文件(provisioning profile,也就是.mobileprovision后缀的文件) App ID不能使用手机的Apple ID,必须使用指定的ID,且在生成的配置文件中选择Push Notifications服务,
②应用程序的Bundle Identifier必须和生成配置文件使用的APP ID完全一致
2.iOS请求获取Device Token,app获取Device Token
___a:注册成功后,接收Device Token
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
___b:获取Device Token失败
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
3.IOS应用将Device Token发送给APP提供商,告诉服务器当前设备允许接受消息
___a:为确保token生成算法变化后,仍能正常接收通知,APP每次启动都会重新获取Token
___b:IOS最好将上次的Device Token存储起来,当向服务器发送token时,将新旧token一起发送给服务器,当服务器发现token发生变化,删除旧的token,新增新token
4.APP提供商将Device Token发送给APNS
___a:发送时,指定Device Token和消息内容,并严格遵守苹果官方的消息格式,可以借助第三方消息推送框架来完成。
5.APNS根据消息中的Device Token查找已注册设备,并推送消息
___a:若用户已卸载程序,消息推送失败,APNS会将错误消息通知给服务器,服务器根据错误消息,删除已经存储的Device Token,下次不再发送。
3.广播通知
广播通知是IOS内部的一种消息广播机制,主要为了解决程序内部不同对象之间的解耦,基于观察者模式,不能垮应用程序通讯,流程图如下:
- 核心类
NSNotificationCenter
NSNotification
3.1 NSNotificationCenter
NSNotificationCenter时通知系统的中心,用于注册和发出通知。
:fa-chevron-circle-right:添加监听
- (void)addObserver:(id)observer //监听者
selector:(SEL)aSelector //监听方法:监听者间听到通知后,执行的方法
name:(NSString *)aName //监听的通知名称
object:(id)anObject; //通知的发送者
- (id <NSObject>)addObserverForName:(NSString *)name //监听的通知名称
object:(id)obj //通知的发出者
queue:(NSOperationQueue *)queue //操作队列
usingBlock:(void (^)(NSNotification *note))block//监听到通知后执行
:fa-chevron-circle-right:发送通知
- (void)postNotification:(NSNotification *)notification; //通知对象
- (void)postNotificationName:(NSString *)aName //通知名称
object:(id)anObject; //通知发送者
- (void)postNotificationName:(NSString *)aName //通知名称
object:(id)anObject //通知发送者
userInfo:(NSDictionary *)aUserInfo; //通知参数
:fa-chevron-circle-right:删除监听
- (void)removeObserver:(id)observer; //监听对象
- (void)removeObserver:(id)observer //监听对象
name:(NSString *)aName //通知名称
object:(id)anObject; //通知发送者
- name :监听的名称
- object :通知的发送者
- userInfo:通知的附加信息
3.2例:对登陆事件添加监听
//1.添加登陆成功的监听事件
//如果登陆成功,执行loginSuccess方法
[[NSNotificationCenter defalutCenter] addObserver:self
selector:@selector(loginSuccess:)
name:@"LOGIN_SUCCESS"
object:nil];
//2.如果登陆成功,给监听事件发送通知
NSDictionary *userInfo = @{@"loginSuccess":@"欢迎登陆成功"};
NSNotification *notification =
[NSNotification notificationWithName:@"LOGIN_SUCCESS"
object:self
userInfo:userInfo];
[[NSNotificationCenter defalutCenter] postNotification: notification];
//等价于下面的方法
[[NSNotificationCenter defaultCenter] postNotificationName:@"LOGIN_SUCCESS"
object:self
userInfo:userInfo];
//3.移除监听事件
[[NSNotificationCenter defalutCenter] removeObserver:self
name:@"LOGIN_SUCCESS"
object:nil];