iOS 27 Public Beta 6: CallKit UI remains after ending two outgoing calls in modified Apple Speakerbox sample

Summary

On an iPhone 17 running iOS 27 Public Beta 6, the system CallKit UI remains visible after ending two outgoing calls individually.

This is reproducible using Apple's “Making and Receiving VoIP Calls with CallKit” sample (Speakerbox), with only two minimal changes to support multiple simultaneous calls. After both calls end, Speakerbox displays “No Calls”, but the system CallKit UI still shows 111, and the Dynamic Island retains a call-related status.

Environment

  • Device: iPhone 17 (physical device)
  • OS: iOS 27 Public Beta 6
  • App: Apple's Speakerbox sample with the modifications below
  • Backend: None. The sample's original simulated calls are used; no external VoIP SDK is involved.

Changes to the original sample

Only two files were modified.

1. ProviderDelegate.swift

Added:

providerConfiguration.maximumCallGroups = 3

The original setting remains unchanged:

providerConfiguration.maximumCallsPerCallGroup = 1

2. SpeakerboxCallManager.swift

Before starting a new outgoing call, hold existing calls that are not already on hold. The hold actions and new start action are submitted in the same transaction:

let transaction = CXTransaction()

for call in calls where !call.isOnHold {
    transaction.addAction(
        CXSetHeldCallAction(call: call.uuid, onHold: true)
    )
}

transaction.addAction(startCallAction)
requestTransaction(transaction)

No changes were made to the simulated connection timing, startedConnectingAt/connectedAt reporting, CXEndCallAction handling, call removal, or audio handling.

The original end-call handler finds the call by UUID, calls endSpeakerboxCall(), fulfills the end action, and removes the call from the app's list.

Steps to reproduce

  1. Launch the modified Speakerbox sample.
  2. Create an outgoing call to 111.
  3. Create a second outgoing call to 222. The first call is placed on hold.
  4. Wait until Speakerbox shows 111 — On Hold and 222 — Active, with call durations displayed.
  5. In Speakerbox, select 222 - End Call.
  6. Select 111 - End Call.
  7. Confirm that Speakerbox displays “No Calls”.
  8. Open the app switcher and inspect the system CallKit UI. Also inspect the Dynamic Island.
  9. Open the remaining system call UI and tap End.

Expected result

After both calls end, the system should no longer display an ongoing call in the CallKit UI or Dynamic Island.

Actual result

  • Speakerbox displays “No Calls”.
  • The system CallKit UI continues to display the first call, 111.
  • The Dynamic Island continues to show a call-related “Hold” status.
  • Tapping End in the remaining system call UI does not clear the residual state during the recording.
  • The issue occurs even after waiting for both simulated calls to connect before ending them.

This is the system-provided CallKit UI, not an active-call view implemented by the sample app.

Reproduction video

Recording: 4b03d30e507b874d9c19c0523632e9d6.mp4

  • 00:24–00:26 (approximately): Both calls are present; 111 is on hold and 222 is active.
  • 00:26–00:31 (approximately): End 222, then end 111. Speakerbox displays “No Calls”.
  • 00:31–01:03 (approximately): The system CallKit UI and Dynamic Island retain the call state despite further attempts to end it.

Questions

Is this an iOS 27 regression, or is additional lifecycle handling required when extending Speakerbox to support multiple calls?

Please advise what additional diagnostics would help investigate why the system UI retains an ongoing-call state after both calls have been ended using the sample's original end-call handling.

Source and video downloads

https://github.com/willbin/callkit-ios27-repro/releases/tag/repro-v1

I used AI to polish the content and the description is correct.

Is this an iOS 27 regression, or is additional lifecycle handling required when extending Speakerbox to support multiple calls?

It's a bug (r.185143623). There have actually been a number of otherwise unrelated bugs which all create the same result (InCallService's lingering), which always complicates fully addressing an issue like this. If you haven't already, please file a bug on this and then post the bug number back here.

Please advise what additional diagnostics would help investigate why the system UI retains an ongoing-call state after both calls have been ended using the sample's original end-call handling.

So, one thing to understand here is that the system UI you're seeing in an entirely separate app ("InCallService") whose only role is to present the call UI you see. Functionally, that means it's totally independent of your app, so the wrong kind of glitch can create exactly what you're seeing.

In terms of your own investigation, the main thing I would look at is whether or not CXCallObserver.calls lists a call after the call UI gets stuck. That call list is retrieved from callservicesd, so it’s telling you what "the system" knows about, not just your app.

Unfortunately, my guess is that it won't contain a call which means that there isn't really anything your app can do about it. Once callservicesd has destroyed "the call", there isn't really any connection from your app to InCallService, which means you don't have any ability to disrupt/alter InCallService.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

@DTS Engineer Please check.

Feedback number: 24737254 https://feedbackassistant.apple.com/feedback/24737254

Question 1: What is the fix plan for this issue, the iOS27 is coming soon.

btw, I also encountered another CallKit issue on iOS 27:

  1. Make a VoIP call.
  2. Receive a native call.
  3. The VoIP call (on my VoIP app) will be ended.
  4. On my iPhone 17, it works well. But on iPhone15, it will be ended.

Question 2: So, the same issue?

iOS 27 Public Beta 6: CallKit UI remains after ending two outgoing calls in modified Apple Speakerbox sample
 
 
Q