Reputation:
In a few weeks I'll be releasing my iOS app to a group of beta testers. I'm allowing them to test from a Friday evening until the following Sunday night. I want to disallow any usage after that Sunday. I don't want to use NSDate
because testers could change the date on their device and keep playing after the session ended. Any ideas?
Upvotes: 3
Views: 289
Reputation: 1021
First, check out this link for a good way to check your time against an NTP server:
https://github.com/jbenet/ios-ntp
Then, you can get the date by calling [NSDate networkDate];
Now, you should be able to do your restriction in your appDelegate. I have done something similar for restricting running an iPhone app on an iPad:
if ([[NSDate networkDate] compare:startDate] == NSOrderedAscending) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Beta Not Started" message:@"Beta starts [[STARTDATE]]." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
return NO;
} else if ([[NSDate networkDate] compare:endDate] == NSOrderedDescending) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Beta Ended" message:@"Beta ended [[ENDDATE]]." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
return NO;
}
Then, in your UIAlertViewDelegate:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
exit(0);
}
Hope this helps!
Upvotes: 0
Reputation: 13966
If you don't want to set up a server or worry about network connectivity, you can do two things that make it stronger than using a single NSDate
:
NSDate
whenever someone opens the app (and when they leave)This will give a shrinking time window that will be harder and harder to circumvent.
Upvotes: 3
Reputation: 11713
Here is the secure option. You make it know that the BETA version of your app requires internet access. So when application starts, it will send a request to the beta server asking if it's alright to play. By default, your app won't play unless it gets a valid response.
The server create a valid response, the server will send at least two pieces of information. The first piece is a flag indicating that the beta period is valid. And the second is the current date/time. The server will sign the response using it's private key.
The application when it receive the response will verify its a valid by using the server public key. The server public key should be in the application as a resource. After verifying the message is valid and authentic, it compare the date/time that was sent to the device's date/time. If the time differences is less than 10 seconds for example, the application know its a current message. Not a message that has been saved and replay using some sort of HTTP proxy.
Upvotes: 0
Reputation: 57040
If you do not wish network and server connectivity, use the keychain to store the last open date. The keychain is more secure and harder for people to change than the user defaults, which are a mere plist file in the app's library.
Upvotes: 0
Reputation: 8170
There are dozens of ways to prevent this, some more complicated that others. But the first two that come to my mind are:
Option 1: You can check the date on a server instead of the system time.
Option 2: If you want to avoid the network hassle... If the user opens the app after sunday, write a boolean in userDefaults (e.g. expired). When starting the app check both the date and the expired flag. Even if the user changes the date, the expired flag would be set.
Upvotes: 1
Reputation: 13333
The date option is probably good enough as most people won't bother changing the date on their device, it would mess up too many other apps. The only case to worry about there would be someone with a device dedicated to your game.
Another option though: add a network request to your server with some code that says if it's allowed to play or not, then you can just change the flag on your server.
Upvotes: 2