iOS and PushKit
This post will cover basic concepts for VoIP apps on iOS.
I will not post any code (Google it out if necessary). I will compare two ways of developing VoIP on iOS and write down my notes while developing them.
VoIP apps before iOS 8
Before iOS 8, VoIP apps had to maintain persistent background connection (VoIP socket) with the server. When a new incoming call arrived iOS gave some execution time to the app so it could notify user (via local notifications).
Developers could add remote push notifications to inform users about incoming calls but apps did not receive any execution time there. Remote push notifications are not reliable since users can disable them at anytime.
To be available as much as possible apps had to perform the following steps:
1.) Configure one of the app’s sockets for VoIP usage
2.) Before moving to the background set a keepAlive timeout handler to be executed periodically
3.) Observing network changes
When keepAlive timeout expired (minimum 10 min) or when network configuration changed, app received a few sec (< 10) of execution time to maintain VoIP socket with the server.
This way of working had two major down sides. It was a drain on the battery and if the app was closed by the user (or crashed) all VoIP calls would have been missed, until the app was executed by the user.
VoIP apps with PushKit (iOS 8+)
With iOS 8 there is a new, more energy efficient way to create iOS VoIP apps - VoIP Push notifications.
VoIP notifications have higher priority compared to regular push notifications and they give you some execution time when received.
They are more reliable (more about this in notes :)) and a lot more useful. Received VoIP push notification will wake up or launch your app (almost) anytime, regardless if your app crashed, was terminated by user, or device was restarted.
You no longer have to maintain persistent connections with your server, set timeouts or observe network changes.
Your VoIP app must do two things on startup:
1.) Initialize PushKit (VoIP type) and set its delegate. User does not need to allow it and cannot disable it
2.) Register for posting user notifications about incoming calls (user confirmation is required)
There is no need for any active connection to the server when there is no active call. When incoming call is created, server will send VoIP push notification to your device.
This notification will wake your app and give you some time to connect to the server (if needed) and notify user about the call. When a call ends you can disconnect from the server.
Battery drain is minimal since your app doesn’t need to run in the background. User can kill your app and still be reachable.
Sample code with PushKit integration can be found in here.
My notes regarding PushKit
Not receiving notifications after device reboot:
- Before initializing PushKit start a background task. Finish this task when PushKit token is received.
Not receiving pushes after app crashed:
- This happens only if your app crashes while processing push notifications. Make sure you do not have a bug in your PushKit delegate function.
Not receiving pushes after app is few hours in background:
- This is a bug in iOS and it it occurs after few days, sometimes after few hours. When your app gets to this point, it has to be launched manually. We have reported this bug to Apple. If you are facing same issue, you can follow this thread on Apple Dev forum: https://devforums.apple.com/message/1113824
Written by: Miha Majcen