Hello! Thank you for bringing the new iPhone experience with the PushToTalk framework.
I have a working walkie talkie app based on the PushToTalk framework. Everything works fine except for an intermittent bug that I face from time to time on different devices with different iOS versions, from iOS 18 to iOS 26.2 Beta.
Sometimes the app goes into a state where the AVAudioInputNode input node tap returns buffers with a constant size that contain only silence. Leaving and rejoining a channel helps, but relaunching or reinstalling (from Xcode) the app does not. Rebooting the device or deleting and reinstalling the app also helps.
I do not activate the audio session in my app. I only configure it on launch using
setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth])
So the flow is:
channelManager?.requestBeginTransmitting(channelUUID: globalChannelUUID)
func channelManager(
_ channelManager: PTChannelManager,
channelUUID: UUID,
didBeginTransmittingFrom source: PTChannelTransmitRequestSource
)
func channelManager(
_ channelManager: PTChannelManager,
didActivate audioSession: AVAudioSession
) {
/// ...
installTapAndStart()
}
private func installTapAndStart() {
let inputNode = audioEngine.inputNode
let hardwareFormat = inputNode.outputFormat(forBus: 0)
guard let targetFormat = AVAudioFormat(
commonFormat: .pcmFormatFloat32,
sampleRate: configuration.audioSampleRate,
channels: configuration.audioChannelsCount,
interleaved: true
) else {
handleError(RecorderError.invalidAudioFormat)
return
}
let converter = AVAudioConverter(from: hardwareFormat, to: targetFormat)!
print("[QUICOpusRecorder]: installTap")
inputNode.installTap(onBus: 0, bufferSize: tapBufferSize, format: hardwareFormat) { [weak self] buffer, _ in
guard let self else { return }
// Here I handle audio data and sometimes get silence
}
//...
do {
audioEngine.prepare()
try audioEngine.start()
} catch {
print(" ⚠️ Audio engine start error: \(error)")
handleError(error)
}
}
Moreover, if the app is in the foreground and PushToTalk gets stuck in this “silence bug”, I can avoid relying on the PushToTalk flow and simulate audio session activation manually in code. In this case I do not request a transmission and do not use any PushToTalk related code, and the app captures audio data perfectly.
Once I leave the channel and rejoin it again, the issue is fixed and I start to receive non silent buffers of varying size, as expected.
It works for a while. It can work fine for a day or more, communicating without launching the app, or with the app in the foreground. But it can also go into the “silence” state 30 minutes after working normally.
I have no clue why this happens. The only thing I notice is that when the app is in this “stuck silence bug” state, iOS does not play its “chirp” system sound when audio recording starts.
P.S. Channel descriptor restoration code:
extension PushToTalkEngine: PTChannelRestorationDelegate {
public func channelDescriptor(restoredChannelUUID channelUUID: UUID) -> PTChannelDescriptor {
print("☀️ \(#function) channelUUID: \(channelUUID)")
Task { @MainActor in
// Here I fetch more detailed channel data asynchronously
do {
await initChannelManagerIfNeeded(channelUUID: channelUUID)
let channelDescriptor = currentChannelDescriptor()
lastChannelDescriptorName = channelDescriptor.name
try await channelManager?.setChannelDescriptor(
channelDescriptor,
channelUUID: channelUUID
)
} catch {
handleError(error)
}
}
return PTChannelDescriptor(name: "Loading...", image: nil)
}
}
private func initChannelManagerIfNeeded(channelUUID: UUID? = nil) async {
guard let channelUUID = channelUUID ?? currentUser?.globalChannelUUID else {
print("❌ No global channel uuid found")
return
}
do {
guard channelManager == nil else {
try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID)
return
}
channelManager = try await PTChannelManager.channelManager(
delegate: self,
restorationDelegate: self
)
try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID)
} catch {
handleError(error)
}
}
I have a working walkie-talkie app based on the PushToTalk framework. Everything works fine except for an intermittent bug that I face from time to time on different devices with different iOS versions, from iOS 18 to iOS 26.2 Beta.
The next time this occurs, please capture a sysdiagnose, file a bug on this, then post the bug number back here. What you're describing sounds similar to a CallKit issue (r.157725305). A fix is being investigated for the CallKit issue, but if it's happening to the PTT system, then that's something we'd need to address.
Once I leave the channel and rejoin it again, the issue is fixed and I start to receive non silent buffers of varying size, as expected.
Assuming this is similar to the CallKit issue, this works because it's "updating" the audio session ID that callservicesd uses to activate your audio session. Unfortunately, that also means that it's basically the only thing that WILL work.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware