Issue Description
On some iOS 26.x devices, the application UI freezes for approximately 0.5 to 0.9 seconds when a user enters or leaves a channel while AirPods or other Bluetooth audio devices are connected.
Platform and SDK Context
Platform: iOS 26.x (Unity-based iOS application)
Hardware: AirPods or Bluetooth audio peripherals
SDK: Agora SDK
Error Message
No explicit error message is displayed. The issue manifests strictly as a UI freeze and a drop in framerate during channel transitions.
Root Cause Analysis
The freeze is caused by heavy operations running synchronously on the application’s main thread. Analysis of the freeze stack traces confirmed that no internal AgoraCore or AgoraRtcKit calls were responsible. The RTCAgora.destroyAsync entry found in the logs was part of the application’s own wrapper callback chain, not an Agora SDK internal block.
The primary factors blocking the main thread were:
Unity scene loading and UI hierarchy processing: The app was loading or activating Unity objects, executing
Awakemethods, changing UI Canvas hierarchies, and initializing IL2CPP metadata synchronously.Unity resource loading: Resources were read synchronously, with LZ4 decompression occurring directly on the main thread during scene loading.
Audio session state changes: During room exit, the application called the iOS native
AVAudioSessionmethodssetCategoryandsetActive. These specific calls waited on the iOS system audio service through XPC (cross-process communication), which introduced a visible UI delay, exacerbated by the connected Bluetooth audio route.Business network logic: Room list requests, HTTP request preparation, request signing, cryptographic logic, and Swift/Objective-C metadata handling were all executed on the main thread after leaving the room.
Solution and Resolution Steps
Optimize Unity Scene Loading
Avoid executing heavy computational work in the
Awakelifecycle method.Reduce UI Canvas hierarchy rebuilds during scene entry.
Preload required Unity objects and prefabs before the user actively enters the room.
Avoid Synchronous Resource Loading on the Main Thread
Move resource loading and asset decompression out of the UI-critical path.
Use asynchronous loading methods (
LoadAsync) wherever possible.Preload frequently used assets into memory before triggering the room entry flow.
Review Audio Session Handling During Room Exit
Avoid changing the
AVAudioSessioncategory or active state repeatedly or unnecessarily during the channel exit flow.Do not perform blocking audio session operations on the main thread in a way that freezes the UI.
Add timing logs around
setCategoryandsetActiveto monitor and confirm exactly how long these system calls take on the affected iOS devices.
Move Business Network Preparation Off the Main Thread
Execute HTTP request building, API signing, cryptographic operations, and metadata-heavy logic on a background queue or thread.
Only dispatch back to the main thread when a direct UI update is required.
Re-Test with Bluetooth Audio Connected
Reconnect AirPods or a Bluetooth headset to the device.
Enter and exit the channel repeatedly to confirm that the main thread is no longer blocked and the UI remains responsive during the transition.
Prevention and Best Practice
Keep Unity scene loading, resource decompression, AVAudioSession state changes, and business network preparation entirely out of the UI-critical path. Utilize asynchronous loading and background queues wherever possible. Furthermore, proactively add timing logs around suspected blocking operations (such as AVAudioSession changes) to easily identify performance bottlenecks when interacting with external Bluetooth audio hardware.