PushToTalk Microphone Permission Issues After Force Quit

Hello Apple Developer Community,

We're implementing the PushToTalk framework as recommended. According to Apple engineers in previous forum responses :

the framework allows your app to continue receiving push notifications even after your app is terminated or the device is rebooted.

Implementation:

We've properly implemented:

  • Early initialization of PTChannelManager via channelManager(delegate:restorationDelegate:completionHandler:)
  • Channel joining with requestJoinChannel(channelUUID:descriptor:) when foregrounded
  • All required delegate methods

Issue

After a user force quits our app, PushToTalk functionality works briefly but fails after some time (minutes to hours). The system logs show:

AudioSessionServerImpCommon.mm:105 { 
  "action":"cm_session_begin_interruption", 
  "error":"translating CM session error", 
  "session":{"ID":"0x72289","name":"getcha(2958)"}, 
  "details":{
    "calling_line":997,
    "error_code":-12988,
    "error_string":"Missing entitlement"
  } 
}

We suspect that entitlement after force-quitting the app, there's a permission cache that temporarily allows functionality, but once this cache is cleared, the features stop working. Without this entitlement, both audio playback and recording fail, completely breaking the PTT functionality.

Questions

  1. Which specific entitlement is missing according to this error?
  2. Is there a permission caching mechanism that expires after force quit?
  3. How can we ensure reliable PTT operation after force quit as stated in documentation?

This behavior contradicts Apple's guidance that PushToTalk should work reliably after termination. Any insights would be greatly appreciated.

Thank you!

Answered by DTS Engineer in 836327022

We suspect that entitlement after force-quitting the app, there's a permission cache that temporarily allows functionality, but once this cache is cleared, the features stop working. Without this entitlement, both audio playback and recording fail, completely breaking the PTT functionality.

Basically, no, this isn't what's going on.

The thing to understand here is that the entitlement system isn't just used to constrain app behavior, it's ALSO used to constrain what exactly the system can do. For example, apps are not allowed to activate recording audio sessions unless they're in the foreground, but this is fact EXACTLY the functionality CallKit provides to voip apps. The architecturally, how that's actually implemented an entitlement exists which allows background activation and that entitlement is then granted to the specific system components (like callservicesd).

However, that does sometimes lead to misleading error messages* (like this one) where the error says "your missing an entitlement" when what it actually means is "you tried to do something your simply not allowed to do".

*Accessing HomeKit from the background is another example of this. On some platforms our error string says an entitlement is missing, but as far as I'm aware we've never granted that entitlement to anyone. The real error is simply that apps are not allowed to access HomeKit from the background.

In any case, the entitlement itself is a distraction. The issue here isn't that your app needs some extra entitlement, it's that it tried to do "something" the system doesn't allow.

So, let me return to here:

How can we ensure reliable PTT operation after force quit as stated in documentation?

The first issue I'd immediately look at is whether or not your app ever directly activates the audio session, as that's the easiest way generate this kind of failure. Note that this can be particularly tricky if you've moved an existing PTT app onto the PushToTalk framework.

