The biggest challenge when writing communications apps is providing a
quick experience that won’t drain your users’ battery. We are going to
investigate the new PushKit framework and make it run with our
Voice API. It will require some
beta installs and server-side code, so expect to spend around 45 to 60
minutes here. This tutorial assumes that you are familiar with the old
push system and how to create certificates.

Prior to iOS 8, this method gave app developers the greatest flexibility
because the OS would keep your VoIP socket alive and periodically ping
your signaling server. If an incoming message was received, the OS would
give you 10 seconds to execute code, like pushing a local notification
and starting to set up the call. The drawback was that one more socket
was kept alive in the phone, and the phone would have to wake up and
ping your servers periodically. And, of course, Apple retains the right
to shut you down to conserve energy.

With iOS 8, Apple introduced a new kind of push: VoIP push. There are a
couple of benefits of this push message:

You don’t need to allow push; it works without the user knowing about
it.

Apple promises to deliver these push notifications high priority.

The best thing? It allows you to execute code when the push arrives. My
initial tests in a sandbox environment show that it’s pretty darn quick,
and since you can handle all calls the same way, it reduces the time to
implement our Voice API.

It only works on iOS 8. With our SDK (and probably any
WebRTC SDK), it only works on iOS
8.1 (as of writing this, it’s beta 1). This is because in 8.0, the
compiler linked is a dynlib and is not able to locate PushKit framework
for 32 bits when running on 64-bit hardware. At Sinch, we are working on
bringing our SDK up to 64 bits, but for now, when you use us, you need
to compile for armv7 and armv7s.

In this tutorial, I will use a very simple push framework from nuget and
a simple WebAPI controller in C#. I decided to build my own because I am
going to do some performance testing and BaaS providers like Parse don’t
support VoIP certificates yet.

I am going to host the site in Azure, but you can host wherever you
want. Update all nuget packages and install PushSharp in package manager
console.

update-package
install-package PushSharp

PushSharp is a wonderful little
package that makes sending push notifications a breeze. I am not
strictly following the implementation guidelines by running PushSharp in
an asp.net application, but let’s do the best we can and follow the
guidelines for hosting there by implementing a singleton.

Create a call called PushService and add the below code:

publicclassPushService{privatestaticPushService_context;publicstaticPushServiceContext(){if(_context==null){_context=newPushService();}return_context;}publicPushBrokerBroker{get;set;}publicPushService(){Broker=newPushBroker();varpath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"yourfile");varappleCert=File.ReadAllBytes(path);//its super important that you set the environment your self to//sandbox and disable certificate validationBroker.RegisterAppleService(newApplePushChannelSettings(false,appleCert,"yourpassword",true));}}

Remember to add the P12 file you exported from your Mac when you created
the VoIP push certificate. PushSharp does not support VoIP certificate
validation yet, so it’s important that you set the environment and
certificate validation yourself.

Next, add a new WebAPI controller to your project and name it PushKit.
Add two methods:

Next, add a call to your models called PushPair. This object is what the
Sinch framework will give you back when you should send push. PushData
contains the token and payLoad contains information about the call

Open the Sinch calling app sample in the Sinch SDK (or copy it if you
want to save the vanilla sample). Rename the project your App ID, in my
case PushKit, then click the project. Select your target and change
bundle identifier to your App ID.

Make sure you download the provisioning profile for the app
(Xcode/preferences/accounts/viewdetails/ and click on the refresh
button) Phew! It’s so much work to just set up the basics. Let the
coding begin.

Here it’s important to make sure you enter your key and secret and the
correct URL (sandbox or production). Also, in this example, you want to
force push to be used so you don’t support any active connections. Next,
implement the PushKit methods:

-(AFHTTPSessionManager*)getManager{AFHTTPSessionManager*manager=[[AFHTTPSessionManageralloc]init];manager=[[AFHTTPSessionManageralloc]initWithBaseURL:[NSURLURLWithString:@"<YOURSERVERURL>"]];manager.responseSerializer=[AFJSONResponseSerializerserializer];returnmanager;}-(AFHTTPSessionManager*)getJsonManager{AFHTTPSessionManager*manager=[selfgetManager];manager.requestSerializer=[AFJSONRequestSerializerserializer];returnmanager;}-(void)pushRegistry:(PKPushRegistry*)registrydidUpdatePushCredentials:(PKPushCredentials*)credentialsforType:(NSString*)type{///tell the Sinch SDK about the push token so we can///give that to users that want to call this user.[_clientregisterPushNotificationData:credentials.token];}

The above method is very similar to the regular notification service,
and you just pass it to the Sinch SDK. AppDelegate adds support to
handle incoming push by implementing below.

The biggest advantage of PushKit is the ability to execute code in the
background. Despite Apple’s documentation, it actually doesn’t seem that
the OS will wake your app if you terminate it, which is a bummer. Also,
there is currently a bug where you only get a token for the sandbox
environment and no production token, but Apple will probably address
this pretty quickly. Overall, I think this is step in the right
direction for Apple to let developers build more real-time applications.
I expect that it will open up this kind of push not only for VoIP, but
also for other types of applications.