iOS 8 pushkit使用总结

最近项目要做关于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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容