iOS 8 pushkit使用总结

作者: 北海有鱼w | 来源:发表于2016-05-27 12:06 被阅读9514次

    最近项目要做关于voip业务,我们都知道苹果后台是一个假后台,当程序退出到后台时,socket是会断开连接,程序是被挂起的。我们要做的就是类似QQ 微信那种,在程序退到后台时,有电话来时弹出一个通知。要了解pushkit概述请参考下面连接

    百度某大神的博客http://blog.csdn.net/openglnewbee/article/details/44807191

    • 1.证书创建
      首先创建voip证书
      0AF8B321-63B9-40CD-88D0-8D782603CB5E.png
      67DAF714-175D-4BB6-A390-258869E22ACF.png
      一步一步往下创建,最后生成下载证书双击安装到钥匙串。
      当安装到钥匙串完成后, 注意:我们还需要另外创建一个配置文件
    7D841F9B-4B15-4809-A7A6-D9149C075538.png ![Uploading CBD67474-28EC-412D-94DD-7F2DD75E1071_112078.png . . .]

    创建完成后下载 双击安装就行了。

    • 2.接下来上代码
    1. 需要导入push kit框架#import <PushKit/PushKit.h>
    2. 注册通知与pushkit,pushkit要ios8 及以后才可以使用
     if (CurrentSystemVersion.floatValue >= 8.0) {
                UIUserNotificationSettings *userNotifiSetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
                [[UIApplication sharedApplication] registerUserNotificationSettings:userNotifiSetting];
                PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
                pushRegistry.delegate = self;
                pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
            }
    

    3.实现代理方法1

    - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
      NSString *str = [NSString stringWithFormat:@"%@",credentials.token];
      _tokenStr = [[[str stringByReplacingOccurrencesOfString:@"<" withString:@""]
                   stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
    } //这个代理方法是获取了设备的唯tokenStr,是要给服务器的
    

    与apns推送不同,pushjit的token获取跟apnstoken的获取方法不同,apps在

    - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
        [application registerForRemoteNotifications];//必须先实现这个方法,才会走下面的方法
    }
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
        NSLog(@"%@",[[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]                  stringByReplacingOccurrencesOfString: @">" withString: @""]                 stringByReplacingOccurrencesOfString: @" " withString: @""]);
        
        NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
        //获取终端设备标识,这个标识需要通过接口发送到服务器端,服务器端推送消息到APNS时需要知道终端的标识,APNS通过注册的终端标识找到终端设备
        NSLog(@"%@",token);
    }
    

    获取设备的token,这两个token的值是不同的,注意不要搞混了。

    实现代理方法2

    - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pancal) name:@"precancel" object:nil];
        NSDictionary *dic = [self jsonToDictionary:[[payload.dictionaryPayload objectForKey:@"aps"] objectForKey:@"alert"]];
        if ([[dic objectForKey:@"cmd"] isEqualToString:@"precall"]) {
            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];
            if (backgroudMsg) {
                backgroudMsg.timeZone = [NSTimeZone defaultTimeZone];
                backgroudMsg.alertBody = @"门口机来电";
                backgroudMsg.alertAction = @"查看";
                //设置通知的相关信息,这个很重要,可以添加一些标记性内容,方便以后区分和获取通知的信息
                NSDictionary *infoDic = [NSDictionary dictionaryWithObject:@"name" forKey:@"key"];;
                backgroudMsg.userInfo = infoDic;
                [[UIApplication sharedApplication] presentLocalNotificationNow:backgroudMsg];
                [self cerateAVAudioPlayer];
            }
        }else if ([[dic objectForKey:@"cmd"] isEqualToString:@"precancel"]){
            [[NSNotificationCenter defaultCenter] postNotificationName:@"precancel"
                                                                object:nil];
            [self pancalStopSound];
    }
    

    如果一切正常,就算程序杀掉进程,重启,退到后台,服务器推送过来的消息都会走代理方法2,在这里我们可以做一些处理,我这里是弹出了一个本地通知,并且播放提示音效。

    使用push kit的优点

    1.应用的voip长连接不保持,在收到呼叫或者发起呼叫时再连接;
    2.当呼叫发送到voip 服务器时,对端若不在线,通过voip 服务器连接到pushserver向对端发push通知;
    3.应用收到voip push通知时,迅速完成注册;
    4.呼叫方通过延时操作等逻辑(复杂一点对voip服务器进行改造,被叫连接上来以后通知到主叫侧),再次发起呼叫,通话即成功建立。

    java后台服务器搭建

    public static void main(String[] args) throws Exception 
    {
            try
            {
                //从客户端获取的deviceToken,在此为了测试简单,写固定的一个测试设备标识。
               String deviceToken = "df779eda 73258894 5882ec78 3ac7b254 6ebc66fe fa295924 440d34ad 6505f8c4"
                System.out.println("Push Start deviceToken:" + deviceToken);
                //定义消息模式
                PayLoad payLoad = new PayLoad();
                payLoad.addAlert("this is test!");
                payLoad.addBadge(1);//消息推送标记数,小红圈中显示的数字。
                payLoad.addSound("default");
                //注册deviceToken
                PushNotificationManager pushManager = PushNotificationManager.getInstance();
                pushManager.addDevice("iPhone", deviceToken);
                //连接APNS
                String host = "gateway.sandbox.push.apple.com";
                //String host = "gateway.push.apple.com";
                int port = 2195;
                String certificatePath = "c:/PushTest.p12";//前面生成的用于JAVA后台连接APNS服务的*.p12文件位置
                String certificatePassword = "123456";//p12文件密码。
                pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
                //发送推送
                Device client = pushManager.getDevice("iPhone");
                System.out.println("推送消息: " + client.getToken()+"\n"+payLoad.toString() +" ");
                pushManager.sendNotification(client, payLoad);
                //停止连接APNS
                pushManager.stopConnection();
                //删除deviceToken
                pushManager.removeDevice("iPhone");
                System.out.println("Push End");
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
    }
    }
    

    注意: 用java搭建的后台服务器我们需要提供给服务器.p12文件,用php搭建的服务器我们需要给服务器提供.pem文件

    .p12文件导出

    DA909015-E4C2-479D-A27B-46E700428C7A.png

    右键导出文件即可。

    .pem文件导出稍微复杂

    参考 简书作者《iOS原生APNS推送之PHP后台的pem证书制作流程》

    pushkit使用就到这里结束了,是不是很简单呢,赶紧来一起愉快玩耍吧。附上使用截图

    IMG_0013(2).PNG

    相关文章

      网友评论

      • 西门淋雨:如何同时使用apns和pushkit?打包的时候证书到底选择apns的证书还是voip的证书啊?这个是怎么处理的啊?
      • 7206e1a4637c:您好,为什么测试环境可以收到voip 推送,但是生产环境收不到推送呢?
        humouroutlaw:请问你在后台超过3分钟 还能唤醒app吗?
      • 865020e67958:这个重新生成的配置文件跟原来创建的开发配置文件有啥区别啊
      • 14a07d8f2018:请问可以私聊吗?我现在遇到了点问题
      • liuyun333:你好,请问为什么我按照你的配置但是获取不到token
        9a6f4c00fe70:會不會是 capabilities 的 push notification 沒打開呢?
      • 我贼稳:iPhone 5s获取不到token,PushKit对设备型号也有限制吗
      • 0271fb6f797c:voip 推送 和 apns 推送能一起使用吗? 不是只能选择一个吗? 这个voip推送和静默推送 是不是很像啊?有什么区别吗?
      • 不董_:大兄弟,我这做了设置,证书也搞了,就是收不到推送消息,是为啥啊?
        小米咸鱼:我也是,你解决了吗
      • no1ever:apns 和pushkit能同时使用吗
        北海有鱼w:@no1ever 第一,查一下服务器有没有发出消息,第二,证书问题
        no1ever:@394e6f841540 为什么我app杀掉。- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type不执行。我在里面做了本地通知测试,结果没看到本地的消息
        北海有鱼w:@no1ever 可以的
      • 3f58e786b546:那么可以一样挂在 极光咯
      • 18516f36aa1f:请问如果是普通app,没有voip的功能,能使用pushkit么?
        北海有鱼w:@idcy 不能 ,好像不行
      • 若雨千寻:配置文件是两个环境都要从新生成吗?
        北海有鱼w:@若雨千寻 是的
      • JornyQi:你好,有demo 吗?1024399113@qq.com
      • 梦随兴飞:你好,我也在做方面,这个voip的推送通知和原来的推送通知给服务端生成p12是方法是一样的 吗?我的服务端是.net的,和你说的java 不一样。
      • 一叶菜:你好,我有个问题想请教一下你。voip在测试环境用生成的生产环境的voip证书吗?还是用什么证书提供给后台呢?麻烦有时间回复我一下,谢谢!
        这个算什么:pushkit没有开发环境的证书,但是生产环境的证书可以设置推给开发环境还是生产环境,设置请求的苹果服务器地址不一样。
        相见是为了再分:现在问题解决了吗,现在在做pushkit遇到了问题。求教
        WTG:@一叶菜 voip只有生产环境的没有开发环境的,直接给生产环境的给后台就行了
      • IAM121:哥们,能方便留个联系方式么,能私下交流一下么?

      本文标题:iOS 8 pushkit使用总结

      本文链接:https://www.haomeiwen.com/subject/dsrbrttx.html