Fix UI freeze when receiving voice notes

Problem: AVAudioPlayer initialization in VoiceNotePlaybackController.init()
was running synchronously on main thread during view creation, blocking
UI for 50-200ms per voice note.

Solution:
- Remove eager preparePlayer() call from init
- Load duration asynchronously on background queue
- Player is only prepared when playback is actually requested via ensurePlayerReady()

This prevents UI freezes when voice notes appear in the chat.
This commit is contained in:
jack
2025-10-15 17:37:19 +01:00
committed by islam
parent f0ca1b27c2
commit 59cc857fde
2 changed files with 23427 additions and 23375 deletions
@@ -16,7 +16,23 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
init(url: URL) { init(url: URL) {
self.url = url self.url = url
super.init() super.init()
preparePlayer(for: url) // Load duration asynchronously to avoid blocking main thread
loadDurationAsync()
}
private func loadDurationAsync() {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else { return }
do {
let player = try AVAudioPlayer(contentsOf: self.url)
let duration = player.duration
DispatchQueue.main.async {
self.duration = duration
}
} catch {
SecureLogger.error("Failed to load audio duration for \(self.url.lastPathComponent): \(error)", category: .session)
}
}
} }
deinit { deinit {
@@ -27,7 +43,8 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
guard url != self.url else { return } guard url != self.url else { return }
stop() stop()
self.url = url self.url = url
preparePlayer(for: url) player = nil
loadDurationAsync()
} }
func togglePlayback() { func togglePlayback() {
@@ -83,6 +100,7 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
// MARK: - Private Helpers // MARK: - Private Helpers
private func preparePlayer(for url: URL) { private func preparePlayer(for url: URL) {
// Prepare player synchronously (only called when playback is requested)
do { do {
let player = try AVAudioPlayer(contentsOf: url) let player = try AVAudioPlayer(contentsOf: url)
player.delegate = self player.delegate = self
+23407 -23373
View File
File diff suppressed because it is too large Load Diff