远程推送流程概述
iOS远程推送是通过deviceToken进行的,拿到deviceToken需要注册远程通知,注册成功系统提供回调方application:didRegisterForRemoteNotificationsWithDeviceToken:
返回deviceToken,拿到deviceToken后直接发送给推送服务器(可以是三方推送服务器或者公司服务端搭建的推送服务器),此时对于客户端而言,只需要在接收远程通知的代理方法中application:didReceiveRemoteNotification:
处理接收到的通知即可
远程推送注册说明
iOS8以前的远程通知设置就是注册(registerForRemoteNotificationTypes:)
,iOS8以后远程通知设置仅仅是用户授权请求(registerUserNotificationSettings:)
,经用户授权成功才可以进行远程通知注册,授权成功系统会提供回调只需要在回调代理方法application:didRegisterUserNotificationSettings:
中进行远程通知注册[application registerForRemoteNotifications]
即可
远程推送代码实现
1、远程通知授权
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//如果使用第三方,通常需要在这里启动三方的sdk
// 注册APNS远程通知设置
// iOS8以上注册远程通知授权,授权成功才会去注册远程通知
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 ||
[UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
// 定义用户通知类型(Remote.远程 - Badge.标记 Alert.提示 Sound.声音)
UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
// 定义用户通知设置
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
// 注册用户通知 - 根据用户通知设置
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else { // iOS8.0 以前不需要授权,直接注册远程通知
// 定义远程通知类型(Remote.远程 - Badge.标记 Alert.提示 Sound.声音)
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
// 注册远程通知 -根据远程通知类型
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
}
return YES;
}
//iOS10和xcode8的改动
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//如果使用第三方,通常需要在这里启动三方的sdk
// 注册APNS远程通知设置
/*
警告:Xcode8 需要手动开启"TARGETS -> Capabilities -> Push Notifications"
*/
/*
警告:该方法需要开发者自定义,以下代码根据 APP 支持的 iOS 系统不同,代码可以对应修改。
以下为演示代码,注意根据实际需要修改,注意测试支持的 iOS 系统都能获取到 DeviceToken
*/
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8编译会调用
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (!error && granted) {
NSLog(@"request authorization succeeded!");
} else {
NSLog(@"request authorization 注册失败");
}
}];
[[UIApplication sharedApplication] registerForRemoteNotifications];
#else // Xcode 7编译会调用
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
#endif
} else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeBadge);
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
}
}
2、授权成功注册远程通知
//这个也是iOS8以后的方法,需要配合上面的注册方法registerUserNotificationSettings
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
// 注册远程通知
[application registerForRemoteNotifications];
}
3、获取deviceToken(注册远程通回调)
//注册远程通知成功回调
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
// 将deviceToken的发送到服务器,如果使用三方推送,将deviceToken发送给三方服务器
}
//注册远程通知失败回调
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
}
4、接收远程通知
//iOS8以前接收远程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//处理通知
}
//iOS8以后接收远程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
//处理通知
//最后必须回调 completionHandler
completionHandler(UIBackgroundFetchResultNewData);
}