每一次接推送,每一次必百度。
这次记录下来,方便(我自己)下次开发。
如有不对或缺了啥,请留言告诉我。
那就开始吧。
1.授权
这个简单,直接上代码
if (@available(iOS 10.0, *)) {
// iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
// 必须写代理,不然无法监听通知的接收与点击事件
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
//用户点击允许
NSLog(@"注册成功");
} else {
//用户点击不允许
NSLog(@"注册失败");
}
}];
} else {
// iOS 8 later
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
/// 注意这里注册远程推送
[application registerForRemoteNotifications];
/// 注册成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//保存deviceToken
NSString *deviceTokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"=================================== deviceToken = :%@", deviceTokenString);
}
/// 注册失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
}
2.代理
#pragma mark - iOS 10
#pragma mark - UNUserNotificationCenterDelegate
/// 收到消息
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//远程推送
} else {
//本地推送
}
// Required
// iOS 10 之后 前台展示推送的形式
completionHandler(UNNotificationPresentationOptionAlert);
}
/// 点击推送消息
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
}
#pragma mark - iOS 8
/// iOS 8收到推送之后有两个代理方法
/// iOS 8 收到推送 以及 APP在后台时点击通知都会走这里
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
点进去第一个代理方法 application:didReceiveRemoteNotification:fetchCompletionHandler: 发现这么一段注释:
This method will be invoked even if the application was launched or resumed because of the remote notification. The respective delegate methods will be invoked first. Note that this behavior is in contrast to application:didReceiveRemoteNotification:, which is not called in those cases, and which will not be invoked if this method is implemented.
大概翻译一下:
程序已经启动 或程序因(点击)远程推送而被唤醒,此方法都会被调用.
各自的代理方法会被首先调用.
注意这个行为和 application:didReceiveRemoteNotification: 是相反的,如果实现了此方法,后者在上述两种情况下都不会被调用。
em... 用第一个就对了。
有一个问题,当你的项目添加了信鸽或者极光的SDK之后,尽管你没有调用它们,但是你会发现你写的这些代理都不走了,我猜那是因为被这些SDK拦截了,删除SDK即可。
网友评论