Get correct time since app was closed without network - flutter

I am creating an idle game (user is rewarded for offline time with ressources). For that calculation I will need the elapsed time since the app was closed.
My first idea was to save the current time when the app is closed and read the current time when the app is opened. But what if a malicious user changes the system time between those actions? The user could get as many ressources as he wants with this trick.
My solution would be to consult a time server to get its current time when closing and opening the app. But this would mean the app would need to be always online, which I am trying to avoid.
Is there any other way I could use to accomplish this?

I don't think it means that the app always needs to be online. You just take the server time when the user closes the app and you take the time when the user opens the app again. You then subtract the first from the latter and then you have the offline time. Assuming of course that you save the "last_closed" time in a database of some sort.

When you are online you read correct time from an api which shows greenwich time not from user's device; so that you always have correct time.

Related

Getting date that user can not change in iphone for offline game [duplicate]

This question already has answers here:
Is there a clock in iOS that can be used that cannot be changed by the user
(6 answers)
Closed 9 years ago.
i am on way to making game. and i am trying to solve an issue about time.
gamer get life (when all rights of playing finished) every ten minutes. (at the same time i will sell a life as an in-app like candy crush). game is offline playable. i am getting time and save it when user killing app . When he/she opens game getting current time and giving life by making date subtraction. here is an issue that;
when user kills app, adjust time to 1 hour later and opens the game again (problem goes and i am giving lifes).
is there any way to solve this problem. is there any time source (without online access)
that user can not change and i can retrieve correct time.
ps: i will code the game in iOS environment. iOS specific answers will be appreciated.
I do not believe that there is a solution.
What you want is a relative time, so you could think about firing an NSTimer after a certain interval, but even that won't work because such timers will fail or die when the app is in the background (or killed).
Ultimately unless you utilize an off-device storage method you are beholden to the user's date management. Whatever absolute time method you use (such as CFAbsoluteTimeGetCurrent) it will be dependent on the system clock that the user can modify.
I would use the "monotonic time" given from the real clock time unit. On linux this is usually done by using clock_gettime(CLOCK_MONOTONIC, &timespec);. On mac/ios I think mach_absolute_time() is the function you are looking for. See one of these posts for further reading
clock_gettime alternative in Mac OS X
Monotonic clock on OSX
CACurrentMediaTime() uses mach_absolute_time(). So it should be your best friend since it is not possible to change by the user. Except for it will be reset on reboots (at least on mac). It would be best in your case if the mach_absolute_time wasn't reset on reboots...

Alert User Every 24 Hours To Update Data On App Start Up

One of my apps uses a database that synch's online with another. The online data update pretty frequently, so I'd like to remind users to update their local data every 24 hours after they open the app, not while it's closed.
Is it easier to do this with NSUserDefaults, or is it possible to schedule a Local Notification to execute only if the application is opened?
Thanks
Use NSUserDefaults.
Notifications are specifically designed to work while the app is not running :)
When the app is started, check the time of the last update and then start an NSTimer to fire at the correct time and tell the user to update.
However, is this good ui practice?
Surely it's better for your app to update itself in the background without interrupting the user?

Ensuring correct date/time

