0

I've experimented with several ways on seeing if I need to update my user's UITableView data source only if the server one is newer. Over the past few years I've done these scenarios: 1: Having a seperate .txt file with a character as the version # then simply comparing them through code and downloading the new .plist, then saving that .txt to the user's NSDocumentDirectory along with the .plist to compare again in the future, and 2: Actually checking the server's file modification date, which worked even better, as there was no .txt file to download along with the .plist (the less stuff to download the better)

But, now I want to try a different way to account for the fact that I ship a .plist file in the App Bundle. Since the .plist file creation date is always later then the server date for new users, they don't get the new .plist file, whereas older users of the app get the new file. Sure, on the first app launch I could grab the server's modification date and overwrite the app's since I copy it from the main bundle to the NSDocumentDirectory, but I don't think I want to go that route, as I've never liked checking launch counts.

Basically, it needs to continue to be lightweight in network request time and be reliable like it's been for me. I was thinking about creating a version # key in my .plist and simply comparing that with the local .plist, but I highly doubt this will be as lightweight, as I would have to download the whole .plist into an NSDictionary first before I can compare the key values.

I'm really sorry this post is long, and I appreciate your help!

klcjr89
  • 5,862
  • 10
  • 58
  • 91
  • Use a hash - md5 or sha1/2/256 – Kevin Aug 02 '13 at 03:39
  • @Kevin please elaborate or can you provide a SO link? – klcjr89 Aug 02 '13 at 03:39
  • Also, if it has anything to do with or use `NSData dataWithContentsOfUrl` that is a no go and bad news. – klcjr89 Aug 02 '13 at 03:51
  • Compute a hash, e.g. [sha1](http://stackoverflow.com/a/6228385/900873), of the plist on the server and client. Have the client get the server's current hash, compare it to its own, and if they differ, download the file. – Kevin Aug 02 '13 at 04:07
  • Does computing the hash require downloading the whole server's plist into memory? That's not the approach I'm after if so. – klcjr89 Aug 02 '13 at 04:34
  • No, the server computes the hash of its file and the client computes the hash of the file it has. Then you just send the hash. – Kevin Aug 02 '13 at 13:46

1 Answers1

1

Why not ship the app with out the data_source.plist file and download it on first launch, or any other time it does not exist on disk (you never know). After that, you could send a HEAD request and check the modification date (maybe even the e-tag), and download as necessary.

UPDATE:

Depending on how much control you have over the server, you could add a hash of the file to the response headers (as mentioned in the comments: MD5,SHA*) along side Last-Modified.

You could add the data_source.plist to the bundle at build time, along with last_modified.plist where you can set the hash, last modified, and any other meta data you want, as starting point.

Checking for updates could look something like:

  1. Send HEAD request for http://server.com/data_source.plist
  2. Pull Last-Modified (and hash if you can send it) from the response headers
  3. Validate against corresponding values in last_modifed.plist
  4. Download updated data_source.plist if needed
  5. If the download was successful, update last_modifed.plist with new meta data (last modified and has, be sure pull this from actual download response headers).

This way, the user has something to start with, and the app can download the resource when needed.

The advantage of a HEAD request is it is light weight since there is no message body, but returns the same response headers as a GET request. It is a common method to check if a resource has been updated. The trick with your scenario is to get a starting point onto the device at build time.

Mike D
  • 4,938
  • 6
  • 43
  • 99
  • 1
    Shipping without a .plist is bad news for users that download the app but open the app and have no internet connection, which means no .plist to download. Consider my original question still please. – klcjr89 Aug 02 '13 at 03:33
  • @troop231 Maybe I should have asked this earlier, how big is the file? A few entries or in the thousands? – Mike D Aug 02 '13 at 03:39
  • Hey Mike, approximately 90 KB, which doesn't seem bad, but when you get on to a high latent network like Verizon 3G, it's not the best experience at all. – klcjr89 Aug 02 '13 at 03:41
  • 1
    Thanks Mike, what I ended up doing was getting the ETag from the response allHeaderFields, then checking that with a local string as a key in the .plist. Extremely lightweight! – klcjr89 Aug 02 '13 at 17:33