I am trying to design a system where real-time events happen and I want to synchronise them to a clock. [NSDate date]
would normally be ok but the user could change this and cheat the system. All I need is a clock that I can take relative times from (a 64-bit counter for example) - I don't need absolute time (or time of day etc).
Is there such an API I can use?
EDIT: I would also like to add that this clock needs to be persistent over sessions of the application.
The only idea that I can think of is to use a NTP server to obtain the clock, but that would require network connectivity.
I am using this in our app
What I know, that there is no any other method to get correct time. I would use NTP.
In one project I'm going to use NTP (tomorrow i quess), but I already did some research:
iOS library: https://github.com/jbenet/ios-ntp - Author notes: The implementation is not a rigorous as described in those RFCs since the goal was to improve time accuracy to with in a second, not to fractions of milliseconds.
For non-commercial project look on: www.packages.ubuntu.com/source/lucid/ntp
C library: www.hillstone-software.com/hs_ntp_details.htm
Documentation: www.nist.gov/pml/div688/grp40/its.cfm
If all you need is a clock to measure events as monotonically increasing, you could just get the current system uptime ala
clock_gettime(CLOCK_MONOTONIC)
. If restarting the device is a problem, just save the last value used and at next launch use the last saved value as an offset. The Problem here may be that if they actually shut the device off, it won't count that time. But if you're worried about the user speeding up time, they can't do that, only slow it down.I think
mach_absolute_time()
may be what you'll want. There is quite a bit of information here: http://developer.apple.com/library/mac/#qa/qa1398/_index.htmlIt is basically a counter of the number of ticks since the device started. This will be reset on reboot but other than that it is a monotonically increasing counter.
You can keep the last value of the counter around and deal with it if the counter has decreased since the last time (the device was restarted). In this case you can add the last known value to the current value to get a lower bound of the time that has elapsed, all you'd lose is the time between the last session and the device shut down, you would keep the time between the reboot and the next session though.
The best monotonically increasing number on an iPhone is
mach_absolute_time()
which is a count of CPU ticks since the last reboot. If you would like it in seconds for any reason, it is most easily fetched withCACurrentMediaTime()
.Using this to create an "always-increment" is pretty easy. On first launch, store the current value wherever you like. When you exit, and periodically, save the offset from that value. When you restart, check the current value; if it is less than your previous base value, replace your base value (there's been a reboot).
All of this of course can be cleared by removing your app unless you store something on the server.
Note that this cannot be used as a strong security measure. There is no way to prevent an authorized user from forging requests. So depending on what you mean by "cheat the system," it may not be a solvable problem. The best you can do is have constant diligence looking for hacks and dealing with them.