we are creating a location-enabled app where users use this app to record certain events in the field.
The important part of the event data is when an event happened. This is no issue when user is online, but we also support situations when user is offline (by remembering & later syncing events).
There could be situations when users are offline and they change the time on the phone, so that event times are wrongly recorded.
So, what would be the best way to ensure we get a correct time, independent of user actions, given that device could be offline. Some ideas:
GPS time. Is it possible to acquire it?
Tracking system time changes made by user?
Any other idea?
Note: time does need second accuracy, approximately minute accuracy would be ok.
Note2: we are creating mobile apps for Android and iPhone, so I'm interested for generic solutions and also solutions that are specific to any of those two platforms.
I, personally, wouldn't worry so much about this scenario. The liklihood of someone intentionally changing the time on their Android (which periodically throughout the day syncs to a time server automatically) while offline seems low to me. That being said, the only way I could see compensating for this is to keep a service running in the background that keeps a running tally of the seconds passed since recording the location data offline. Once uploaded to your servers you could use the elapsed seconds to calculate a time offset from current UTC time. It's an awful lot to go through, but it would work.
GPS time is an interesting idea, but Android allows users of the SDK to send mock locations to their devices. I'm not sure you could reliably track changes to system time either, and even if you could you'd be capturing them after the fact without the current real time as context.
We use GPS times in our app for very similar reasons. Since our users are in different time zones and we want local times, we define from our server what time zone they are in at installation time (they don't move very far). Hadn't thought of the mock GPS locations, but you would need to be a fairly advanced user to do that.

Client Server with IPad

I have a bit of a design question if anyone at there cares to offer some advice (or point me in the right direction).
I am writing an IPad app that will be gathering data from a server and then will be using that data for some time (read: it would be nice to be able to store the data locally even when the app is not running). Anyone know of the best way to accomplish a feat like this.
Essentially, order of events would preferbly go something likes this:
User launches app.
IPad requests data from server.
Server supplies data.
User interacts with app etc.
User closes app.
At a later time, user launches app again.
App checks data, sees it is still up to date, reads in previous data from disk.
User interacts with data etc.
Thanks in advance.
When the application is launching for the first time you should get all the data and store in to a local database.
When the user open the application after some other time just write make a webservice call that check for the last updated time, if it matches your time then leave it,else update the database.

iphone sdk system time vs user time

I have an app that requires me to take an action after some period of time. For example, if an user hasn't been inside the app in few weeks, when the user eventually starts the app, I have to ask them to put in a special code that was given to them when they installed this app. (this is an in-house app and i am being required to do this due to security concerns)
I am using the [NSDate date] method to retrieve the date when the user logs in and save it into a database. I compare this saved date next time they open up the app and see how long its been since their last login. The problem is that [NSDate date] gives the time that is effected by the time settings that can be changed manually by the user in the native settings app. As you can probably tell, this causes lots of problems to my situation. If the user is suppose to be put the special code after 3 weeks of inactivity, he can cause the app to show this screen by modifying the time in the native settings app or worse, get away from it by setting the time to a previous date that will be within 3 weeks of his activity.
Is there a way to get the "system time" instead of the "user time"? I have looked into mach_absolute_time() but this gets reset after restart of the device. Since the time of inactivity I will be comparing against is pretty large, chances are device would have been restarted by then. I also thought of using network connection to get the time from servers outside the app, but lots of users won't have access to wifi where they use their iPads. That will be my last resort solution if i can't find anything else. Because of their location during usage, I am trying to use everything on the device itself.
Am I overlooking something simple here? this seems too simple of a problem to not have an answer. Please guide me toward the right direction. Thank you in advance.
Why not query a remote server for the time - lots of NTP servers about or just make a simple HTTP request to a php script on your own server. Of course if your app is likely never to be connected to the internet that could be a problem, but once you have a 3rd party time its quite easy to guess if the user has been playing with the clock.
If this is an inhouse app (so you aren't constrained by Apples approval process), you could mark your app as doing some background stuff (voip or receiving location updates), so that the app will always be active and you'd be able to update some sort of an "unused" counter. Voip app will even be restarted by the OS after device reboot.
But of course it'll drain the battery somewhat.
Either: make having the actual time an essential feature of your app. This way the users will have a need to keep the time of the device current and can't go back three weeks
Or: mark the code as expired and save this information before the app informs the user. This will stop most user from setting the time back. Most will try once or twice, see that the app stays disabled and will give up.
You can also save the timestamp of the last successful execution and if that is more than a reasonable time frame in the future (remember summer/winter time) then consider it a "hack attempt". Put a CRC check (or whatever obscure idea you come up with) on that timestamp and save it too and you will stop a large number of script kiddies.
You can never stop the diehard hacker who search actively for every trick you might have put into the app. Just focus on the "average" user.