实施 PushKit 并测试开发行为 [英] Implement PushKit and test in development behavior

查看:18
本文介绍了实施 PushKit 并测试开发行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序(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 长度] == 0) {NSLog(@"voip token NULL");返回;}NSLog(@"didUpdatePushCredentials: %@ - Type: %@", credentials.token, type);}

如果我尝试从我的服务器向之前上传的 voip 设备令牌生成推送通知消息,我永远不会收到 didReceiveIncomingPushWithPayload 回调的通知,但是从服务器我收到 200 条 ok 消息(消息已成功发送)

解决方案

以防万一有人对使用 Pushkit 测试 voip 推送通知感兴趣,我留下了一个我成功遵循的小程序:

1 - 创建一个带有钥匙串访问的 CSR(如果您还没有)并在本地保存您的 CSR.

2 - 转到 Apple Developer 并获得访问证书、标识符和;简介.在会员中心.

  • Inside Identifiers-> App IDs 创建一个新的应用程序 ID
  • Inside Devices-> 所有添加设备 UDID 您要用于测试 voip 推送
  • Inside Certificates-> All 创建一个新的生产证书:VoIP 服务证书.为您的 voip 服务证书选择之前创建的应用程序 ID.选择之前创建的 CSR(证书签名请求),创建后下载新的 voip_services.cer

下载后双击 voip_services.cer 以打开 Keychain Access 应用程序并导出生成证书的私钥:右键导出 certificate.p12 文件.>

voip_services.cercertificate.p12 文件保存在一个文件夹中,以创建您的服务器推送通知生成器

最后再次访问 Apple Developer 网站,在 Provisioning Profiles->Distribution 创建一个新的 Ad-Hoc 分发配置文件,其中包括您要用于测试 voip 推送的所有设备 UDID.下载此配置文件并将其拖放到您的 xcode 中,以便在您的应用程序中使用它.

现在让我们创建将接收 voip 推送通知的 iOS 应用:

  • 从 Xcode 新项目菜单创建一个新的单一视图应用程序.
  • 根据上一节中创建的应用程序 ID 填写其 bundle Identifier.
  • 在 General-> Linked Frameworks and Libraries 中添加 PushKit.framework.
  • 在功能中启用后台模式并选择 IP 语音选项.
  • 在构建设置 -> 代码签名中,选择您之前下载的配置文件,然后选择分发作为代码签名标识.

让我们在应用中添加代码 Pasquale 在他的问题中添加:

在您的根视图控制器标头 (ViewController.h) PushKit.framework 的导入:

#import 

添加委托以实现其功能:

@interface ViewController : UIViewController 

在你的根视图控制器(ViewController.m)的 viewDidLoad 函数中添加推送注册:

- (void)viewDidLoad {[超级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 长度] == 0) {NSLog(@"voip token NULL");返回;}NSLog(@"PushCredentials: %@", credentials.token);}- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type{NSLog(@"didReceiveIncomingPushWithPayload");}

一旦一切都编译好了,就归档您的项目并导出您的 ipa 文件,以便将其安装在测试设备上(例如,您可以使用 Testflight 来完成这项工作).

执行它并从日志中获取我们将用于发送推送的 PushCredentials.

现在让我们转到服务器端(我遵循了 raywenderlich 教程):

回到放置三个文件的文件夹:

  • voip_services.cer
  • 证书.p12

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 >文件

为了发送推送,您可以使用 Pusher.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1" rel="noreferrer">raywenderlich 教程 教程或使用简单的 php 脚本:

$消息,'声音' =>'默认');//将有效负载编码为 JSON$payload = json_encode($body);//构建二进制通知$msg = chr(0) .包('n', 32) .pack('H*', $deviceToken) .pack('n', strlen($payload)) .$有效载荷;//发送到服务器$result = fwrite($fp, $msg, strlen($msg));如果(!$结果)echo '消息未送达'.PHP_EOL;别的echo '消息发送成功'.PHP_EOL;//关闭与服务器的连接fclose($fp);

你应该在脚本中修改:

  • $deviceToken 通过添加您的 PushCredentials(来自应用日志)
  • $passphrase 根据您在第 2 步中创建 PushVoipKey.pem 时添加的密码

就是这样.执行php脚本:

#php simplePushScript.php

