我想在我的应用程序(Voip应用程序)中实现PushKit服务,但我有以下疑问:我看到我只能生成生产voip证书,如果我尝试测试voip推送通知服务,它可以工作开发设备?
这是我的实施测试:
使用这3行代码,我可以在用于保存到我的服务器的didUpdatePushCredentials回调中获得推送令牌。
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
服务器端我生成"正常"只有警报文本的有效负载推送通知,我发送到存储在我服务器中的voip令牌。
我使用带有调试日志的回调,但它们永远不会被调用!
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type {
NSLog(@"didInvalidatePushTokenForType");
}
-(void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
NSLog(@"didReceiveIncomingPushWithPayload: %@", payload.description);
}
-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
if([credentials.token length] == 0) {
NSLog(@"voip token NULL");
return;
}
NSLog(@"didUpdatePushCredentials: %@ - Type: %@", credentials.token, type);
}
如果我尝试从我的服务器生成推送通知消息,以便先前上传的voip设备令牌,我从未通知didReceiveIncomingPushWithPayload回调,但是从服务器i获得200 ok消息(消息已成功发送)
答案 0 :(得分:63)
以防万一有人对使用Pushkit测试voip推送通知感兴趣,我留下了一个我成功遵循的小程序:
1 - 如果您还没有,请创建带有钥匙串访问权限的 CSR ,并在本地保存您的CSR。
2 - 访问Apple Developer并获取证书,标识符和配置文件。在会员中心。
下载后双击 voip_services.cer 以打开Keychain Access应用程序并导出生成的证书的私钥:右键导出 certificate.p12 文件。
将 voip_services.cer 和 certificate.p12 文件保存在文件夹中,以便创建服务器推送通知生成器
最后再次访问Apple Developer网站,在Provisioning Profiles-> Distribution中创建一个新的 Ad-Hoc发布配置文件,其中包括您要用于测试voip推送的所有设备UDID。下载此配置文件并拖放到您的xcode,以便在您的应用程序中使用它。
现在让我们创建将接收voip推送通知的iOS应用程序:
让我们在应用中添加他的问题中添加的代码Pasquale:
在根视图控制器标头中( ViewController.h )PushKit.framework的导入:
#import <PushKit/PushKit.h>
添加委托以实现其功能:
@interface ViewController : UIViewController <PKPushRegistryDelegate>
添加根视图控制器的viewDidLoad函数(ViewController.m)推送注册:
- (void)viewDidLoad {
[super viewDidLoad];
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
实施所需的委托功能:
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
if([credentials.token length] == 0) {
NSLog(@"voip token NULL");
return;
}
NSLog(@"PushCredentials: %@", credentials.token);
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
NSLog(@"didReceiveIncomingPushWithPayload");
}
一旦所有内容都正在编译并确定,请归档您的项目并导出您的ipa文件,以便将其安装在测试设备上(您可以使用Testflight来完成这项工作)。
执行它并从日志中获取我们将用于发送推送的PushCredentials。
现在让我们去服务器端(我遵循了raywenderlich tutorials的精彩指南):
如果您放置了三个文件,请返回文件夹:
1 - 打开终端并从证书文件创建pem文件:
#openssl x509 -in voip_services.cer -inform der -out PushVoipCert.pem
2 - 从导出的私钥文件创建pem文件:
#openssl pkcs12 -nocerts -out PushVoipKey.pem -in certificate.p12
3 - 将两个pem文件合并为一个:
#cat PushVoipCert.pem PushVoipKey.pem > ck.pem
为了发送推送,您可以使用Pusher教程中的raywenderlich tutorials或使用简单的PHP脚本:
<?php
// Put your device token here (without spaces):
$deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';
// Put your private key's passphrase here:
$passphrase = 'pushchat';
// Put your alert message here:
$message = 'My first push notification!';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.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(
'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);
你应该在脚本中修改:
就是这样。执行php脚本:
#php simplePushScript.php
你应该收到你的voip推送通知(你应该看到app log:“didReceiveIncomingPushWithPayload”)
在那次测试之后,我想知道如何通过pushkit框架接收标准推送通知,但不幸的是我没有回答,因为在注册推送类型时我找不到任何其他PKPushType但PKPushTypeVoIP ......
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
这就是全部!谢谢你的阅读!
答案 1 :(得分:3)
今天我详细探讨了这一点。当Apple只允许我们生成生产VoIP推送证书时,我也想知道如何在开发版本中使用生成的推送令牌。
在服务器上,您必须将生产推送发送到gateway.push.apple.com
,并将开发/沙箱推送到gateway.sandbox.push.apple.com
。我能够使用gateway.sandbox.push.apple.com
上的生产VoIP证书在我的应用程序的开发版本上生成和接收VoIP推送。我还没有尝试过,但是假设它也适用于临时或生产构建并使用gateway.push.apple.com
。
另请注意,推送通知在模拟器中根本不起作用。
答案 2 :(得分:0)
即使您不使用远程通知,也需要启用远程通知:
完成此操作后,您将在Debug和Release中收到委托回调。