1

There are some games where certain actions are time related. For example, every 24 hours user gets one credit if he played a game ... After we turn off our phone and come back after few hours timer is correctly set.

How is this done ? There must be some method which writes current time into a persistent storage and then reads from it?

I am just guessing it's something like this:

 NSDate * now = [NSDate date];
 NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
 [outputFormatter setDateFormat:@"HH:mm:ss"];
 NSString *newDateString = [outputFormatter stringFromDate:now];

And then comes part where newDateString is written into persistent storage.

Also, if this is a method, what happens if user change time manually on his device? Can we rely on this or there are some other methods to track real time passed between certain moments in the game?

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • 1
    Maybe the timer is linked to a clock on a server? – mti2935 Feb 11 '15 at 21:10
  • I understand. But, for example, how this is done when there is no server ? I've played games in offline mode, (also iCloud turned off) and timer still works... I don't know for sure does game relying on server time or system time on device... – Whirlwind Feb 11 '15 at 21:14
  • Write the start time into NSUserDefaults and process time elapsed when game becomes active again. To guard against the user messing with the time on their device, you would probably have to communicate with a server to get accurate time. – sangony Feb 11 '15 at 21:15
  • @sangony what do you mean by server time actually? Which server ? – Whirlwind Feb 11 '15 at 21:17
  • Either a public server offering this service or your own. – sangony Feb 11 '15 at 21:20
  • 2
    Here is one in a JSON format http://time.jsontest.com – sangony Feb 11 '15 at 21:25
  • @sangony I got confused with "server" thing, but now I got it (Ian has explained it also in his answer). I thought you were talking about some iCloud feature :) – Whirlwind Feb 11 '15 at 21:26

1 Answers1

2

You could do this by writing the next award time to NSUserDefaults and comparing previous values.

// Fetch previous "next award" time.
NSNumber *previousTime = [[NSUserDefaults standardUserDefaults] objectForKey:@"next_award_time"];
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];

// If we haven't yet scheduled a "next award" time, or if we've passed it..
if (!previousTime || [previousTime doubleValue] < now) {
  // We had a previous value, so we've passed the time.
  if (previousTime) {
    // Award user.
  }
  // Set next award time.
  NSTimeInterval nextTime = [[NSDate date] timeIntervalSince1970] + 60*60*24;
  [[NSUserDefaults standardUserDefaults] setObject:@(nextTime) forKey:@"next_award_time"];
}

As far as worrying about users changing their own device time, you'll need to make a network request to an unbiased third-party clock. This could be a server you control or a well-known time server. You might want to check out this answer for help on how to contact an NTP.

Community
  • 1
  • 1
Ian MacDonald
  • 13,472
  • 2
  • 30
  • 51
  • 1
    time.jsontest.com is probably the easiest method to have a remote time authority in an iOS app. Simple data fetch from URL and then parse JSON. So good. I didn't know about that. – Ian MacDonald Feb 11 '15 at 21:36