Help with Text to Speech

I have discovered that I can make the iPhone speak text with the following two lines of code.

let synth = AVSpeechSynthesizer()
synth.speak(AVSpeechUtterance(string: "Text to be spoken."))

However lets say I have an array of strings and I would like to speak the first item in the array. Then remove that idem from the array and speak the next?
If its already speaking and I send another synth.speak it just starts speaking them both at the same time.

You may have to deliberately introduce a delay to give the speech synthesiser time to complete.

Alternatively, does synth.speak() return a value to indicate that it has completed the the task?

I tried doing a while synth.isSpeaking loop to wait for it to stop speaking but then the app freezes up until it finish’s speaking.

It might have to do the speaking on a background thread. I’m guessing here as I have not used the speech synthesiser.

Another solution:

If the intention is to play all the text elements in an array then lets look at this example

let stringArray = ["The", "quick", "brown", "fox", "jumps", "over", "the ", "lazy", "dogs", "back."]
let speechString = stringArray.joined(separator: " ")
synth.speak(AVSpeechUtterance(string: speechString))

What that does is concatenate all the elements in the array of strings into one string separated by a space and then play it in one single call to synth.speak.

I set up a test project to see if that works and its fine.

If the array of strings is a random set of words that are in no specific order then you can do this:

let stringArray = ["The", "quick", "brown", "fox", "jumps", "over", "the ", "lazy", "dogs", "back."]
let speechString = stringArray.joined(separator: ", ")
synth.speak(AVSpeechUtterance(string: speechString))

What that results in is each of the words being read with a different speech inflection and pause due to the comma.

thanks, yes the reason why I was using the array is because its possible for new things to be spoken to be added to the array while its currently saying something, once finished it moves on to whatever is left in the array.

After looking into your first suggestion I have found a solution that is working. Instead of using the Array, I am just executing the code via background thread. I can just push out something to say into the background thread and they all get executed one after another as more get added to the queue.

let dispatchQueue = DispatchQueue(label: “speech”, qos: .background)
dispatchQueue.async{
self.synth.speak(AVSpeechUtterance(string: “Say something!”))
}

1 Like