iOS8之前的通知写法在ios8之后会失效,会出现下面的提示,修复方法则是要注册通知(参考下面的示例1代码)
1 Attempting to schedule a local notification
2 with an alert but haven’t received permission from the user to display alerts
3 with a sound but haven’t received permission from the user to play sounds
本地推送简单使用(基于时间)
- 创建本地通知和属性
创建本地推送通知对象
UILocalNotification *ln = [[UILocalNotification alloc] init];
设置本地推送通知属性
推送通知的触发时间(何时发出推送通知)
@property(nonatomic,copy) NSDate *fireDate;
推送通知的具体内容
@property(nonatomic,copy) NSString *alertBody;
在锁屏时显示的动作标题(完整标题:“滑动来” + alertAction)
@property(nonatomic,copy) NSString *alertAction;
音效文件名
@property(nonatomic,copy) NSString *soundName;
app图标数字
@property(nonatomic) NSInteger applicationIconBadgeNumber;
每隔多久重复发一次推送通知
@property(nonatomic) NSCalendarUnit repeatInterval;
点击推送通知打开app时显示的启动图片
@property(nonatomic,copy) NSString *alertLaunchImage;
附加的额外信息
@property(nonatomic,copy) NSDictionary *userInfo;
时区
@property(nonatomic,copy) NSTimeZone *timeZone;
(一般设置为[NSTimeZone defaultTimeZone] ,跟随手机的时区)
案例一
- AppDelegate.m 文件中代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// iOS8 之后, 需要去注册通知配置 (包括了授权的申请)
// 通知配置的注册, UIApplication
// 通知 由iOS系统来完成, 就算App被杀掉, 通知依然可以弹出
/** 可用的效果类型
UIUserNotificationTypeNone = 0, // 不能展示任何UI效果
UIUserNotificationTypeBadge = 1 << 0, // 能够在AppIcon的边缘实现数字
UIUserNotificationTypeSound = 1 << 1, // 可以播放提示音
UIUserNotificationTypeAlert = 1 << 2, // 弹窗效果
*/
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
// UIUserNotificationSettings 表示 通知的配置
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
//开始时注册通知
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
return YES;
}
- ViewController.m 文件中
- (IBAction)addAction:(id)sender
{
// iOS8 之后, 需要去注册通知配置 (包括了授权的申请)
// UILocalNotification 表示 本地通知
// 本地通知, 触发的方式: 基于时间 / 基于位置
// 实例化本地通知
UILocalNotification *notification = [[UILocalNotification alloc] init];
// 配置参数
notification.alertBody = @"OMG VS JJ, 12点准时开开播呦!"; // 通知的具体内容
// NSDateFormatter -> NSDate
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // 通知的触发时间
// alertTitle 会在通知中心 / AppleWatch 看到标题
notification.alertTitle = @"LOL被子"; // 通知的标题
// 通知弹出时的音效
// UILocalNotificationDefaultSoundName 使用手机默认的提示音
// 模拟器没有默认提示音
notification.soundName = UILocalNotificationDefaultSoundName;
// 自定义的音效, 需要是保存在Bundle里面的音效文件的名称
// notification.soundName = @"xiaosheng.mp3";
// 图标的红色边缘数字
notification.applicationIconBadgeNumber = 99;
// [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
// 执行次数
// 本地通知默认只执行一次
// 重复时间间隙, 不能小于分钟
notification.repeatInterval = NSCalendarUnitDay;
// UserInfo 表示 用户的自定义数据
notification.userInfo = @{
@"custom" : @"六味地黄丸",
};
// 让通知等待被调度 ( 由UIApplication完成 )
// 将本地通知添加到 通知调度池 当中
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
// self.notification = notification;
}
// 查看通知的点击事件
- (IBAction)seeAction:(id)sender
{
// 查看当前调度池当中已经添加的通知
NSArray <UILocalNotification *> *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
NSLog(@"调度池: %@", notificationArray);
}
// 移除指定的本地通知
- (IBAction)removeAction:(id)sender
{
// 移除指定的通知
// [[UIApplication sharedApplication] cancelLocalNotification:self.notification];
// 1. 找到指定的通知, 调度池
NSArray <UILocalNotification *> *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (UILocalNotification *notification in notificationArray) {
// 通过UserInfo携带的数据来辨别指定的通知
if (notification.userInfo[@"custom"]) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
}
// 移除所有本地通知
- (IBAction)removeAllAction:(id)sender
{
// 移除本App所添加的通知
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
本地推送的简单使用(基于位置,位置的改变用模拟器设置)
案例2:
- AppDelegate.m 文件中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// iOS8 之后 注册用户配置
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
/*================= 定位授权 =================*/
self.manager = [[CLLocationManager alloc] init];
self.manager.delegate = self;
// 1. 定位服务
// 2. 授权状态
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.manager requestWhenInUseAuthorization];
}
return YES;
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
NSLog(@"授权成功");
}
}
- ViewController.m 文件中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"%s", __func__);
// 添加本地通知
UILocalNotification *notification = [[UILocalNotification alloc] init];
// 配置
notification.alertBody = @"醒老师出书了!";
// notification.fireDate
// 监听地理上的指定区域的时候, 只有Always才能实现 (App 让用户一直可以使用定位)
// 通知的区域监听, 必须通过CoreLocation实现至少when-in-use权限 (系统-用户同意)
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(23.133916, 113.395557) radius:500 identifier:@"ReuseID"];
// 监听指定区域, 在进入/离开的时候会触发相应的通知
notification.region = region;
// YES表示只追踪一次, NO表示多次
notification.regionTriggersOnce = YES;
// 添加到通知调度池中, 等待触发
本地推送_Category
案例3:
- AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
/*================= Category =================*/
// 配置通知的样式类别 (先声明可用类别, 通知再去使用对应的类别)
// UIUserNotificationCategory *category = [[UIUserNotificationCategory alloc] init];
UIMutableUserNotificationCategory *catetory = [[UIMutableUserNotificationCategory alloc] init];
// 唯一标识, 通知会通过 identifier 来使用对应的类别
catetory.identifier = @"category";
/*================= Action =================*/
// UIAlertController -- Action
// UIMutableUserNotificationCategory 当中 Action 表示按钮来实现点击事件
// UIUserNotificationAction 不能修改
UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
action.identifier = @"action1"; // 区分到底点击的是哪个Action
action.title = @"title1"; // 按钮对应的标题
/**
UIUserNotificationActivationModeForeground, // 点击会进入App, App会处于前台状态
UIUserNotificationActivationModeBackground // 不会进入到App, 如果处于后台, 依然处于后台状态
*/
action.activationMode = UIUserNotificationActivationModeForeground;
UIMutableUserNotificationAction *action2= [[UIMutableUserNotificationAction alloc] init];
action2.identifier = @"action2";
action2.title = @"title2";
action2.activationMode = UIUserNotificationActivationModeBackground;
// 为category 配置相关的按钮
[catetory setActions:@[action, action2] forContext:UIUserNotificationActionContextDefault];
/*================= Settings =================*/
NSSet *set = [NSSet setWithObjects:catetory, nil];
// 用户通知配置
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:set];
// 注册用户通知配置
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
return YES;
}
#pragma mark - 直接点击了通知时, 触发的代理方法
// 直接点击了通知, 进入App的时候触发的代理方法
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"直接点击了通知 : %@", notification);
// 做出相对应的处理
}
#pragma mark - 点击了通知上的Category里面的Acton时触发的对应代理方法
// iOS9 新增加
//- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
//{
//
//}
// iOS8 方法
// 不跳转到App / 跳转到App 都会触发访代理方法
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler
{
// identifier 是 Action的identifier, 用来区分多个Action
// notification 触发的本地通知
NSLog(@"点击了通知上的Category上的按钮时: %@, %@", identifier, notification);
// 在处理完相关的事件之后, 需要调用completionHandler 让系统知道你已经处理完
// ... 做自己
completionHandler();
}
- ViewController.m 文件中
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = @"帅哥好帅";
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];
// 应用在通知配置里面已经注册好的Category
// Category的identifier, 该Category必须在用户通知配置里进行了注册
notification.category = @"category";//没有指定通知的显示类型就会使用默认的类型
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}