携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
APNS
一、简述APNS
APNS全称是Apple Push Notification service(苹果推送通知服务) 。是苹果工程师们的杰作。早期iOS设备CPU和内存资源有限,为节约资源,系统不允许app进程常驻后台,但是开发商需要有一个稳定的网络通道能每隔一段时间推送新的内容到用户设备,就是这个矛盾催促了apns的诞生。
二、APNS机制
apns的机制,官网上一张图,已经说明了一切~
\
apns推送机制
三、APNS的限制
能够有效收到apns推送,首先必须要确保设备处于online的状态。其次苹果只会存储发送给用户一条最新的推送,之前发送的推送会被舍弃。而且每条离线推送是有过期时间的。苹果apns服务器每天要处理至少几十亿设置上百亿条推送消息,所以偶然的一次推送不成功,就不要纠结了~
四、申请APNS推送证书
apns推送证书
如上图所示,apns推送有生产证书和发布证书两种,一般生产证书比较少会使用(前期与后台调试使用,只能直推,可真机测试)。发布证书是上线使用的,根据发布证书生成p12文件,与配置文件一起发给后台即可。
这里提一下,有使用推送功能的小伙伴,别忘了勾选上appid设置里的Push Notifications。
五、代码设置
- 在didFinishLaunchingWithOptions方法里注册apns推送。
**
UIApplication *application = [UIApplication sharedApplication]; application.applicationIconBadgeNumber = 0; if (IOS10) { //iOS10+ UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (!error) { NSLog(@"succeeded!"); } }]; [application registerForRemoteNotifications]; } else if (IOS8_10){ //iOS8-iOS10 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil]; [application registerUserNotificationSettings:settings]; [application registerForRemoteNotifications]; } else { //iOS8以下 [application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; }
- 在didRegisterForRemoteNotificationsWithDeviceToken方法里获取apns的deviceToken。
**
// 1.获取deviceToken,并去除非法字符 NSString *deviceTokenStr = [[deviceToken description] stringByReplacingOccurrencesOfString:@" " withString:@""]; deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@"<" withString:@""]; deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@">" withString:@""]; // 2.保存deviceToken NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName]; [groupDefault setValue:checkValue(deviceTokenStr) forKey:EUCDeviceTokenKey]; [groupDefault synchronize];
- 在didFailToRegisterForRemoteNotificationsWithError方法里清空问题deviceToken。
**
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName]; [groupDefault setValue:checkValue(@"") forKey:EUCDeviceTokenKey]; [groupDefault synchronize];
- iOS8在didRegisterUserNotificationSettings方法里注册推送。
**
[application registerForRemoteNotifications];
- 在didReceiveRemoteNotification方法里做跳转处理,本地推送也会执行此方法。
VoIP
一、简述VoIP
VOIP全称voice-over-ip,是iOS8新引入的一种推送方式类型。它可以使用户收到一个来电时唤醒App。有了这种新推送,麻麻再也不用担心App长时间在后台被系统杀死的问题了,因为这种推送消息可以在后台唤醒App。
二、申请VoIP推送证书
voip推送证书
VoIP推送证书只有发布证书,所以调试起来是个问题。小伙伴在处理这个问题上一定要有耐心。
三、xcode配置
- xcode9之前配置主target下capabilities的Background Modes\
VoIP配置2 - xcode9+ 配置plist文件\
VoIP配置1 - Link Binary With Libraries里引入PushKit系统动态库
\
引入系统库
四、代码设置
- 在didFinishLaunchingWithOptions方法里注册VoIP推送
**
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()]; pushRegistry.delegate = self; pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; }
- 在pushKit回调方法didUpdatePushCredentials里获取VoIP的deviceToken
**
// 1.获取deviceToken,并去除非法字符 NSString *deviceTokenStr = [[credentials.token description] stringByReplacingOccurrencesOfString:@" " withString:@""]; deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@"<" withString:@""]; deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@">" withString:@""]; // 2.本地保存deviceToken NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName]; [groupDefault setValue:checkValue(deviceTokenStr) forKey:EUCDeviceTokenKey]; [groupDefault synchronize];
- 在pushKit回调方法didInvalidatePushTokenForType里清除问题deviceToken
**
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName]; [groupDefault setValue:checkValue(@"") forKey:EUCDeviceTokenKey]; [groupDefault synchronize];
- 在pushKit回调方法didReceiveIncomingPushWithPayload处理VoIP推送。一般做本地推送处理或者结合callKit弹出电话页面。