AVSpeechSynthesizer не работает при добавлении новых строк для произнесения [xcode - swift 4]

Я использую код ниже, чтобы читать случайные предложения в случайное время. Однако я сталкиваюсь с проблемой, когда для чтения вызывается случайное предложение, в то время как предыдущее предложение все еще произносится AVSpeechSynthesizer, в результате чего второе предложение не произносится. Я спрашиваю, как я могу произнести второе предложение после того, как первое предложение будет произнесено?

Любой импорт приветствуется. Ваше здоровье

Вот мой код:

import UIKit
import AVFoundation


class ViewController: UIViewController {

var myTimer = Timer()
   let string = ["what kind of car do you have?", "do you like the beach?","did you bring a towel?","There are big waves today"]
var randomTimer = Int()


@objc func speakToMe(){

    let random = Int.random(in: 0...3)
    randomTimer = Int.random(in: 0...2)
    print(randomTimer)
    print(string[random])


let utterance = AVSpeechUtterance(string: string[random])
utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
utterance.rate = 0.1
let synthesizer = AVSpeechSynthesizer()
synthesizer.speak(utterance)

}

override func viewDidLoad() {
    super.viewDidLoad()
    speakToMe()
    myTimer = Timer.scheduledTimer(timeInterval: TimeInterval(randomTimer), target: self, selector: #selector(ViewController.speakToMe), userInfo: nil, repeats: true)
}


}   

person Dan.code    schedule 20.03.2019    source источник


Ответы (1)


Вы можете просто использовать AVSpeechSynthesizerDelegate для этого, и вы можете удалить таймер из своего кода.

И чтобы использовать AVSpeechSynthesizerDelegate, сначала вам нужно подтвердить свой контроллер представления с помощью AVSpeechSynthesizerDelegate, как показано ниже:

class ViewController: UIViewController, AVSpeechSynthesizerDelegate {

следующее, что вам нужно добавить

synthesizer.delegate = self

в вашем методе viewDidLoad. и вам нужно объявить

let synthesizer = AVSpeechSynthesizer()

вне методов и внутри класса.

И вы можете использовать свойство randomElement, чтобы найти случайный элемент из массива string.

И ваш окончательный код будет выглядеть так:

import UIKit
import AVFoundation

class ViewController: UIViewController, AVSpeechSynthesizerDelegate {

    let string = ["what kind of car do you have?", "do you like the beach?","did you bring a towel?","There are big waves today"]
    let synthesizer = AVSpeechSynthesizer()

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

    @objc func speakToMe(){

        let utterance = AVSpeechUtterance(string: string.randomElement()!)
        utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
        utterance.rate = 0.1
        synthesizer.speak(utterance)

    }

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

ИЗМЕНИТЬ:

Поскольку вы используете только 4 элемента в своем массиве, у вас будет возможность повторять одно и то же предложение много раз, когда вы берете для него случайную строку, поэтому вы можете добавить сюда еще одну логику, которая предотвратит это.

Обновите свою функцию speakToMe, как показано ниже:

@objc func speakToMe(){

    var randomStr = string.randomElement()!
    while previousStr == randomStr {
        randomStr = string.randomElement()!
    }
    previousStr = randomStr
    let utterance = AVSpeechUtterance(string: randomStr)
    utterance.voice = AVSpeechSynthesisVoice(language: "en-GB")
    utterance.rate = 0.1
    synthesizer.speak(utterance)
}

И объявить var previousStr = "" вне функции.

person Dharmesh Kheni    schedule 20.03.2019