本地推送通知
“本地”可以理解为”不联网”;即使没有网络情况下,也可以推送通知消息
通知发送方: 开发人员负责在APP内发送
应用场景: 确定知道未来某个时间点应该提醒用户什么
远程推送通知
与“本地”相对,表示,必须在联网情况下才会向用户推送通知消息
远程推送服务,又称为APNs(Apple Push Notification Services)
通知发送方: 服务器
应用场景:
- 不确定未来某个时间点应该提醒用户什么,临时性的
- 当APP彻底退出时也想继续让用户获取一些最新消息
通知呈现样式,是有用户设置的.
通知使用细节:
发出推送通知时,如果当前程序正运行在前台,那么推送通知就不会被呈现出来
点击推送通知后,默认会自动打开发出推送通知的app
不管app打开还是关闭,推送通知都能如期发出
使用:
核心类: UILocalNotification
// 1. 创建本地通知
UILocalNotification *localNotice = [[UILocalNotification alloc] init];
// 1.1 设置通知内容
localNotice.alertBody = @"你中彩票了!";
// 1.2 设置通知发送时间
localNotice.fireDate = [NSDate dateWithTimeIntervalSinceNow:3];
// 1.3 设置通知的时区(使用默认时区就可以)
localNotice.timeZone = [NSTimeZone defaultTimeZone];
/** --------额外属性补充---------- */
// 设置重复周期(最小重复周期是一分钟)
// localNotice.repeatInterval = NSCalendarUnitMinute;
// 滑动后面的文字
localNotice.hasAction = NO;
localNotice.alertAction = @"领取";//滑动来领取
// 设置启动图(任何情况下都读取LaunchImage文件)
localNotice.alertLaunchImage = @"abc";
// 通知标题(8.2)
if(isiOS(8.2))
{
localNotice.alertTitle = @"中奖啦";
}
// 接收到通知时,播放的音频
localNotice.soundName = @"buyao.wav";
// 设置提醒数字
localNotice.applicationIconBadgeNumber = 2;
// 2. 发送本地通知
// 通知是一个应用程序级别操作
// [[UIApplication sharedApplication] presentLocalNotificationNow:localNotice]; // 立即发送一个通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNotice]; // 计划发送一个通知
iOS8之后,需要额外请求授权,操作必须在程序一启动的时候执行,放在AppDelegate的
didFinishLaunchingWithOptions方法里面调用
核心类: UIUserNotificationSettings
-(void)registerAuthor
{
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// 创建一个设置对象
UIUserNotificationSettings *sets = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
// 注册通知设置
[[UIApplication sharedApplication] registerUserNotificationSettings:sets];
}
}
通知参数的传递:
// 用来传递参数
localNotice.userInfo = @{
@"message" : @"顺子要不要?"
};
UIApplicationDelegate代理有个 didReceiveLocalNotification 方法;
1.当前在前台时
2.或者从后台进入到前台
这两个状态,都可以执行didReceiveLocalNotification方法.
那么如何区分这2种状态?
typedef NS_ENUM(NSInteger, UIApplicationState) {
UIApplicationStateActive, 前台状态
UIApplicationStateInactive,从后台进入到前台状态
UIApplicationStateBackground 后台状态
} NS_ENUM_AVAILABLE_IOS(4_0);
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"接收到通知");
/**
* UIApplicationStateActive, // 活动状态
UIApplicationStateInactive, // 进入活动状态
UIApplicationStateBackground // 后台状态
*/
// 跳转界面(当前在前台模式下, 不能跳转)
if(application.applicationState == UIApplicationStateActive)
{
NSLog(@"不跳转界面,只给提示---%@", notification.userInfo);
}else if (application.applicationState == UIApplicationStateInactive) // 只有当从后台进入前台时,才需要跳转
{
NSLog(@"跳转界面---%@", notification.userInfo);
}
}
如果app退出(kill) , 那么在通过点击通知,进去app,那么didReceiveLocalNotification方法就不会执行.
那么这种情况,如何监听通知回调呢?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerAuthor];//iOS8 之后的请求授权
// launchOptions : 如果非正常点击图标启动程序,此字典都会有值
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
// 做一些接收到通知,通过通知点击启动app的一些业务逻辑
}
return YES;
}
iOS8之后可以给通知附带一些操作行为
// categories may be nil or an empty set if custom user notification actions will not be used
+ (instancetype)settingsForTypes:(UIUserNotificationType)types
categories:(nullable NSSet<UIUserNotificationCategory *> *)categories; //
NSSet<UIUserNotificationCategory *>
这个集合存放着UIUserNotificationCategory对象,是一个操作选项组
我们应该使用其子类:UIMutableUserNotificationCategory,有个actions属性,来存放操作行为.
UIMutableUserNotificationAction 对象
@interface UIMutableUserNotificationAction : UIUserNotificationAction
// The unique identifier for this action.
@property (nullable, nonatomic, copy) NSString *identifier;
// The localized title to display for this action.
@property (nullable, nonatomic, copy) NSString *title;
// The behavior of this action when the user activates it.
@property (nonatomic, assign) UIUserNotificationActionBehavior behavior NS_AVAILABLE_IOS(9_0);
// Parameters that can be used by some types of actions.
@property (nonatomic, copy) NSDictionary *parameters NS_AVAILABLE_IOS(9_0);
//设置点击对应行为后是否会进入APP
@property (nonatomic, assign) UIUserNotificationActivationMode activationMode;
//是否解锁之后才能点击通知行为
@property (nonatomic, assign, getter=isAuthenticationRequired) BOOL authenticationRequired;
//设置行为是否是危险操作,只是颜色显示不同
@property (nonatomic, assign, getter=isDestructive) BOOL destructive;
@end
设置完action属性后,通过数组赋值给Category对象.
-(void)registerAuthor
{
if(isiOS(8.0))
{
// NSSet<UIUserNotificationCategory *>
// 一个操作选项组
UIMutableUserNotificationCategory *unc = [[UIMutableUserNotificationCategory alloc] init];
unc.identifier = @"select";
// 创建操作行为
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
action1.title = @"不进入APP";
action1.identifier = @"exit";
// 行为执行的必要状态
action1.activationMode = UIUserNotificationActivationModeForeground;
// 创建操作行为
UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
action2.title = @"进入APP";
action2.identifier = @"enter";
// 行为执行的必要状态
action2.activationMode = UIUserNotificationActivationModeBackground;
NSArray *actions = @[action1, action2];
// 给操作选项组,设置操作选项
[unc setActions:actions forContext:UIUserNotificationActionContextDefault];
NSSet *categories = [NSSet setWithObjects:unc, nil];
// 创建一个设置对象
UIUserNotificationSettings *sets = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:categories];
// 注册通知设置
[[UIApplication sharedApplication] registerUserNotificationSettings:sets];
}
}
action的identifer怎么使用?
通过代理方法 的参数来判断对应行为
/**
* 当点击一个通知的操作选项时,调用
*
* @param application 应用程序
* @param identifier 行为标识
* @param notification 本地通知对象
* @param completionHandler 完成代码块
*/
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
NSLog(@"点击了--%@", identifier);
// 调用系统的完成代码块,告诉系统,已经处理完毕
completionHandler();
}
iOS9 之后还可以附带输入框行为,将输入内容传递给APP,
通过设置 UIUserNotificationActionBehavior属性为UIUserNotificationActionBehaviorTextInput可实现;
回调的代理方法也是带有参数的那个
- (void)application:(UIApplication *)application handleActionWithIdentifier:
(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo
withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)
())completionHandler
取出所有通知对象,以及移除所有通知对象:
NSArray *Notifications = [UIApplication sharedApplication].scheduledLocalNotifications;//取出所有通知对象
[[UIApplication sharedApplication] cancelAllLocalNotifications];//取消所有通知对象
[[UIApplication sharedApplication] cancelLocalNotification:nil];//取消某个通知对象
TIps:
取消图标右上角的数字:
UIApplicationDelegate 代理方法
-(void)applicationDidBecomeActive:(UIApplication *)application
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
获取设置的UUID:
[UIDevice currentDevice].identifierForVendor.UUIDString