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.
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:
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:
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:
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!