最近项目要作关于voip业务,咱们都知道苹果后台是一个假后台,当程序退出到后台时,socket是会断开链接,程序是被挂起的。咱们要作的就是相似QQ 微信那种,在程序退到后台时,有电话来时弹出一个通知。要了解pushkit概述请参考下面链接php
百度某大神的博客http://blog.csdn.net/openglnewbee/article/details/44807191java
建立完成后下载 双击安装就好了。ios
#import <PushKit/PushKit.h>
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.实现代理方法1json
- (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的值是不一样的,注意不要搞混了。微信
实现代理方法2app
- (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的优势socket
1.应用的voip长链接不保持,在收到呼叫或者发起呼叫时再链接;
2.当呼叫发送到voip 服务器时,对端若不在线,经过voip 服务器链接到pushserver向对端发push通知;
3.应用收到voip push通知时,迅速完成注册;
4.呼叫方经过延时操做等逻辑(复杂一点对voip服务器进行改造,被叫链接上来之后通知到主叫侧),再次发起呼叫,通话即成功创建。post
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文件导出
右键导出文件便可。
.pem文件导出稍微复杂
pushkit使用就到这里结束了,是否是很简单呢,赶忙来一块儿愉快玩耍吧。附上使用截图