Problem with AVFoundation / AVSpeechUtterance on iOS (works on Mac OS, but not on iPhone)

I tried the following code which works fine under Mac OS 11 (iPhone 8 Plus simulator Big Sur on Mac mini M1), but does not generate sound under iOS (iPone 8 plus):

I don't know what the issue is:

  • Authorisation problem (plist or something)?
  • Version of iOS?
  • Libraries?

... or how to debug it...

    import SwiftUI
    import AVFoundation //Speech library

    struct ContentView: View {
        @State var text: String = "Starting"
        
        var body: some View {
            VStack {
                Text(text)
                    .fontWeight(.bold)
                    .font(.title)
                    .padding()
                Button(action: speak) {
                    Text("Click to test TTS")
                }
            }
        }
        
        func speak(){
            let utterance = AVSpeechUtterance(string: "Hello world")
            utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
            if utterance.voice != nil {
                self.text = "Voice available"
            } else {
                self.text = "Pb: Voice not available"
            }
            utterance.rate = 0.5
            utterance.volume = 1.0
            let synthesizer = AVSpeechSynthesizer()
            synthesizer.speak(utterance)
        }
    }

You need to retain a reference to AVSpeechSynthesizer.
You can e.g. put in a @State variable of your view.

Source:

Note

The system doesn’t automatically retain the speech synthesizer so you need to manually retain it until speech concludes.

1 Like

Thank you very much for your answer.
I tried moving the declaration of the AVSpeechSynthesizer object at the beginning of the file, like so:

import SwiftUI
import AVFoundation //Speech library

struct ContentView: View {
    @State var text: String = "Starting"
    @State var synthesizer = AVSpeechSynthesizer()

But it does not make a difference, the app still does not generate any sound when run on an iPhone.

1 Like

The sound of the app was in fact blocked by the "mute" switch (the physical mute switch on the left of the iPhone). It works fine now. This is odd because I'm also working on a voice recorder app and that one wasn't blocked by the same switch...

1 Like

The physical switch only controls the speakers/headphones, i.e., output only. You can mute the microphone during a phone call, and you may be able to mute the microphone using another app, or some obscure Siri setting, but, according to the known references, there is no simple way to turn off all the microphones in an iPhone. It's probably because iOS relies on audio cues, especially Siri, which requires the mics to be on.

1 Like