iOS 10 之后 终于不用再适配 iOS 7了,如果再适配的话,光推送就要写3套。当然我们说的不算,老板说的算。
好了,废话不多说。直接进入主体。
代码开始前的设置
iOS 10 的推送 与原来的都不一样,他把本地的推送 跟 远程的推送结合到一起了,UserNotifications.framework 库。在使用推送的时候,先开启通知的开关。
就是上面这个。当你开启后,xcode 会自动帮你在 项目里面创建一个文件,xxxx.entitlements.
这个文件是系统帮你创建的,不用管它。
在appledata 文件里面需要先导入 UNUserNotificationCenterDelegate 这个代理。他的代理方法分别是:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0)
开始写代码
注册通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 10.0)
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:UNAuthorizationOptionCarPlay | UNAuthorizationOptionSound | UNAuthorizationOptionBadge | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@" iOS 10 request notification success");
}else{
NSLog(@" iOS 10 request notification fail");
}
}];
}
else if (version >= 8.0)
{
UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil];
[application registerUserNotificationSettings:setting];
}
//注册通知
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
因为我这个项目是新建的项目,xcode 默认只适配到 iOS 8 ,想适配 iOS 7 的话,可以在 else 后面继续添加:
else
{
UIRemoteNotificationType type = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:type];
}
上面注意 一定不要忘记添加这一句: [[UIApplicationsharedApplication]registerForRemoteNotifications];
获取通知的token
获取推送的token方法跟之前一样
#pragma mark 注册推送的token
//获取token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [deviceToken description]; //获取
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];
token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
NSLog(@"request notificatoin token success. %@",token);
}
//注册失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"request notification Token fail. %@",error.localizedDescription);
}
注意,在把NSData 转化为NSString 的时候,不能使用 [[NSStringalloc]initWithData:deviceTokenencoding:NSUTF8StringEncoding ]; 这个方法,同时,使用系统json 解析 [NSJSONSerialization JSONObjectWithData:deviceToken options:kNilOptions error:&error]; 也失败了。错误原因为 是不正确的解析格式。
我们先用 NSString *token = [deviceTokendescription]; 获取token字符串。我在文章《iOS 10 NSData 转化NSString 失败》中描述了。
获取推送的信息
还记得我们之前说的UNUserNotificationCenterDelegate 代理吗?我搜索的是:
#pragma mark iOS 10 获取推送信息 UNUserNotificationCenterDelegate
//APP在前台的时候收到推送的回调
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
UNNotificationContent *content = notification.request.content;
NSDictionary *userInfo = content.userInfo;
[self handleRemoteNotificationContent:userInfo];
//可以执行设置 弹窗 和 声音
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}
//APP在后台,点击推送信息,进入APP后执行的回调
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
UNNotificationContent *content = response.notification.request.content;
NSDictionary *userInfo = content.userInfo;
[self handleRemoteNotificationContent:userInfo];
completionHandler();
}
- (void)handleRemoteNotificationContent:(NSDictionary *)userInfo
{
NSLog(@" iOS 10 after Notificatoin message:\n %@",userInfo);
}
这个应该就是获取推送信息的回调方法,但是我在测试的时候发现,上面的方法没有执行,你自己也可以加断点测试一下。
我使用 iOS 10 之前的获取推送信息的方法。
#pragma mark iOS 10 之前 获取通知的信息
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"iOS 10 before Notification message。\n %@",userInfo);
}
则能够获取推送的信息。暂时不知道是什么原因。
至此,我们的 iOS 10 项目能够获取到推送的信息了。