1

I am developing an iOS application for iPod Touch in which my application displays the server time always. I always sync the application time with server time whenever the application comes to foreground by making a web service call to the server. If there is a connectivity loss between my server and client for few hours I wont be able to sync the application time. I read iOS does not support running a timer when the application is in background other than few limited cases mentioned below:

  • Apps that play audible content to the user while in the background, such as a music player app
  • Apps that keep users informed of their location at all times, such as a navigation app
  • Apps that support Voice over Internet Protocol (VoIP)
  • Newsstand apps that need to download and process new content
  • Apps that receive regular updates from external accessories

So how can I keep track of application time? Whenever the user switches to my application he needs to look at the server time so I need to run a timer to update the last synced server time.

Tim
  • 5,024
  • 2
  • 30
  • 58
Cooldude
  • 31
  • 3
  • 9

3 Answers3

1

A combination of other answers, create a class in charge of obtaining the server time and maintaining the last time the application was synced to the server using a combination of NSDate* lastSync and applicationDidBecomeActive. For example:

-(void)applicationDidBecomeActive:(UIApplication*)application {
  [ServerTimeSync sharedInstance] resync];
}

ServerTimeSync will maintain an NSDate* property with the last sync time (you'll want to convert what the server gives you to an NSDate*).

Joe
  • 2,352
  • 20
  • 38
  • Hi Joe, I am willing to rely on the device time because it can be changed by the user at any point of time. – Cooldude Jul 10 '12 at 02:13
  • Others comments about the server time changing notwithstanding, you can add an observer for NSSystemClockDidChangeNotification to a ServerTimeSync class and react accordingly. Unfortunately I doubt that will be delivered to you if the task is suspended in the background. – Joe Jul 10 '12 at 02:40
  • @Cooldude - it shouldn't matter if the user changes the time and your app is suspended. When your app becomes active then you can sync with the server. Don't overthink it. – spring Jul 10 '12 at 02:46
0

You can store the NSDate when the app goes into the background. When it resumes, get the current NSDate again, and add the difference to your stored server time.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Hi Josh,I went with this approach and started facing issues when the user changes the time in the device. – Cooldude Jul 10 '12 at 02:08
  • Have a gander at [How can I locally detect iPhone clock advancement?](http://stackoverflow.com/questions/7122216/how-can-i-locally-detect-iphone-clock-advancement-by-a-user-between-app-runs) – jscs Jul 10 '12 at 02:12
0

You don't need a timer for this at all.

I would suggest that when you sync time with your server, you have it return its current UNIX timestamp. You can then do:

[[NSDate date] timeIntervalSince1970];

...to get the device's current UNIX timestamp. Then what you can do is store the difference between these two timestamps. This is the clock skew between the server time and the device time.

You can now compute the server's approximate time by taking the device's current UNIX timestamp and adding the clock skew to it. Adjust for time-zone when displaying it (if you want), and you're done. Whenever you sync time with the server, you can just refresh the stored clock skew value.

If you want to get fancy, you can also attempt to measure and take network latency into account when determining the clock skew.

This approach should work much better than trying to store the server's absolute timestamp and then track how much time has elapsed using a timer (or any other mechanism).

aroth
  • 54,026
  • 20
  • 135
  • 176
  • If we follow this approach the application time will not be reliable since the user can change his device time at any point of time then the whole logic crashes. – Cooldude Jul 10 '12 at 02:12
  • Check Josh Caswell's link on his answer. And of course, it's not possible to handle every possible edge case. What if the sysadmin (or even just the NTP daemon) changes the server's time? It would cause the same problem. – aroth Jul 10 '12 at 02:16
  • Based on the TIME displayed on the application will be used as reference for all the user actions of my application for syncing those changes to the server. SO I would like it think of all possible scenario's. Thanks for your suggestions. – Cooldude Jul 10 '12 at 02:55