I am trying to assign regular function like this
var body: some View {
contentView
.task {
navigation.tabBarVisibility = .hidden
viewModel.fetchWordset()
synthesizer.onNextUtteranceEnded = onNextUtteranceEnded
}
}
private func onNextUtteranceEnded(_ utterance: AVSpeechUtterance) {
guard utterance.voice?.language == "pl-PL" else { return }
viewModel.next()
}
That is defined in swiftui view
To @StateObject var SpeechSynthesizer
that has property
public final class SpeechSynthesizer: NSObject, ObservableObject, AVSpeechSynthesizerDelegate {
@Published public var isSpeaking = false
public var onNextUtteranceStarted: ((AVSpeechUtterance) -> Void)?
public var onNextUtteranceEnded: ((AVSpeechUtterance) -> Void)?
But I am getting warning
Converting function value of type '@MainActor (AVSpeechUtterance) -> ()' to '(AVSpeechUtterance) -> Void' loses global actor 'MainActor'
What I can do about it?
A View
is, as you have pointed out, tied to the @MainActor
. This means that the implementation of onNextUtteranceEnded
in your view is also tied to the main actor.
SpeechSynthesizer
's property doesn't hold any such restriction, so the compiler is telling you that it won't be able to help you out should you happen to call onNextUtteranceEnded
via the synthesizer from any other actor, you might get yourself in a mess.
The answer is in the warning:
Converting function value of type '@MainActor (AVSpeechUtterance) -> ()'
This is the type of your view's function
to '(AVSpeechUtterance) -> ()' loses global actor 'MainActor'
This is the type of SpeechSynthesizer.onNextUtteranceEnded
You can remove the warning by changing the definition:
public var onNextUtteranceEnded: (@MainActor (AVSpeechUtterance) -> ())?
However, as others have pointed out, this does feel like a strange way to do things. You have a state object, that should be making logic decisions internally and updating published properties. The view should just be responding to those changes.