4

In my application i want to run an internal clock in background mode [while application is not running in foreground].

The whole functionality will be like this:

The objective is to get the server time to use in the application, because using device time may sometimes cause issues. The issues may be in situations like somebody has changed the user's iPhone time etc. So i am following the below method.

-Running an internal clock in my application background even if the application is not running. -Communicate with server every 15 minutes to get the real time and run a timer. -If net is disconnected in between,timer will continue and take the timer time.

My application is heavily depended on this time factor as this is a ticket booking system.Kindly help me to implement this or please confirm whether this is possible or not?

I am developing an iPhone application which involves Ticket Booking System. I registered my application as location based beacuse it is using user's location taken in background for a purpose.

My problem is that i need to run an internal clock in my application in background mode. I need to write the codes for internal clock in core location delegate methods, so that internal clock will also run along with the location bsed services. Will my app get rejected? Is anything wrong in doing like this?

I need to get the correct time to use in my app, so that i am running this internal clock. I can use NSDate, but that will return the device time. Anyone can change the device time. So once somebody chaged, wrong time will affect the smooth functioning of the app. Kindly some body suggest to get the correct time with out running the internal clock ?

Praveen
  • 301
  • 2
  • 11
  • Answer here: http://stackoverflow.com/questions/12488481/getting-ios-system-uptime-that-doesnt-pause-when-asleep/12490414#12490414 – Russell Quinn Jul 03 '14 at 19:57

5 Answers5

14

Update: Sorry to say my original answer isn't correct. When the device goes to sleep (can happen sometime after it's locked) the internal CPU clock stops ticking, and mach_absolute_time won't update either. Theoretically it will return the exact same value if you call it right before the device went to sleep, and after it awakes.

The best available way I know of to check for date changes is kern.boottime, it holds the boot time, and is modified whenever the system time changes. Among other things, kern.boottime will be updated if the user changes the time, or if the OS changes the time itself according to info from cell towers.

So, in your case, you can take the original time you calculated and modify it according to the modifications in kern.boottime. If you see kern.boottime changed significantly, it may mean that the device was turned off, and in this case you will need to contact the server to ask it for the time until the flight.

Relevant code:

time_t getBootTimeSecs(void)
{
    struct timeval boottime;    
    size_t size = sizeof(boottime);
    int ret = sysctlbyname("kern.boottime", &boottime, &size, NULL, 0);
    assert(ret == 0);
    return boottime.tv_sec;
}

Original (incorrect) answer: You can use mach_absolute_time which isn't affected by date changes made by the user.

When you book the ticket, get the correct date from the server and record mach_absolute_time. Now you will always be able to call mach_absolute_time whenever you want, calculate the difference from the one you recorded initially, and display the correct date.

This will only work as long as the device wasn't shut down, in that case it makes sense for the app to re-connect to the server to get the correct date.

You can also either Local or Push Notifications to alert the user when the target date is getting closer, even if the app isn't running.

Danra
  • 9,546
  • 5
  • 59
  • 117
  • here only problem is while user switch off the device.Is there any way to know whether user switched off and on his device? – Praveen Mar 23 '12 at 05:33
2

apple is support small task for background mode which will work for approximate 10 sec only.

so you can do one thing when app is active then get time form server and update your local time according that.

priyanka
  • 2,076
  • 1
  • 16
  • 20
  • yes, i thought about that...but we have to think about the offline condition also.if there is no net connection, we cannot get the server time.We need the correct time because the image in the ticket is changing with respect with time.Anyone please suggest a solution that is applicable for offline mode also... – Praveen Mar 05 '12 at 12:29
  • 1
    use NSDate and convert that time to server timezone. this will give you perfect time. – priyanka Mar 05 '12 at 13:50
  • http://stackoverflow.com/questions/5985468/iphone-differences-among-time-zone-convenience-methods – priyanka Mar 06 '12 at 06:13
  • @priyanka....how this provide the correct time, if user changed his device time? If i depend only on device time, the user can easily hack my app by changing the device time...i am asking a solution for this? – Praveen Mar 14 '12 at 11:33
2

I think that you can only detect that the date of the iOs device has been changed (using NSSystemClockDidChangeNotification). I guess you to use this notification and force reload the real date of your application from your server (With a WebService).

EDIT: You can use the systemUptime in NSProcessInfo:

 NSLog(@"ProcessInfo System uptime: %f",[NSProcessInfo processInfo].systemUptime);

but it will not solve your problem if the Device is restarted.

Julien
  • 963
  • 5
  • 8
  • I am developing this for a travel agency.So i have to thing the worst condition of not having net connection after booking tickets to journey time.So your last sentence is not possible.Thanks for your suggestion on NSSystemClockDidChangeNotification. Changing time will not be reflected on this? I need to call this method while app is in foreground mode? or will this work in bg mode also?What abou the method applicationSignificantTimeChange:, will this help to know whether time changed manually? – Praveen Mar 14 '12 at 12:19
  • 1
    the notification UIApplicationSignificantTimeChangeNotification doesn't mean that the time clock has been changed in preference pane of the device, it means that there is a significant change of the time (like day has changed,...). – Julien Mar 14 '12 at 12:29
  • Ok...so it won't recognize small time changes made manually..Kindly expalain NSProcessInfo? – Praveen Mar 14 '12 at 14:10
1

I think there are 2 ways you can go about solving your problem.

  1. Never use system time. In other words, never call [NSDate date] in your code. When you need the current time, call an NTP server. This will of course cause latency in your app, but will guarantee accuracy.

  2. When the app launches, or enters foreground, verify that the system time is reasonably accurate against an NTP server. If the system time is off by more than your tolerance level, then do not let them continue running the app until they address it. If the system time is okay, then start monitoring to ensure they don't change the system time while running the app (NSSystemClockDidChangeNotification). If they pass the initial check, but the move the clock forward, you can catch that and disable the app til they change it back to being accurate.

Here is an iOS NTP implementation which could be helpful in implementing either solution above. http://code.google.com/p/ios-ntp/

EDIT: The Ticketmaster app uses technique #2, so this seems like a reasonable solution for a ticketing app that requires your system time to be correct.

Joel
  • 15,654
  • 5
  • 37
  • 60
1
  1. timezone settings should not affect time as in UTC
  2. your app cannot run in the background. Abusing the location requirement for this will cause your app to be rejected by Apple

so my suggestion: do the logic server side with push notification

Dirk de Kok
  • 199
  • 12