并且您应该会收到您的 voip 推送通知(您应该会看到应用日志:didReceiveIncomingPushWithPayload")

在那次测试之后,我想知道如何通过 pushkit 框架接收标准推送通知,但不幸的是我没有答案,因为在注册推送类型时我找不到任何其他 PKPushType,但 PKPushTypeVoIP...

pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

仅此而已!感谢阅读!

i'd like to implement PushKit service within my app ( Voip app ), but i have following doubt: I see that i can generate only production voip certificate , it works if i try to test voip push notification service on develop device ?

This is my implementation test:

With this 3 line of code i can get push token on didUpdatePushCredentials callback that i use to save into my server.

PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

Server side i generate a "normal" payload push notification with only alert text, and i sent to voip token stored into my server.

I use the callback with debug log, but they never getting called!

- (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);

}

If i try to generate a push notification message from my server to voip device token previously uploaded, i'm never notified on didReceiveIncomingPushWithPayload callback, but from server i get 200 ok message( message was successfully sent )

解决方案

Just in case someone is interested on testing voip push notifications with Pushkit here I left a small procedure I followed successfully:

1 - Create, if you do not have it already, a CSR with Keychain Access and save your CSR locally.

2 - Go to Apple Developer and get access Certificates, Identifiers & Profiles. On the member center.

  • Inside Identifiers-> App IDs Create one new app id
  • Inside Devices-> All Add devices UDID you want to use for testing voip pushes
  • Inside Certificates-> All Create a new Production certificate: VoIP Services Certificate. Select previously created app Id for your voip Service Certificate. Select previously created CSR (Certificate Signing Request) and once created download your new voip_services.cer

Once downloaded double click on voip_services.cer in order to open Keychain Access application and export private key for generated certificate: right button Export certificate.p12 file.

Save voip_services.cer and certificate.p12 file in a folder in order to create your server push notification generator

Finally go to Apple Developer website again and inside Provisioning Profiles->Distribution create a new Ad-Hoc distribution profile including on it all devices UDID you want to use for testing voip pushes. Download this profile and drag and drop to your xcode in order to use it on your application.

Now lets create the iOS app that will receive voip push notifications:

  • Create a new Single View Application from Xcode new project menu.
  • Fill its bundle Identifier according to created app id in previous section.
  • Add PushKit.framework in General-> Linked Frameworks and Libraries.
  • In Capabilities enable Background Mode and select Voice over IP option.
  • In Build Settings -> Code Signing select provisioning profile you downloaded previously and select Distribution as Code Signing Identity.

Lets add in the app the code Pasquale added in his question:

In your root view controller header (ViewController.h ) an import for PushKit.framework:

#import <PushKit/PushKit.h>

Add delegate in order to implement its functions:

@interface ViewController : UIViewController <PKPushRegistryDelegate>

Add in viewDidLoad function of your root view controller (ViewController.m) push registration:

- (void)viewDidLoad {
    [super viewDidLoad];

    PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    pushRegistry.delegate = self;
    pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}

Implement required delegate functions:

- (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");
}

Once everything is compiling and ok, archive your project and export your ipa file in order to install it on testing devices (you can use for example Testflight to do the job).

Execute it and get from logs the PushCredentials we will use to send pushes.

Now lets go to server side (I followed this great guide of raywenderlich tutorials):

Get back to folder were you placed the three files:

  • voip_services.cer
  • certificate.p12

1 - Open a terminal and create pem file from certificate file:

#openssl x509 -in voip_services.cer -inform der -out PushVoipCert.pem

2 - Create pem file from exported private key file:

#openssl pkcs12 -nocerts -out PushVoipKey.pem -in certificate.p12

3 - Join both pem files in one:

#cat PushVoipCert.pem PushVoipKey.pem > ck.pem

In order to send pushes you can use Pusher from raywenderlich tutorials tutorial or using a simple php script:

<?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);

you should modify in script:

  • $deviceToken by adding your PushCredentials (from app logs)
  • $passphrase by the passphrase you added on step 2 when creating PushVoipKey.pem

That's it. Execute php script:

#php simplePushScript.php

and you should receive your voip push notification (you should see app log: "didReceiveIncomingPushWithPayload")

After that test I wondered how I could receive standard push notifications through pushkit framework, but unfortunately I have no answer as when registering the push type I could not find any other PKPushType but the PKPushTypeVoIP...

pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

That's all! Thanks for reading!

这篇关于实施 PushKit 并测试开发行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