views:

161

answers:

2

I'm building an application that needs to download web content for offline viewing on an iPad. At present I'm loading some web content from the web for test purposes and displaying this with a UIWebView. Implementing that was simple enough. Now I need to make some modifications to support offline content. Eventually that offline content would be downloaded in user selectable bundles.

As I see it I have a number of options but I may have missed some:

  1. Pack content in a ZIP (or other archive) file and unpack the content when it is downloaded to the iPad.
  2. Put the content in a SQLite database. This seems to require some 3rd party libs like FMDB.
  3. Use Core Data. From what I understand this supports a number of storage formats including SQLite.
  4. Use the filesystem and download each required file individually. OK, not really a bundle but maybe this is the best option?

Considerations/Questions:

  1. What are the storage limitations and performance limitations for each of these methods? And is there an overall storage limit per iPad app?
  2. If I'm going to have the user navigate through the downloaded content, what option is easier to code up?
  3. It would seem like spinning up a local web server would be one of the most efficient ways to handle the runtime aspects of displaying the content. Are there any open source examples of this which load from a bundle like options 1-3?
  4. The other side of this is the content creation and it seems like zipping up the content (option 1) is the simplest from this angle. The other options would appear to require creation of tools to support the content creator.
+1  A: 

If you have the control over the content, I'd recommend a mix of both the first and the third option. If the content is created by you (like levels, etc) then simply store it on the server, download a zip and store it locally. Use CoreData to store an Index about the things you've downloaded, like the path of the folder it's stored in and it's name/origin/etc, but not the raw data. Databases are not thought to hold massive amounts of raw content, rather to hold structured data. And even if they can -- I'd not do so.

For your considerations:

  1. Disk space is the only limit I know on the iPad. However, databases tend to get slower if they grow too large. If you barely scan though the data, use the file system directly -- may prove faster and cheaper.
  2. The index in CoreData could store all relevant data. You will have very easy and very quick access. Opening a content will load it from the file system, which is quick, cheap and doesn't strain the index.
  3. Why would you do so? Redirect your WebView to a file:// URL will have the same effect, won't it?
  4. Should be answered by now.

If you don't have control then use the same as above but download each file separately, as suggested in option four. after unzipping both cases are basically the same.

Please get back if you have questions.

Max Seelemann
A: 

You could create a xml file for each bundle, containing the path to each file in the bundle, place it in a folder common to each bundle. When downloading, download and parse the xml first and download each ressource one by one. This will spare you the overhead of zipping and unzipping the content. Create a folder for each bundle locally and recreate the folder structure of the bundle there. This way the content will work online and offline without changes.

With a little effort, you could even keep track of file versions by including version numbers in the xml file for each ressource, so if your content has been partially updated only the files with changed version numbers have to be downloaded again.

Toastor