The issue in that case is that legacy PTT apps regularly "flipped" between a mixable playback-only session (so they could immediately play over/alongside other audio) and the CallKit session (so they could record). If that older playback-only code is still in the app, it can end up creating race conditions where things work "most" of the time (because you're calling activate on a mixable playback-only session) and then fail unexpectedly (because the session configuration shifted to the PTT config).

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

We suspect that entitlement after force-quitting the app, there's a permission cache that temporarily allows functionality, but once this cache is cleared, the features stop working. Without this entitlement, both audio playback and recording fail, completely breaking the PTT functionality.

Basically, no, this isn't what's going on.

The thing to understand here is that the entitlement system isn't just used to constrain app behavior, it's ALSO used to constrain what exactly the system can do. For example, apps are not allowed to activate recording audio sessions unless they're in the foreground, but this is fact EXACTLY the functionality CallKit provides to voip apps. The architecturally, how that's actually implemented an entitlement exists which allows background activation and that entitlement is then granted to the specific system components (like callservicesd).

However, that does sometimes lead to misleading error messages* (like this one) where the error says "your missing an entitlement" when what it actually means is "you tried to do something your simply not allowed to do".

*Accessing HomeKit from the background is another example of this. On some platforms our error string says an entitlement is missing, but as far as I'm aware we've never granted that entitlement to anyone. The real error is simply that apps are not allowed to access HomeKit from the background.

In any case, the entitlement itself is a distraction. The issue here isn't that your app needs some extra entitlement, it's that it tried to do "something" the system doesn't allow.

So, let me return to here:

How can we ensure reliable PTT operation after force quit as stated in documentation?

The first issue I'd immediately look at is whether or not your app ever directly activates the audio session, as that's the easiest way generate this kind of failure. Note that this can be particularly tricky if you've moved an existing PTT app onto the PushToTalk framework.

The issue in that case is that legacy PTT apps regularly "flipped" between a mixable playback-only session (so they could immediately play over/alongside other audio) and the CallKit session (so they could record). If that older playback-only code is still in the app, it can end up creating race conditions where things work "most" of the time (because you're calling activate on a mixable playback-only session) and then fail unexpectedly (because the session configuration shifted to the PTT config).

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi Kevin,

Thank you for your response. While your explanation about entitlements and audio session management is helpful, our specific issue remains unaddressed.

To clarify our exact scenario:

  1. We're using the official PushToTalk framework as recommended
  2. When our app is running normally (background or foreground), the system UI (blue circle in status bar/Dynamic Island) works perfectly
  3. When a user force quits our app, the blue PushToTalk UI indicator remains visible in the system UI
  4. However, when users press and hold this system UI control to talk, they cannot record or play audio

This behavior seems to contradict the statement in your previous forum responses that "The PushToTalk framework will deliver push notification payloads to your app as long as the user remains joined to the channel, even if your app terminates."

Since the blue UI indicator remains visible after force quit (suggesting the channel is still active), shouldn't the system UI's press-and-hold functionality continue to work? Or is there something specific about the recording functionality through system UI that's expected to stop working after force quit?

We're not attempting to directly activate audio sessions ourselves when using the system UI controls. We rely entirely on the PTChannelManager framework to handle this when users interact with the blue circle UI.

Thank you for any clarification on this specific use case.

Since the blue UI indicator remains visible after force quit (suggesting the channel is still active), shouldn't the system UI's press-and-hold functionality continue to work? Or is there something specific about the recording functionality through system UI that's expected to stop working after force quit?

So, the key point to understand here is what the blue system UI actually means. The ONLY thing it specifically tells you is that an app (in this case, "your app") is the active PTT app. An app becomes the you become the active PTT app when you call requestJoinChannel(channelUUID:descriptor:). An app stops being the active PTT app either by calling leaveChannel(channelUUID:), or because the user left the channel through the system UI.

Note that I did NOT say that it indicates your app was running and that's because the presence of the PTT UI does NOT mean your app is actually running (either active or suspended in the background). The PTT system is designed to function the same way voip/PushKit functions. That is, when "something" happens, the systems will deliver that event to your app by either waking it (if it's suspended) or launching it (if it's not running), then delivering that event to your app. What the PTT framework changes about that process is:

  • Only the active PTT app receives PTT pushes.

  • User activity (like interacting with the system UI) can also generate events.

That leads to here:

When a user force quits our app, the blue PushToTalk UI indicator remains visible in the system UI

When this occurred, your app was terminated and is no longer running.

However, when users press and hold this system UI control to talk,

When this occurred, the system relaunched your app and (presumably) delivered the event to your app.

they cannot record or play audio

Yes, that's not unusual. The broad issue you're describing here is "my app works perfectly when I launch it myself, but doesn't work right when the system launches my app into the background". It's an easy edge case to overlook at it's tricky to test/debug, so many apps have problems with it.

EXACTLY what your app is doing wrong isn't something I can answer. This kind of failure is rarely a simple case of "you did this wrong", but is almost always caused by the specific details of your apps implementation and how that changes when your app is launched directly into the background.

That leads to here:

Since the blue UI indicator remains visible after force quit (suggesting the channel is still active), shouldn't the system UI's press-and-hold functionality continue to work?

The critical thing understand here is that most of the actual "work" here is actually done by your app, NOT "the system" or PTT framework. That is, the PTT system doesn't have it's own recording or audio "system". What it actually does is activate your apps audio session from out of process, at which point your app is what's doing all the "work".

*While it's possible for there to be bugs in that process, this is the same code path that's used by CallKit itself (which include Phone.app), not just the PTT framework.

Or is there something specific about the recording functionality through system UI that's expected to stop working after force quit?

This functionality does work properly across force quit. It's not at state where I can publish it, but if you contact DTS there is a trivial project I can share showing that it works.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

The broad issue you're describing here is "my app works perfectly when I launch it myself, but doesn't work right when the system launches my app into the background".

To clarify our exact situation:

  • When our app is suspended in the background, PushToTalk works perfectly

  • When the user kills our app, the PushToTalk UI indicator (blue circle) remains visible, but the functionality fails (can't record or play audio)

Anyway, thank you for your detailed explanation. I believe our understanding is now aligned with yours: I understand that an active PTT app should still be able to use PushToTalk functionality even after being force-quit, as the system should relaunch it when needed. The presence of the blue UI indicator confirms the channel is still active at the system level.

We're still uncertain about the specific issue in our implementation. But we are examinating if any bugs.

We've submitted a DTS request to get more specific guidance and hopefully access to the sample project you mentioned that demonstrates the correct implementation. We look forward to resolving this issue.

Thank you for your assistance.

PushToTalk Microphone Permission Issues After Force Quit
 
 
Q