一、准备工作
1、项目中要集成推送,首先要了解推送的原理,虽然3个版本中的推送实现方式不一样,但是原理还是一样的。安卓总是因为推送出问题,由于苹果有自己的推送服务(APNS),所以我觉得苹果的推送比安卓好实现很多。推送分为远程推送和本地推送。远程推送可以看成是客户端,APNS,后台服务器相互关联形成的一个服务;本地推送只是在客户端实现,比如提醒事项,甚至闹钟;
2、远程推送需要我们去申请证书,相信你们都已经知道怎么做了,此处省略几百字;
3、推送的基本流程:
(1)客户端启动,注册推送;
(2)注册成功后,我们可以拿到deviceToken,此时我们把deviceToken发给后台;
(3)我们实现接受到推送的方法,下面会介绍;
(4)需要推送的时候后台会把推送的信息和deviceToken发给APNS;
(5)APNS会在已经注册的deviceToken中查找后台传入的deviceToken;
(6)找到后,发出通知我们就可以接收到了(前提是已经同意接收通知,并且手机是开机状态~~)。
tps:
推送信息的最大长度是255个字符;
二、注册推送
注册推送是在下面的方法中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
1、iOS8以前注册方式:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert];
2、iOS8-iOS10注册方式:
//iOS8的新特性,后台接收到通知侧滑显示选项
UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init]; action1.identifier = @"action_identifier1"; action1.title = @"Accept"; action1.activationMode = UIUserNotificationActivationModeForeground; UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init]; action2.identifier = @"action_identifier2"; action2.title = @"Reject"; action2.activationMode = UIUserNotificationActivationModeBackground; action2.authenticationRequired = YES; action2.destructive = YES; UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init]; categorys.identifier = @"category1"; [categorys setActions:@[action1, action2] forContext:(UIUserNotificationActionContextDefault)];
//注册推送 UIUserNotificationSettings *userSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:[NSSet setWithObject:categorys]]; [[UIApplication sharedApplication] registerForRemoteNotifications]; [[UIApplication sharedApplication] registerUserNotificationSettings:userSettings];
3、iOS10及其以上注册:
在iOS10中,苹果对推送进行了一层封装,需要加入UserNotifications.framework,不然会报错;并且要导入头文件:#import <UserNotifications/UserNotifications.h>,因为iOS10才有这个文件,所以在导入时要加判断,遵循代理UNUserNotificationCenterDelegate。
#ifdef NSFoundationVersionNumber_iOS_9_x_Max #import <UserNotifications/UserNotifications.h> #endif
开始注册:
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; //遵循代理UNUserNotificationCenterDelegate center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error && granted) { NSLog(@"注册成功"); }else{ NSLog(@"注册失败"); } }]; //获取通知授权信息 [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { UNAuthorizationStatusNotDetermined : 没有做出选择 UNAuthorizationStatusDenied : 用户未授权 UNAuthorizationStatusAuthorized :用户已授权 }]; [application registerForRemoteNotifications];
三、获取 deviceToken
在消息注册成功后,会在下面的方法中返回deviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
返回的是data类型,解析的时候看网上很多人说解析失败,我把解析的方法也放上来供大家参考
NSString *token = [NSString stringWithFormat:@"%@", [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<" withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]];
接着我们就需要把获取的token发送给后台。
四、实现接收到通知的方法
1、iOS10以下,userInfo是后台传给APNS的字典,可以直接使用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { }
2、iOS10及以上
在前台的时候调用代理方法:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
{
}
在方法中,返回UNNotification类型的实例notification,我们可以从UNNotification开始逐层点击查看。获取后台传入APNS最终的方法是:
notification.request.content.userInfo
在后台的时候调用代理方法:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED
{
//这个方法必须调用
completionHandler();
}
在方法中,返回UNNotificationResponse类型的实例response,我们可以从UNNotificationResponse开始逐层点击查看发现UNNotification是UNNotificationResponse的一个属性,所以获取后台传入APNS最终的方法是:
response.notification.request.content.userInfo