1

I'm currently putting together my first app using XCode 9.4.1 and Swift. Within my code, I am working my way through a list and I would like each value in the list to be spoken aloud. Below is my code for this

// classificationResults is my list
for returnedValue in self.classificationResults{
                    let utterance = AVSpeechUtterance(string: returnedValue)
                    utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
                    utterance.rate = 0.5

                    let synthesizer = AVSpeechSynthesizer()
                    synthesizer.speak(utterance)
                    // print(returnedValue)

When running this in the simulator, it works however it only says allowed the first one or two values out of the list (there are 7). When I then run this directly on my device, nothing is said aloud.

Any ideas / suggestions? Thanks in advance

thefragileomen
  • 1,537
  • 8
  • 24
  • 40

2 Answers2

2

The problem may be your player lifecycle: the most important thing to remember is to retain your AVSpeechSynthesizer instance until full speech is done.

Move your synthesizer creation outside the loop and keep it alive until the end of the speech: this answer may help as well.

XLE_22
  • 5,124
  • 3
  • 21
  • 72
0

I have implemented following code to make my all text to voice conversion by using AVSpeechSynthesizer. This code as a example, you can try by your code.

class TextToVoiceVC: UIViewController, AVSpeechSynthesizerDelegate {

    var arrSpeechCount = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"]
    var count : Int = 0
    let speechSynthesizer   = AVSpeechSynthesizer()        

    //----------------------------------------------------------------
    // MARK:- AVSpeechSynthesixerDelegate
    //----------------------------------------------------------------

    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) {

    }

    //----------------------------------------------------------------

    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {

        speechSynthesizer.stopSpeaking(at: .word)

        count += 1
        if count < arrSpeechCount.count {
            let speechUtterance = AVSpeechUtterance(string: (arrSpeechCount[count]))
            DispatchQueue.main.async {
                self.speechSynthesizer.speak(speechUtterance)
            }
        }
    }


    //----------------------------------------------------------------
    // MARK:- View Life Cycle Methods
    //----------------------------------------------------------------

    override func viewDidLoad() {
        super.viewDidLoad()
        speechSynthesizer.delegate = self
    }

    //----------------------------------------------------------------

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // Code to start speech
        if speechSynthesizer.isSpeaking {
            speechSynthesizer.stopSpeaking(at: .immediate)
        } else {
            let speechUtterance = AVSpeechUtterance(string: (arrSpeechCount[count]))

            DispatchQueue.main.async {
                self.speechSynthesizer.speak(speechUtterance)
            }
        }
    }
}

This code is working in my both simulator as well as device. I hope this will useful to you also. You should try delegate with your data.

Sagar Chauhan
  • 5,715
  • 2
  • 22
  • 56