苹果的在iOS 10 中将通知相关的API统一成了UserNotifications.framework
。在新的UserNotifications.framework
中,苹果还增加了撤回单条通知,更新已展示同比,中途修改通知内容,在通知中展示图片、视频,自定义通知UI等一系列新功能。
iOS 10中使用远程推送
在Project
-> Project Setting
- > Capabilities
, 打开 Push Notifications
开关。
注册通知
注册通知在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
方法里。
iOS 10
使用- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler;
方法来注册通知。
导入 #import <UserNotifications/UserNotifications.h>
// 使用 UNUserNotificationCenter 来管理通知
UNUserNotificationCenter *uncenter = [UNUserNotificationCenter currentNotificationCenter];
// 监听回调事件
[uncenter setDelegate:self];
[uncenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert+UNAuthorizationOptionBadge+UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
NSLog(@"%@" , granted ? @"授权成功" : @"授权失败");
}];
// 获取当前的通知授权状态, UNNotificationSettings
[uncenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%s\nline:%@\n-----\n%@\n\n", __func__, @(__LINE__), settings);
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
NSLog(@"未选择");
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
NSLog(@"未授权");
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
NSLog(@"已授权");
}
}];
上面的方法只在ios 10
中有效, 所以要想兼容之前的版本,还是需要适配
- (void)registerForRemoteNotification {
// iOS10 兼容
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
// 使用 UNUserNotificationCenter 来管理通知
UNUserNotificationCenter *uncenter = [UNUserNotificationCenter currentNotificationCenter];
// 监听回调事件
[uncenter setDelegate:self];
[uncenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert+UNAuthorizationOptionBadge+UNAuthorizationOptionSound)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
NSLog(@"%@" , granted ? @"授权成功" : @"授权失败");
}];
// 获取当前的通知授权状态, UNNotificationSettings
[uncenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%s\nline:%@\n-----\n%@\n\n", __func__, @(__LINE__), settings);
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
NSLog(@"未选择");
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
NSLog(@"未授权");
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
NSLog(@"已授权");
}
}];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
UIUserNotificationType types = UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
UIRemoteNotificationType types = UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
}
#pragma clang diagnostic pop
}
注册结果的回调还是AppDelegate
的代理方法。
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSString *dt = [token stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
NSString *dn = [dt stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
TheRuntime.pushToken = [dn stringByReplacingOccurrencesOfString:@" " withString:@""];
DDLog(@"deviceToken____: %@",TheRuntime.pushToken);
}
//查看推送功能是否失败
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSString *error_str = [NSString stringWithFormat: @"%@", error];
DDLog(@"Token Error: %@",error_str);
}
响应通知
iOS 10 之前版本
在iOS 10
之前的版本中,当应用是被通知打开的时候,可以通过 application:didFinishLaunchingWithOptions:
方法的 launchOptions
参数所使用的 dictionary
访问到数据:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
. . .
if ([[UIDevice currentDevice].systemVersion floatValue] < 10.0) {
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (notificationPayload) {
NSLog(@"%@",notificationPayload);
}
}
return YES;
}
如果当通知到达的时候,你的应用已经在运行,通过 application:didReceiveRemoteNotification:fetchCompletionHandler:
方法的 userInfo
参数所使用 dictionary
访问到数据:
// Required for iOS 7+
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//处理远程推送内容
NSLog(@"iOS7及以上系统,收到通知:%@", userInfo);
}
iOS10 以上需要使用下面代理方法来获得 userInfo
:
// 在前台收到推送内容, 执行的方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSDictionary *userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//TODO:处理远程推送内容
NSLog(@"%@", userInfo);
}
// 需要执行这个方法,选择是否提醒用户,有 Badge、Sound、Alert 三种类型可以选择设置
completionHandler(UNNotificationPresentationOptionAlert);
}
// 在后台和启动之前收到推送内容, 点击推送内容后,执行的方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//TODO:处理远程推送内容
NSLog(@"%@", userInfo);
}
completionHandler();
}
最后附上2篇参考文章: