Reputation: 121
Can anyone share how we can implement AVSpeechSynthesizerDelegate in SwiftUI. how we can listen to delegate callbacks methods in SwiftUI app.
Thanks
Upvotes: 2
Views: 788
Reputation: 1061
One solution would be to define a class which conforms to ObservableObject
. The idea would be to use an @Published
property to enable SwiftUI to make updates to your UI. Here's an example of a simple way to keep track of the state of an AVSpeechSynthesizer
(I'm unsure of your actual use case):
final class Speaker: NSObject, ObservableObject {
@Published var state: State = .inactive
enum State: String {
case inactive, speaking, paused
}
override init() {
super.init()
synth.delegate = self
}
func speak(words: String) {
synth.speak(.init(string: words))
}
private let synth: AVSpeechSynthesizer = .init()
}
Then, make this class conform to AVSpeechSynthesizerDelegate
like so:
extension Speaker: AVSpeechSynthesizerDelegate {
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {
self.state = .speaking
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) {
self.state = .paused
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
self.state = .inactive
}
// etc...
}
Here, I've simply used the delegate callbacks to update a single @Published
property, but you could update however you like here depending on your use case. The main point to bear in mind with ObservableObject
s is using the @Published
property wrapper for any properties you wish to drive UI updates upon a change in value. Here's an example view:
struct MyView: View {
@ObservedObject var speaker: Speaker
var body: some View {
// 1
Text("State = \(speaker.state.rawValue)")
.onReceive(speaker.$state) { state in
// 2
}
}
}
Note how there's two ways to use @Published
properties in SwiftUI View
s. 1: Simply read the value. SwiftUI will update your view upon a value change. 2: Access the @Published
property's publisher with the $ prefix. Using View
s onReceive
method, you can execute code whenever the publisher emits a value.
Upvotes: 7