2

I inherited some code for use in detection of end of speech.

...
recognitionRequest.shouldReportPartialResults = true 
recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in

    if result != nil {

        if self.eosTimer != nil {
            self.eosTimer!.invalidate()
            self.eosTimer = nil
        }
        self.eosTimer = Timer(timeInterval: 2.0, target: self, selector: #selector(self.timerHasCompleted(timer:)), userInfo: nil, repeats: false)
        RunLoop.current.add(self.eosTimer!, forMode: .commonModes)
    }
    ...

I assume this is because the timer is added to RunLoop. Without doing that, the timer doesn't fire at all. How can I get the eosTimer to only fire once?

  • You've specified `shouldReportPartialResults`. So this could get called multiple times. In terms of why you need to `add`, that's because you're using `Timer(...)`, which just creates the timer and doesn't schedule it. If you create it with [`scheduleTimer`](https://developer.apple.com/documentation/foundation/timer/1412416-scheduledtimer), you don't have to call `add`. – Rob Sep 03 '17 at 03:08
  • Even with using schedule (which works) I still have the timer firing twice. I need partial results because each time I get a segment result I want to invalidate the timer. When 2 seconds with no results happens, then I know entry of speech has occurred. I don't know why the timer selector is being called twice yet. – Radagast the Brown Sep 03 '17 at 03:12
  • Is it getting called more than two seconds apart? I'd suggest `NSLog` as the timer is created and `NSLog` in the selector so you can confirm precisely when timers are created and when they fire. Bottom line, timers don't just fire multiple times by themselves. You must have some flow that is permitting this. Or you have something calling `timerHasCompleted` directly. But the problem isn't with timers, themselves, but something about how you're calling it. And there's not enough here to reproduce/diagnose the problem. – Rob Sep 03 '17 at 03:30
  • 1
    I think whats happening is that the timer is cleared repeatedly, I stop talking, the timer fires, and 2 seconds later fires again because the task returns the same result a couple of times more than 2 seconds later. It's a little odd. So I used a BOOL variable and check that. It's set in the selector so that the timer only now fires once because it can only be created if the selector hasn't fired yet. I'm not sure I can say that's an answer though. – Radagast the Brown Sep 03 '17 at 13:44

0 Answers0