为什么第二次调用我的函数会被触发两次? (Swift iOS计时器/语音识别)

时间:2018-04-10 12:07:02

标签: ios swift speech-recognition speech speech-synthesis

当定时器在最后一次录制的语音输入后达到1.5秒后,

self.adaResponseApi运行两次。它应该只运行一次。

它专门从1.5间隔实例化运行而不是从第一个实例化运行,这是在用户专门停止语音输入时触发的。

recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
    if result != nil {
        self.textView.text = result?.bestTranscription.formattedString
        self.isFinal = (result?.isFinal)!
    }

    if let timer = self.detectionTimer, (timer.isValid) {
        if self.isFinal! {
            self.detectionTimer?.invalidate()
            self.adaResponseApi()
            self.isFinal = true
        }
    } else  { // if self.isFinal == false
        self.detectionTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false, block: { timer in
            self.adaResponseApi() // This call gets triggered twice and for the life of me I can't figure out why.
            timer.invalidate()
            self.isFinal = true
        })
    }
})

1 个答案:

答案 0 :(得分:0)

好了,这就是......我假设请求已将shouldReportPartialResults设置为true(默认值)。

recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { [weak self] (result, error) in
    // [weak self] to stop memory leaks

    guard let result = result else {
        // no result means probably an error, you should report that to your user
        return
    }

    // display the most accurate transcription (partial or final)
    self?.textView.text = result.bestTranscription.formattedString

    // invalidate timer
    // result is final (and so should invalidate timer)
    // or result is partial (and so will create new timer ... and invalidate this one)
    self?.detectionTimer?.invalidate()

    if result.isFinal {
        // we have a final result... use it
        self?.adaResponseApi()
    } else {
        // create timer for if the next response times out
        self?.detectionTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] timer in
            self?.adaResponseApi()
        }
    }
}

我想我会这样做......

我不是100%肯定你的计时器是什么,所以我认为它是在那里,以防识别器没有快速返回响应,所以我们可以回到最近的partial结果?

我也认为我们不应该存储result.isFinal的值。如果确实需要,则可以在self?.textView.text = result.bestTranscription.formattedString之后将其添加到该行。