Hello everyone,
I’m developing a VoIP-based application that supports both standard VoIP calls and Push-To-Talk (PTT) calls. The app does not use the unrestricted-voip entitlement since it’s not publicly documented or communicated as a standard by Apple.
Previously, I handled PTT calls using CallKit after receiving PushKit notifications, but I’m now migrating PTT functionality to the PushToTalk Framework while keeping CallKit for standard VoIP calls. I’m facing a few challenges that I’d like help with:
-
Handling Incoming Push-To-Talk Calls When the App Is Closed and the Device Is Locked
I considered continuing to use PushKit notifications to alert users via CallKit and using CallKit until the user brings the app into the foreground, at which point I’d switch to the PushToTalk Framework. While this could technically work, the user experience is not ideal. Are there any recommended approaches for handling PTT calls in this state? -
Handling Incoming PTT Calls When the App Is in the Background
According to Apple documentation, I cannot join a PTT session unless my app is in the foreground. However, in practical scenarios, we often receive incoming PTT calls while the app is in the background. What’s the best solution for this situation? It feels odd to show notifications or use CallKit until the app is foregrounded. -
Conflict Between Ongoing PushToTalk Call and Incoming Cellular Call
Currently, if there’s an ongoing PushToTalk call using the PTT framework and a cellular call comes in, if I receive a PTT transmission and callrequestBeginTransmission
, the cellular call is ended. I can handle this within my app, but is this expected behavior? Is this the intended conflict management for concurrent PTT and cellular calls?
Lastly, a broader question: when will the unrestricted-voip entitlement stop working? I’m contemplating using this entitlement to handle incoming PTT calls without CallKit, but I’m concerned about its longevity. Some apps have been using it for messaging and other features for over four years, and it’s still functional for them.
Any guidance or insights on these points would be greatly appreciated!
Thanks in advance!
First off, I want to clarify the situation here:
Lastly, a broader question: when will the unrestricted-voip entitlement stop working? I’m contemplating using this entitlement to handle incoming PTT calls without CallKit, but I’m concerned about its longevity.
Being specific here, the "com.apple.developer.pushkit.unrestricted-voip"
entitlement was disabled in the iOS 15 SDK and has not functioned since then. There are apps that continue to include it, but that is either because they're specifically supporting older systems or (and I think this is more likely) because they simply haven't removed it.
There is a PTT specific variant which does still function, however, that is only because the PTT framework was introduced later (iOS 16) and requires significantly more work to adopt than the other use cases.
The only commitments I've made on the PTT entitlement were that:
-
It would continue functioning in iOS 17.
-
It would be disabled using a linked on/after check, just like the broader entitlement was, ensuring that shipping apps would continue to function.
All PTT developers should be transitioning to the PushToTalk framework and removing their reliance on the entitlement as quickly as possible. While the PTT entitlement does function on iOS 18, we've also made it very clear that it will be disabled in the future.
Also, on this specific point:
Some apps have been using it for messaging and other features for over four years, and it’s still functional for them.
At this point, every PTT and voip developer should be aware that using PushKit for ANYTHING other than incoming call notifications is no longer supported. Message traffic should be moved over to standard push and the Notification Service Extension architecture.
Previously, I handled PTT calls using CallKit after receiving PushKit notifications, but I’m now migrating PTT functionality to the PushToTalk Framework while keeping CallKit for standard VoIP calls. I’m facing a few challenges that I’d like help with:
Looking over your questions, I think the main issue here comes from a misunderstanding of how we expect the PTT session to work. One of the issues the PushToTalk framework was designed to address was that PTT apps were interrupting the users without the user having any awareness that this could occur or any ability to control it. The systems expectation here is that the user would start your PTT session while your app was in the foreground and your app would remain in that session the entire time it expected to receive PTT traffic.
As a side note here, with the benefit of hindsight, the PushToTalk framework should NOT have used the term "channel" in the API. The term "channel" is widely used in PTT apps and that's created confusion and misunderstandings about how it PTChannelManager should be used. The PTChannelManager is how your app manages the system UI, NOT your apps own channels/calls/etc.
Moving to this comment:
However, in practical scenarios, we often receive incoming PTT calls while the app is in the background.
As noted above, PTT apps were previously able to simply play audio on demand, but that functionality is something the PushToTalk framework is designed to eliminate. The answer here is that you should leave the PTChannelManager active the entire time the user wants to receive you PTT messages. This is why PTChannelManager includes restoration support, as it's designed to restore your session if your app is terminated in the background (just as can happen with voip apps) or even across reboots.
3.Conflict Between Ongoing PushToTalk Call and Incoming Cellular Call Currently, if there’s an ongoing PushToTalk call using the PTT framework and a cellular call comes in, if I receive a PTT transmission and call requestBeginTransmission, the cellular call is ended.
How are you triggering transmission here? Through your app in the foreground and/or the homescreen UI? Or through hardware, particularly through Bluetooth HFP? HFP support is extremely complicated and it's possible there's a more complex interaction here.
Having said that...
I can handle this within my app, but is this expected behavior? Is this the intended conflict management for concurrent PTT and cellular calls?
...the answer is basically "yes"? The PushToTalk framework was intended to operate as a "peer" with CallKit and part of that interoperability means that it needs to be able to interrupt CallKit calls. You could argue that it should put the call on hold instead, but I don't think the current behavior is inherently "wrong".
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware