I’m using a web service that returns a JSON formated data from a database on my server, this data will be displayed in some view on my iPhone app.
Since the app is free so I get thousands of rows on my DB and so of course in the JSON data I have to download.
How can I do a lazy loading for my JSON data? please any code lines will be very appreciated.
Thanks.
EDIT 1 :
in other words, I’m using an Sql request such as “select all from table”, then returns this data as JSON to my app.
How can I request a little number then add others etc .. ?
The term “lazy-loading” might not be entirely well suited to a single JSON response, and it might predispose us to one approach over another. So let me tackle what I presume is the underlying question, that you want to achieve improved user experience despite a very large server database:
If the JSON is really large, you could always contemplate a “paging” metaphor, where you download the first x records, and then make subsequent requests for the next “pages” of server data. Given that additional server records can presumably be added between requests, you’ll have to think carefully about that implementation, but it’s probably easy to do.
Another way of making the JSON more efficient, is to limit the data returned in the initial request. For example, the first request could return just identifiers or header information for all or a reasonable subset of the records, and then you could have subsequent requests for additional details (e.g. the user goes to a detail screen).
A particular permutation of the prior point would be if the JSON is currently including any large data elements (e.g. Base64-encoded binary data such as images or sound files). By getting those out of the initial response, that will address many issues. And if you could return URLs for this binary data, rather than the data itself, that would definitely lend itself for lazy loading (as well as giving you the ability to easy download the binary information rather than a Base64 encoding which is 33% larger). And if you’re dealing with images, you might want to also contemplate the idea of thumbnails v large images, handling the latter, in particular, in a lazy-loading model.
You could contemplate implementing a version of XML parsing that supports streaming. The standard
NSXMLParserimplementations try to load the entire XML feed (or as much as possible?) into memory at one time (despite method names that would suggest the contrary) before parsing proceeds. If your app usedLibXML2(such as in Apple’s AdvancedURLConnections sample), you can continue downloading and parsing the XML in the background while the initial data is presented to the user. This will simultaneously yield the benefit that most people associate with “lazy loading” (i.e. you don’t wait for everything before presenting the results to the user) and “eager loading” (i.e. it will be downloading the next records so they’re already ready for the user when they go there).For us to make more intelligent suggestions, you really need to share more information about the nature of your JSON and the data behind it, describe why you think “lazy loading” is the solution, etc. You might not want to go nuts on a particular solution until you do some analysis of the data (e.g. a JSON for thousands of rows can still be smaller than a single large image).
Update:
If you were going to adopt the first approach, you first need to change your web service so that in response to a request, it only delivers n records, starting at at a particular record number. You probably also need to return the total number of records on the server so you can give the user some visual cues as to how much there is to scroll through.
Second, you need to update your iOS app to support this model. Thus, in your UI, as you’re scrolling through the results, you probably want your user interface to respond to scrolling events by showing either (a) actual results if you’ve already fetched it; or (b) some UI that visually indicates that the record in question is being retrieved and then asynchronously request the information from the server. If you were doing this in a
UITableViewCell, it might do something like:There are a whole bunch of refinements I might suggest over the above, fairly simplistic code, but hopefully it gives you the basic idea. You (a) figure out how many total rows of data there are; (b) you retrieve the first n records; (c) as the user scrolls to a record, you show it if you’ve got it, but if not, provide visually cue that you’re going to get that data for them asynchronously; and (d) when the data comes in, update the UI, if appropriate.
Like I said, I’d probably pursue some refinements over the above code, e.g., I’d probably not embed the asynchronous retrieval in the view controller itself but rather do that in my model and have some delegate pattern to update the UI, I’d probably use operations queue rather than dispatch queue so I could cancel requests that we not needed any more, etc, but you get the basic idea.
If you’re using a
UICollectionViewController, it’s analogous to the above code. If you’re using a scroll view, the pattern is very similar, though you’d be responding to theUIScrollViewDelegatemethodscrollViewDidScrollinstead (and you’d need to write code not only like the above, but also something that would releaseUIKitelements that had scrolled off the screen, too).