P i
P i

Reputation: 30684

How to detect (say) 2 seconds of inactivity in swift?

This question could be rephrased as: How to invoke a function if 2 seconds pass without an event (re)occurring?

I'm playing with SFSpeechRecogniser. While the user is speaking it sends continuous updates (maybe 2-3 per second). I'm trying to detect when the user stops speaking. If I don't receive any updates for (say) 2 seconds, I can assume that the user has paused speaking.

How to implement this in Swift?

I am aware that I could do:

var timer : Timer?

func f() {
    on_event = { result, error in
        print( "Got event, restarting timer" )
        self.timer?.invalidate()
        self.timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { _ in
            print( "2s inactivity detected" )
            self.timer?.invalidate()
            NotificationCenter.default.post( name: inactivity_notification,  object: nil )
        }
    }
}

But is it possible to do it without repeatedly creating and destroying the Timer instance (and thus creating a boatload of temporary Timer instances that never get used)?

Upvotes: 0

Views: 287

Answers (2)

trapper
trapper

Reputation: 11993

Timer's .fireDate property is writable.

So every time a speech event occurs just do timer.fireDate = Date(timeIntervalSinceNow: 2)

Upvotes: 1

vacawama
vacawama

Reputation: 154603

One way to do it is to:

  1. Record the current time when an event occurs
  2. Set up a recurring timer with a granularity you are comfortable with (for example 0.25 seconds).
  3. When the timer pops, check difference between current time and last event time. If that is greater than 2 seconds, fire your notification.

This is what I'd do if I had to recognize that a person had stopped typing for 2 seconds. Invalidating and creating timers at typing speed would be a lot of churn. You can tune this to your requirements depending on how close to exactly 2 seconds you need to be.

You could also do this by just having a timeSinceLastEvent variable, and set it to 0 when an event occurs. The recurring timer would increment this by the granularity, and check if it has reached 2 seconds and fire the notification if it had. This is cruder than doing the time math since the timer interval isn't guaranteed, but simpler.

Upvotes: 1

Related Questions