What is an NSTimer's behavior when the app is

2020-04-06 00:53发布

I know that when you background an app, the timer stops running. However, what is the behavior when you come back from the background? Does the timer maintain its original fireDate?

I've run into a bit of an issue where upon returning from the background with an NSTimer set to fire in ten minutes, sometimes I'll immediately have the timer fire before applicationWillEnterForeground: is even called. When it doesn't fire, and applicationWillEnterForeground: is called, I have some logic to check if the 10 minutes has passed by comparing the timer's fireDate to the current date, however, even if 10 minutes has passed, it always seems to give me a value of about 525 seconds in the future from the current date.

My theory is the following:

  • An NSTimer will fire the timer upon coming back from the background, as long as you haven't missed the scheduled time by more than what was originally scheduled. (In this case, we schedule the timer for 10 minutes, as long as you're in the background for between 10-20 minutes, it will fire upon re-entering the app.)

  • If more than that has passed, it does not fire and instead schedules another timer for the same time period in the future when you return. (A.K.A. If you've been in the background for 20+ minutes with a 10 minute timer, when you get back, it schedules the timer for 10 minutes in the future from the time you return to the app.)

Does anyone have any documentation on this behavior? My theories are based purely off observation, the documentation on what happens when backgrounding is either woefully lacking, or I haven't been able to find it.

2条回答
贼婆χ
2楼-- · 2020-04-06 01:23

You observed correctly how an NSTimer behaves.

If you create a timer right now that should fire every ten minutes, it will try to fire ten minutes, 20 minutes, 30 minutes and so on from now. If the app goes to sleep after one minute and wakes up after 12 minutes, the timer will fire immediately, and then again at 20 minutes (not ten minutes after the timer firing, but 20 minutes after the original time).

But if the timer misses one event completely and then is late for the next timer event as well, say if you wake up after 29 minutes, then the 10 minute event is dropped, the 20 minute event is fired as soon as possible (after 29 minutes), and the 30 minute event is fired after 30 minutes.

查看更多
可以哭但决不认输i
3楼-- · 2020-04-06 01:30

You can't use timers for this problem. Here is what I discovered after investigating a similar problem:

  • After an app has been in the background for about 30 seconds, the timer stops.
  • When you re-enter from background the timer starts to fire again.

What you can do to overcome this problem and add this functionality properly you would have to implement the timers on your backend server. Hit a service when the timer starts and start the timer when the app is in foreground. The timer will take care of itself but when app is terminated or in the background the server will come into play. Hit a service to get how much time has elapsed or send a push notification when the 10 minutes have passed.

查看更多
登录 后发表回答