Skip to content

Commit

Permalink
fix(ios): speak method resolves immediately on iOS (#59)
Browse files Browse the repository at this point in the history
* fix(ios): `speak` method resolves immediately on iOS

* style: format
  • Loading branch information
robingenz authored Mar 20, 2021
1 parent 2b6da17 commit e77e8ba
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 18 deletions.
46 changes: 30 additions & 16 deletions ios/Plugin/TextToSpeech.swift
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
import AVFoundation
import Capacitor

@objc public class TextToSpeech: NSObject, AVSpeechSynthesizerDelegate {
let synthesizer = AVSpeechSynthesizer()
var utterance: AVSpeechUtterance?
var calls: [CAPPluginCall] = []

override init() {
super.init()
self.synthesizer.delegate = self
}

public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
self.resolveCurrentCall()
}

public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
do {
try AVAudioSession.sharedInstance().setActive(false)
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
try AVAudioSession.sharedInstance().setActive(true)
} catch {}
self.resolveCurrentCall()
}

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

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

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

self.synthesizer.stopSpeaking(at: .immediate)
self.calls.append(call)

self.utterance = type(of: AVSpeechUtterance()).init(string: text)
self.utterance?.voice = AVSpeechSynthesisVoice(language: lang)
self.utterance?.rate = adjustRate(rate)
self.utterance?.pitchMultiplier = pitch
self.utterance?.volume = volume
self.synthesizer.speak(self.utterance!)
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: lang)
utterance.rate = adjustRate(rate)
utterance.pitchMultiplier = pitch
utterance.volume = volume
synthesizer.speak(utterance)
}

@objc public func stop() {
synthesizer.pauseSpeaking(at: .immediate)
synthesizer.stopSpeaking(at: .immediate)
}

Expand All @@ -64,4 +65,17 @@ import AVFoundation
}
return rate / 2
}

@objc private func resolveCurrentCall() {
do {
try AVAudioSession.sharedInstance().setActive(false)
} catch {
CAPLog.print(error.localizedDescription)
}
guard let call = calls.first else {
return
}
call.resolve()
calls.removeFirst()
}
}
3 changes: 1 addition & 2 deletions ios/Plugin/TextToSpeechPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public class TextToSpeechPlugin: CAPPlugin {
}

do {
try implementation.speak(text, lang, rate, pitch, category, volume)
call.resolve()
try implementation.speak(text, lang, rate, pitch, category, volume, call)
} catch {
call.reject(error.localizedDescription)
}
Expand Down

0 comments on commit e77e8ba

Please sign in to comment.