内容简介:由于最近项目要做关于voip业务,所以在此做个记录:我们都知道当应用程序退出到后台时,socket是会断开连接,程序是被挂起的。我们现在要做的就是在这种情况下直接唤醒APP。PushKit是苹果在ios8苹果新引入的框架,一种新的push通知类型,被称作voip push.该push方式旨在提供区别于普通APNs push的能力,PushKit区别与普通APNS的地方是,它不会弹出通知,而是直接唤醒你的APP,进入回调,也就是说,可以在没点击APP启动的情况下,就运行我们自己写的代码.PushKit框架将特
由于最近项目要做关于voip业务,所以在此做个记录:我们都知道当应用程序退出到后台时,socket是会断开连接,程序是被挂起的。我们现在要做的就是在这种情况下直接唤醒APP。
PushKit背景
PushKit是苹果在ios8苹果新引入的框架,一种新的push通知类型,被称作voip push.该push方式旨在提供区别于普通APNs push的能力,PushKit区别与普通APNS的地方是,它不会弹出通知,而是直接唤醒你的APP,进入回调,也就是说,可以在没点击APP启动的情况下,就运行我们自己写的代码.
PushKit框架将特定类型的通知(例如VoIP邀请,watchOS复杂性更新和文件提供程序更改通知)直接发送到您的应用程序以进行处理。
PushKit通知与您使用UserNotifications框架处理的通知不同。具体来说,PushKit通知从不显示警报,标记应用程序的图标或播放声音。与用户通知相比,它们还具有以下优势:
- 设备仅在收到PushKit通知时才会唤醒,这可以延长电池寿命。
- 收到PushKit通知后,如果应用程序未运行,系统会自动启动它。相比之下,用户通知无法保证启动您的应用。
- 系统会为您的应用执行时间(可能在后台)处理PushKit通知。
- PushKit通知可包含比用户通知更多的数据。
在PushKit中最主要用到的就是PKPushRegistey这个类,首先我们来分析一下这个类里面的内容:
/* 目标推送类型 */ PK_EXPORT PKPushType const PKPushTypeVoIP NS_AVAILABLE_IOS(8_0); //VOIP推送 PK_EXPORT PKPushType const PKPushTypeComplication NS_AVAILABLE_IOS(9_0); //Watch更新 PK_EXPORT PKPushType const PKPushTypeFileProvider NS_AVAILABLE_IOS(11_0); //文件传输 NS_CLASS_AVAILABLE_IOS(8_0) @interface PKPushRegistry : NSObject @property (readwrite,weak,nullable) id<PKPushRegistryDelegate> delegate; //代理对象 @property (readwrite,copy,nullable) NSSet<PKPushType> *desiredPushTypes; //获取本地缓存的Token 申请Token执行回调后 这个方法可以直接获取缓存 - (nullable NSData *)pushTokenForType:(PKPushType)type; //初始化,并设置工作线程 - (instancetype)initWithQueue:(nullable dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER; @end @protocol PKPushRegistryDelegate <NSObject> @required //申请Token更新后回调方法 - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type; @optional //收到推送后执行的回调方法 - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type NS_DEPRECATED_IOS(8_0, 11_0); //同上,收到推送后执行的回调方法,最后的block需要在逻辑处理完成后主动回调 - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void(^)(void))completion NS_AVAILABLE_IOS(11_0); //Token失效时的回调方法 - (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type; @end NS_ASSUME_NONNULL_END 复制代码
PushKit证书申请
跟APNs push类似,PushKit的voip push也需要申请证书的,申请证书步骤如下:
按申请步骤操作就可以完成,相信大家都有申请证书的经验,在这里就不多嘴了。 生成正式之后把它下载,双击安装到KeyChain中即可,这里需要在KeyChain里把VoIP证书的密钥导出成.p12格式,发给你的后台人员。(这里关于后台具体使用的证书格式,根据情况而定,我们通常是把.p12文件经过nodes命令生成.pem文件给后台使用)
项目配置
和APNS一样,需要在Project-> Capabilities里打开推送开关和配置后台,Background Modes里把Voice over IP选项打开,同时把Background fetch ,Remote notification选项一起打开,并在Build Phases中加入PushKit.framework。
据说Xcode9的Background Modes中是没有Voice over IP这个选项的,(我用的是Xcode10.2,还是有这个选项的)如果没有的话,可以手动在info.plist文件中加入,在Required background modes里面添加一项 App provides Voice over IP services。
简单代码实现
在AppDelagate中需要导入PushKit框架#import <PushKit/PushKit.h> 注册PushKit,注意PushKit要ios8 及以后才可以使用, 添加代理PKPushRegistryDelegate
if (CurrentSystemVersion.floatValue >= 8.0) { PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil]; pushRegistry.delegate = self; pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; } 复制代码
实现获取token的代理方法:
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type { NSString * tokenString = [[[[credentials.token description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""] stringByReplacingOccurrencesOfString: @" " withString: @“"]; } 复制代码
设备从苹果服务器获取到了VoIP token,这个token与APNs是不一样的。app将收到的token传递给push服务器。(流程和APNs类似,但是接受的代理方法和token都是不一样的)获取到的token也是64位的,与APNs一样,需要去掉<>和空格。
做接收到推送的处理
// iOS 8.0~11.0 - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type { NSLog(@"收到push"); NSDictionary *dic=payload.dictionaryPayload[@"aps"]; UIUserNotificationType theType = [UIApplication sharedApplication].currentUserNotificationSettings.types; if (theType == UIUserNotificationTypeNone){ UIUserNotificationSettings *userNotifySetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:userNotifySetting]; } UILocalNotification *backgroudMsg = [[UILocalNotification alloc] init]; backgroudMsg.timeZone = [NSTimeZone defaultTimeZone]; backgroudMsg.alertBody= [dic objectForKey:@"alert" ]; backgroudMsg.soundName = [dic objectForKey:@"sound"]; [[UIApplication sharedApplication] presentLocalNotificationNow:backgroudMsg]; } 复制代码
查看PKPushRegistry.h的文件,在iOS8.0~iOS11.0是使用上面这个代理方法来实现唤醒后的操作,但在iOS11.0之后,系统也提供了另外一个方法:
//iOS 11.0之后 - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void(^)(void))completion 复制代码
如果一切正常,就算程序杀掉进程,重启,退到后台,服务器推送过来的消息都会走这个代理方法,在这里为了能看到推送的内容,这里我是把接收到的内容生成一个本地的推送发出来了,并且播放声音,实际上在这个方法里面应该处理唤醒APP之后的操作。
推送测试
在这里我在做推送测试的时候使用的是Easy APNs Provider这个应用,使用起来还是很方便的。 附上下载地址
1.首先要添加所要发送的Token值,这里有三种添加方式:
2.然后并选择之前创建好的voip_services.cer证书,
3.连接至服务器,Debug模式选择sandbox,Release模式选择push,
之后点击“连接至”按钮,查看是否连接成功。
4.设置发送的内容(推送负载)
5.点击“发送推送”。
以上所述就是小编给大家介绍的《iOS : PushKit的使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- RecyclerView使用指南(一)—— 基本使用
- 如何使用Meteorjs使用URL参数
- 使用 defer 还是不使用 defer?
- 使用 Typescript 加强 Vuex 使用体验
- [译] 何时使用 Rust?何时使用 Go?
- UDP协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。