Client Server with IPad - iphone

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.

Related

Automatically sync with central database

I have developed an application. My application takes feedback from users. When network is not available, then that data is saved in local db. But, once the network is available, it will sync automatically with the central database.
But, I have some problem here. If I save database & send my application to background, once the network is available, it has to automatically do this syncing with the central database. How to do that?
I am using Reachability class to check network availability.
At the present time there is no way to have your app "wake up" when the network becomes available. If the user quit your app without a network connection, you cannot do anything until they voluntarily open your app.
However, you can prompt them to do so using UILocalNotification. If your app is being quit and you have some data waiting to be uploaded, you can schedule a notification to fire in 4 hours (or whatever amount of time makes sense).
If the user opens the app before the notification time and you are able to upload the data, you can cancel the notification and no one will ever know it was scheduled.
If the user does not open the app, the notification will appear, and say something like, "You have data on your phone that you have not uploaded in a while. Connect to the Internet and launch MyAwesomeApp to sync your data."
You cannot do it on iPhone. Your app ceases to exist in a few seconds (once the app moves to the background).
I believe its 5 seconds for all apps, 10 mins for some apps that have requested for more background time.
PS: Unless, you mark your app as a navigation or a music app, which can stay on in the background, theoretically, forever. But I doubt if a feedback app can get approved on the appstore with such permissions.
Keep an additional column in your saved database which marks successful uploading of your data to your server. Set this when the data is written, but not yet uploaded. When it's successfully uploaded, clear the value. You can check this value when your app comes to the foreground, and have it upload any data that hasn't had this column cleared. While your app is running, you can set a timer for an appropriate interval to recheck reachability and if successful, attempt an upload. Only clear your flag when the data is successfully written, and make sure your server doesn't try to process a partial upload (think of someone trying to do this on a subway or train, moving in and out of connectivity).

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.

Best practice for sending data updates to iPhone app?

I'm currently in the middle of developing an iPhone app with a big reference database (using Core Data backed with a pre-populated sqlite database). Once the app is live and deployed to a client's iPhone, I need the facility to update/insert a small amount of data. What are best practices / methods for doing this?
There may be occassions when the frequency of updates will be daily for a month or so. Other occassions when a data update happens once every few months.
What is the recommended way of doing this? Note, I don't anticipate any data model changes for these updates -- this is purely an insert/update of data.
At the moment I'm starting to research the use of push data notifications (q:payload size restrictions?), app store updates (q:code/data model only, not data updates?) and the use of my own ad hoc data server (which the app connects to routinely to check for updates).
Can anyone please provide me any pointers on the above?
Thanks in advance
IIRC Push Notifications have a maximum payload of 256 bytes. Enough for notification purposes, but not more. Your app would still have to download the actual data from your own server after receiving the notification.
Note that the app bundle is not writable on the device. So if your app needs to update the data store, you should copy the pre-populated database file from the app bundle to the app's documents directory on first launch.
App Store updates would certainly be feasible (especially now that Apple seems to have gotten its review process down to a few days at most) but note that an App Store update will always replace the entire app bundle (code and data), so if your pre-populated reference database is big, the customer would have to download it in full every time.

Possible? Use Google Maps/GPS to tell how long someone has been in a location?

I'm thinking about building an iphone app that would use the GPS feature to track where someone is and for how long. I realize I could probably get the current location from the iphone from a website but the only way I'm familiar with is using ajax calls, etc (Sorry if this is a rather newbie concept) but I fear that would bog down my servers with constant calls to track time. Is there a better way to do this? Any resources I could consult on this idea/concept? Is it even plausible at this point?
I'm more versed in php/mysql but trying to branch out on some new ideas I've had. Any help would be greatly appreciated!
You could keep a local datastore then only send updates to the server when the app detects that the user has moved. I'm pretty sure that would work and on the server side you just work out the last time a user checked in and then compare that against the current time to see how long they have been somewhere. The only technical issue I can see with this is that this requires the user to have the iphone on and the app open the ENTIRE time they are somewhere, which would mean the iphone is now just a rather expensive GPS tracker with a built in phone!
you could store user locations on a local list on the iphone and once an hour you send the list with location/timesptamp pairs to server.
As James Raybould says, you can compute on server how long a user stayed inside a range for a given position. And also by sending data once an hour... not each time the iphone detects that user moved, then you save your server for continuously pings.

When to persist data in iPhone application?

I'm currently creating an iPhone app where in one part of my app you can view your twitter stream. I'm unsure if I need to ever save the twitter information to a sqlite database or not.
So here is the flow of this part of the app:
press button to see twitter stream
go get twitter stream
display twitter stream in table view
I'm wondering if I should ever save the twitter stream into a database. Any advice?
I would say you should save the twitter stream. You should almost always try to save some application state in an iPhone app. This way, if the user is interrupted (a phone call) they can jump back into your app without missing a beat.
There are a few different ways to persist data in an iPhone app. Instead of bothering with using a SQLite database you will almost certainly want to use Core Data, which is new in iPhone OS 3.0
If you won't ask the user to provide his/her twitter credentials and it will be an anonymous stream, you don't need to store anything.
But the minute you want to store some preferences, actual state (to show the user what he/she was seeing when a phone call came or after application restart) you will need to store persistent data.
I think it's important to cache web data. With a cache, you can present data immediately on app startup - this is important on the iPhone OS because users are constantly opening and closing apps. Having your data immediately available is a big win for the user.
You can make the caching very simple, just have a single table with the URL as one column and the HTTP response as a second. Then you don't have to change any of your code to make the caching happen.
Alternatively, you will need to define a data model and manage that through CoreData or sqlite.