最近做一个门铃项目,需要voip的方式通知客户端,需要用到pushkit来进行推送,首先这里讲一下如何制作后台所需要的.pem文件。
1.点击 “Certificates -> All” ,在 iOS Certificates界面,点击右上角的加号;
2.选择 Production -> VoIP Services Certificate,点击 “Continue”;
3.选择应用对应的App ID,然后点击 “Continue”;
4.点击 "Create Certificate",这时候会提示需要 Certificate Signing Request(CSR),用证书助理生成一个CSR文件即可。
5.回到Apple Developer页面,点击 "Continue",上传生成的 .certSigningRequest文件,点击 “Generate”,即可生成推送证书;
6.将刚才创建的证书下载到本地,然后双击打开,这时候系统会将其导入钥匙串中。 我们再打开钥匙串应用,选中对应的证书,右键选择导出,设置好密码然后导出到本地这样我们就得到了voip.cer文件
7.进入钥匙串,上边选择登录,下边选证书,找到刚才安装在钥匙串中的的voip.cer,右击选择到处voip.p12文件。
8.创建一个文件夹,随意命名,将voip.cer和voip.p12文件放入文件夹中
9.打开电脑的命令终端,进入(cd 文件夹名字)存储 voip.cer和voip.p12的文件夹
10.分别执行下列命令,最终生成.pem文件 ps:所有的文件名皆可以自定义,后缀不可随意更改
openssl x509 -in voip.cer -inform der -out PushVoipCert.pem
openssl pkcs12 -nocerts -out PushVoipKey.pem -in voip.p12
cat PushVoipCert.pem PushVoipKey.pem > xbell.pem
这三句命令会生成3个.pem,选择最后一个.pem文件给服务端即可
然后我们需要测试一下,我们需要一个php文件,内容如下
<?php
// Put your device token here (without
$deviceToken = '设备deviceToken';
// Put your private key's passphrase here:
$passphrase = 'pem证书的密码';
// Put your alert message here:
$message = '推送的信息';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create([
'ssl' =>[
'verify_peer' =>false,
'verify_peer_name' => false
]
]);
stream_context_set_option($ctx, 'ssl', 'local_cert', '你的pem证书.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
// Create the payload body
$body['aps'] = array(
'event' => 'push',
'alert' => $message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>
这样我们后台工作就已经完成了!下面我们只需要在AppDelegate中注册一下通知,就可以愉快的收到通知啦!直接上代码
1、首先注册一下通知
-(void)registerVoipAndLocationNotifications{
if ([UIDevice currentDevice].systemVersion.doubleValue >= 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];
}
if (@available(iOS 10.0, *)) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
NSLog(@"request authorization succeeded!");
}
}];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"%@",settings);
}];
}
}
2、设置一下通知回调
别忘了加
<PKPushRegistryDelegate,UNUserNotificationCenterDelegate>
UILocalNotification *_callNotification;
UNNotificationRequest *_request;//ios 10
进入正题,代理方法如下
//当VoIP推送过来会调用此方法,一般在这里调起本地通知实现连续响铃、接收视频呼叫请求等操作
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {//应用程序运行在前台,目前接收事件。
//这里可以直接执行你需要做的事
}else if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive){//应用程序运行在前台但不接收事件。这可能发生的由于一个中断或因为应用过渡到后台或者从后台过度到前台。
}else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground){
//应用程序在后台
//直接响铃
[self beginCallingWithNotificationName:@"door bell is singing~~~~"];
}else{
//反正是不在前台 直接响铃
[self beginCallingWithNotificationName:@"door bell is singing~~~~"];
}
}
//应用启动此代理方法会返回设备Token 、一般在此将token上传服务器
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
NSString *str = [NSString stringWithFormat:@"%@",credentials.token];
NSString *deviceToken = @"";
deviceToken = [[[str stringByReplacingOccurrencesOfString:@"<" withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"deviceToken------>>>%@",deviceToken);
//这里可以吧deviceTokens上传到服务器
}
- (void)beginCallingWithNotificationName:(NSString *)NotificationName {
if (@available(iOS 10.0, *)) {
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.body =[NSString localizedUserNotificationStringForKey:[NSString stringWithFormat:@"%@", NotificationName] arguments:nil];;
UNNotificationSound *customSound = [UNNotificationSound soundNamed:@"voip_call.caf"];
content.sound = customSound;
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
_request = [UNNotificationRequest requestWithIdentifier:@"Voip_Push" content:content trigger:trigger];
[center addNotificationRequest:_request withCompletionHandler:^(NSError * _Nullable error) {
}];
}else{
_callNotification = [[UILocalNotification alloc] init];
_callNotification.alertBody = [NSString stringWithFormat:@"%@", NotificationName];
_callNotification.soundName = @"voip_call.caf";
[[UIApplication sharedApplication]
presentLocalNotificationNow:_callNotification];
}
}
3、开启提送测试
将.pem证书和php文件放在一个随意命名的文件夹中,比如说命名为voip,打开终端,cd voip文件夹 ,然后输入 php php文件名称.php,然后enter如果你看到
Connected to APNS
message successfully delivered
那么恭喜你,推送成功啦!
ok,这样就完成了voip推送了!喜欢的小伙伴可以点个赞哟~