本地通知常用来作为本地提醒,提醒用户待办事项,事物提醒,位置提示等功能 iOS 10.0前,本地通知通知使用的是UILocalNotification
,10.0后,苹果推送了专门用户通知提醒的库UserNotificaiton.framework
1.使用 UILocalNotification
在iOS8.0
之前,通知权限默认开启,可直接使用,但是之后想要使用通知功能,必须提示用户开启通知权限,所以首先需要注册通知, 在didFinishLaunchingWithOptions
中
if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) {
// iOS8以后 本地通知必须注册(获取权限)
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:settings];
}
复制代码
接下来我们需要添加通知触发行为,调用本地通知
1.创建本地通知实例
UILocalNotification * localNoty = [[UILocalNotification alloc]init];
复制代码
2.本地通知属性设置
/* 本地通知触发时间 */
localNoty.fireDate = [NSDate dateWithTimeIntervalSinceNow:4.0];
/* 通知提示框 */
localNoty.alertBody = @"提示文本";
/* 通知提示title */
localNoty.alertTitle = @"提示框内容";
/* 通知提示音 */
localNoty.soundName = UILocalNotificationDefaultSoundName;
/* 这里接到本地通知,badge变为1 */
localNoty.applicationIconBadgeNumber = 1;
// 设置额外信息,appdelegate中收到通知,可以根据不同的通知的额外信息确定跳转到不同的界面
localNoty.userInfo = @{@"notifaication":@"我是一条本地推送"};
复制代码
还有其他不常用的属性,如timeZone
时区
repeatInterval
多长时间重复一次:一年,一个世纪,一天..
region
区域 : 传入中心点和半径就可以设置一个区域(如果进入这个区域或者出来这个区域就发出一个通知)
regionTriggersOnce
BOOL 默认为YES, 如果进入这个区域或者出来这个区域 只会发出 一次 通知,以后就不发送了。
alertAction
: 设置锁屏状态下本地通知下面的 滑动来 ...字样 默认为滑动来查看 hasAction
: alertAction的属性是否生效
alertLaunchImage
: 点击通知进入app的过程中显示图片,随便写,如果设置了(不管设置的是什么),都会加载app默认的启动图
alertTitle
: 以前项目名称所在的位置的文字: 不设置显示项目名称, 在通知内容上方 soundName
: 有通知时的音效 ,UILocalNotificationDefaultSoundName默认声音 可以更改这个声音: 只要将音效导入到工程中,调用localNote.soundName = @"111.waw"
3.调用通知
[[UIApplication sharedApplication] scheduleLocalNotification:localNoty];
复制代码
通知发起后,我们需要接受本地通知,一般在AppDelegate
或者其分类中添加实现方法。 一般通知的接受分为三种: 1.前台接收 2.后台未杀死程序进入前台接收 3.程序已经杀死,点击通知消息启动app
针对前两中情况,app的进程仍在运行状态,在didReceiveLocalNotification
方法中,添加执行代码,这里可以通过application
的applicationState
属性来判断当前的运行状态,一般执行的操作是app前台运行弹出提示框,后台执行点击通知进入前台直接执行。可以通过notification.userInfo
来获取发送通知的userInfo
。 针对第三种情况,需要在didFinishLaunchingWithOptions
,程序启动过程中添加执行方法
/* launchOptions: 1.点击图标打开是空的
2.应用间跳转是有值的
3.杀死的应用接收到本地通知,也是有值的
虽然说launchOptions有值,但是他们不同的key有值
*/
if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) { // 如果这个key有值,代表是杀死的程序接收到本地通知跳转
// 查看launchOptions内容
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"本地通知" message:[NSString stringWithFormat:@"%@",launchOptions] delegate:self cancelButtonTitle:@"知道了" otherButtonTitles: nil];
[alert show];
NSLog(@"跳转到指定页面");
}
复制代码
UIApplicationLaunchOptionsLocalNotificationKey
这个属性是启动的时候用来判断启动来源的,Keys used to access values in the launch options dictionary passed to the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods of the app delegate.
具体说明如下
UIApplicationLaunchOptionsURLKey
// A key indicating that the app was launched so that it could open the specified URL.
UIApplicationLaunchOptionsSourceApplicationKey
// A key indicating that another app requested the launch of your app.
UIApplicationLaunchOptionsRemoteNotificationKey
// A key indicating that a remote notification is available for the app to process.
UIApplicationLaunchOptionsLocalNotificationKey
// A key indicating that the app was launched to handle a local notification.
Deprecated
UIApplicationLaunchOptionsAnnotationKey
// A key indicating that the URL passed to your app contained custom annotation data from the source app.
UIApplicationLaunchOptionsLocationKey
// A key indicating that the app was launched to handle an incoming location event.
UIApplicationLaunchOptionsNewsstandDownloadsKey
// A key indicating that the app was launched to process newly downloaded Newsstand assets.
UIApplicationLaunchOptionsBluetoothCentralsKey
// A key indicating that the app was relaunched to handle Bluetooth-related events.
UIApplicationLaunchOptionsBluetoothPeripheralsKey
// A key indicating that the app should continue actions associated with its Bluetooth peripheral objects.
UIApplicationLaunchOptionsShortcutItemKey
// A key indicating that the app was launched in response to the user selecting a Home screen quick action.
UIApplicationLaunchOptionsUserActivityDictionaryKey
// A key indicating that the data associated with an activity that the user wants to continue.
UIApplicationLaunchOptionsUserActivityTypeKey
// A key indicating the type of user activity that the user wants to continue.
复制代码
类似,我们可以用 NSDictionary *remoteUserInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
来处理远程通知。
需要注意一点,发送多条通知,app的角标会一直累加,所以在启动app的时候didFinishLaunchingWithOptions
需要将角标清零
[application setApplicationIconBadgeNumber:0 ];
复制代码
2.使用UserNotificaiton.framework
相关文档参照:developer.apple.com/documentati… 1.首先,我们需要将UserNotifications
引入工程。 然后在AppDelegate.m导入库文件 #import <UserNotifications/UserNotifications.h>
2.授权应用通知权限
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if(!error)
{
NSLog(@"@授权成功");
}
}];
复制代码
之前注册推送服务,ios 8 及之前使用了不同的 API,并且返回结果也不同。现在 apple 不仅统一了这个 API,而且我们可以获取到用户更加详细的设定了。
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@",settings);
}];
复制代码
打印结果如下: <UNNotificationSettings: 0x60400009cd40; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, carPlaySetting: NotSupported, alertSetting: Enabled, alertStyle: Banner>
如果需要注册远程通知:
[[UIApplication sharedApplication] registerForRemoteNotifications];
复制代码
2.发送本地通知 UserNotificaiton
发送本地通知需要使用UNNotificationRequest
类,实例方法如下
+ (instancetype)requestWithIdentifier:(NSString *)identifier content:(UNNotificationContent *)content trigger:(nullable UNNotificationTrigger *)trigger;
复制代码
所以我们需要分别设定 UNNotificationContent
和UNNotificationTrigger
并设置一个标识符。
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"this is Notifications";
content.subtitle = @"本地通知";
content.body = @"推送一条本地通知";
content.badge = @1;
content.userInfo = @{@"type":@"this is a userNotification"};
复制代码
Triggers
又是一个新的功能,有三种
-
UNTimeIntervalNotificationTrigger
-
UNCalendarNotificationTrigger
-
UNLocationNotificationTrigger 他们的使用方式如下:
//8s后提醒
UNTimeIntervalNotificationTrigger *trigger1 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:8 repeats:NO];
//每小时重复 1 次喊我喝水
UNTimeIntervalNotificationTrigger *trigger2 = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3600 repeats:YES];
//每周一早上 8:00 提醒我给起床
NSDateComponents *components = [[NSDateComponents alloc] init];
components.weekday = 2;
components.hour = 8;
UNCalendarNotificationTrigger *trigger3 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];
//需导入定位库 #import <CoreLocation/CoreLocation.h>
//一到距离(123.333, 123.344)点20米就喊我下车
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:CLLocationCoordinate2DMake(123.333, 123.344) radius:20 identifier:@"regionidentifier"];
UNLocationNotificationTrigger *trigger4 = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
复制代码
发出通知
NSString *requestIdentifier = @"sampleRequest";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier
content:content trigger:trigger1];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
}];
复制代码
3.接收本地通知并处理。 与LocalNotificationL类似,有三种情况
(1).前台接收
(2).后台未杀死程序进入前台接收
(3).程序已经杀死,点击通知消息启动app 需要遵循UNUserNotificationCenterDelegate代理协议方法
center.delegate = self;
复制代码
通过以下两个UNUserNotificationCenterDelegate
的方法实现
// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED;
复制代码
实现如下:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
NSLog(@"willPresentNotification:%@",notification.request.content.title);
// 这里真实需要处理交互的地方
// 获取通知所带的数据
NSString *apsContent = [notification.request.content.userInfo objectForKey:@"type"];
NSLog(@"%@",apsContent);
}
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
//在没有启动本App(包括后台运行中)时,收到服务器推送消息,下拉消息会有快捷回复的按钮,点击按钮后调用的方法,根据identifier来判断点击的哪个按钮
NSString *apsContent = [response.notification.request.content.userInfo objectForKey:@"type"];
NSLog(@"didReceiveNotificationResponse:%@",response.notification.request.content.title);
NSLog(@"%@",apsContent);
}
复制代码
我们可已通过removeIdentifier删除计划的推送事件:
[center removePendingNotificationRequestsWithIdentifiers:@[requestIdentifier]];
复制代码
如果我们需要更新推送,可以通过 addNotificationRequest: 方法,在 Identifier
不变的情况下重新添加,就可以刷新原有的推送。