Skip to content

Commit

Permalink
fix(ios): prevent UI hangs by optimizing AVAudioSession management (#135
Browse files Browse the repository at this point in the history
)
  • Loading branch information
physxP authored Sep 21, 2024
1 parent e134a42 commit aaa4ace
Showing 1 changed file with 11 additions and 14 deletions.
25 changes: 11 additions & 14 deletions ios/Plugin/TextToSpeech.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ import Capacitor
@objc public class TextToSpeech: NSObject, AVSpeechSynthesizerDelegate {
let synthesizer = AVSpeechSynthesizer()
var calls: [CAPPluginCall] = []
let queue = DispatchQueue(label: "backgroundAudioSetup", qos: .userInitiated, attributes: [], autoreleaseFrequency: .inherit, target: nil)

override init() {
super.init()
self.synthesizer.delegate = self
// set session in background to avoid UI hangs.
queue.async {
do {
let avAudioSessionCategory: AVAudioSession.Category = .playback
try AVAudioSession.sharedInstance().setCategory(avAudioSessionCategory, mode: .default, options: .duckOthers)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Error setting up AVAudioSession: \(error)")
}
}
}

public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
Expand All @@ -20,15 +31,6 @@ import Capacitor

@objc public func speak(_ text: String, _ lang: String, _ rate: Float, _ pitch: Float, _ category: String, _ volume: Float, _ voice: Int, _ call: CAPPluginCall) throws {
self.synthesizer.stopSpeaking(at: .immediate)

var avAudioSessionCategory = AVAudioSession.Category.ambient
if category != "ambient" {
avAudioSessionCategory = AVAudioSession.Category.playback
}

try AVAudioSession.sharedInstance().setCategory(avAudioSessionCategory, mode: .default, options: AVAudioSession.CategoryOptions.duckOthers)
try AVAudioSession.sharedInstance().setActive(true)

self.calls.append(call)

let utterance = AVSpeechUtterance(string: text)
Expand Down Expand Up @@ -77,11 +79,6 @@ import Capacitor
}

@objc private func resolveCurrentCall() {
do {
try AVAudioSession.sharedInstance().setActive(false)
} catch {
CAPLog.print(error.localizedDescription)
}
guard let call = calls.first else {
return
}
Expand Down

0 comments on commit aaa4ace

Please sign in to comment.