Using DB or XML Parsing for an iPhone App? - iphone

For a products catalogue app on iphone which approach is more efficient? Using sqllite db or directly parsing online from xml without db?

Small amounts of data can be loaded as XML directly into memory. Thus, XML would do just fine. When using a large amount of data, a database would be a better option, but it will decrease speed simply because it needs to read/write the data to storage.With iPhone apps and other mobile phone apps, the difference between memory and storage tends to be very small. Unfortunately, for an app to understand an XML file, it must load the XML in a DOM model. This will eat up additional memory of about the size of the XML. Thus XML is not suitable for large amounts of data. (Or huge records.)
If you have up to 50 products, the balance is in favor for XML. Over 50 and you're better off with sqllite.
An added bonus of XML is that you need to explicitly save back to storage to update your changes. With databases, any updates to the data tends to be done directly. Thus, with a database you have a bit more problems undoing any errors. However, with XML your changes will be lost if your application crashes. Personally, I prefer it to only update data explicitly on my command, thus I would prefer XML. (But not for large amounts of data.)

Add your products to sqllite and update only changed/newly added products to the db at every launch asynchronously.
Render your View from the data in DB.

Related

Apple "Avoid writing cache files to disk." - where should I save cache?

In Apple's Performance Tuning Guide there is a writing:
Avoid writing cache files to disk. The only exception to this rule is
when your app quits and you need to write state information that can
be used to put your app back into the same state when it is next
launched.
I'm saving a lot of cache files in Library/Cache directory, because my app deals with web services, and nobody likes the white screen. What does this statement mean? I shouldn't do this or what?
Thank you!
Well, "avoid" means "avoid if possible, because writing/reading is relatively slow". If by caching a small amount of data (I assume the definitions of the web services retrieved from somewhere?) you can improve the performance of your app's startup, by all means do it. If you are only using this data for one run of your application, and the next run will re-fetch this anyway, use an in-memory cache.
Library\Caches is basically designed to store data you fetched from somewhere which provides performance boosts when stored locally.
The text from Apple feels like more a general guideline against overusing storage if you don't need data to persist from one run of your application to another.

Is there any value in using core data for iPhone apps?

Can people give me examples of why they would use coreData in an application?
I ask this because most apps are just clients to a central server where an API of some sort gives you the information you need.
In my case I'm writing a timesheet application for a web app which has an API and I'm debating if there is any value in replicating the data structure on my server in core data(Sqlite)
e.g
Project has many timesheets
employee has many timesheets
It seems to me that I can just connect to the API on every call for lists of projects or existing timesheets for example.
I realize for some kind of offline mode you could store locally in core data but this creates way more problems because you now have a big problem with syncing that data back to the web server when you get connection again.. e.g. the project selected for a timesheet no longer exists.
Can any experienced developer shed some light on there experiences on when core data is best practice approach?
EDIT
I realise of course there is value in storing local persistance but the key value of user defaults seems to cover most applications I can think of.
You shouldn't think of CoreData simply as an SQLite database. It's not JUST an SQLite database. Sure, SQLite is an option, but there are other options as well, such as in-memory and, as of iOS5, a whole slew of custom data stores. The biggest benefit with CoreData is persistence, obviously. But even if you are using an in-memory data store, you get the benefits of a very well structured object graph, and all of the heavy lifting with regards to pulling information out of or putting information into the data store is handled by CoreData for you, without you necessarily needing to concern yourself with what is backing that data store. Sure, today you don't care too much about persistence, so you could use an in-memory data store. What happens if tomorrow, or in a month, or a year, you decide to add a feature that would really benefit from persistence? With CoreData, you simply change or add a persistent data store, and all of your methods to get information out or in remain unchanged. The overhead for that sort of addition is minimal in comparison to if you were trying to access SQLite or some other data store directly. IMHO, that's the biggest benefit: abstraction. And, in essence, abstraction is one of the most powerful things behind OOP. Granted, building the Data Model just for in-memory storage could be overkill for your app, depending on how involved the app is. But, just as a side note, you may want to consider what is faster: Requesting information from your web service every time you want to perform some action, or requesting the information once, storing it in memory, and acting on that stored value for the remainder of the session. An in-memory data store wouldn't persistent beyond that particular session.
Additionally, with CoreData you get a lot of other great features like saving, fetching, and undo-redo.
There are basically two kinds of apps. Those that provide you with local functionality (games, professional applications, navigation systems...) and those that grant access to a remote service.
Your app seems to be in the second category. If you access remote services, your users will want to access new or real-time data (you don't want to read 2 week old Facebook posts) but in some cases, local caching makes sense (e.g. reading your mails when you're on the train with unstable network).
I assume that the value of accessing cached entries when not connected to a network is pretty low for your customers (internal or external) compared to the importance of accessing real-time-data. So local storage might be not necessary at all.
If you don't have hundreds of entries in your timetable, "normal" serialization (NSCoding-protocol) might be enough. If you only access some "dashboard-data", you will be able to get along with simple request/response-caching (NSURLCache can do a lot of things...).
Core Data does make more sense if you have complex data structures which should be synchronized with a server. This adds a lot of synchronization logic to your project as well as complexity from Core Data integration (concurrency, thread-safety, in-app-conflicts...).
If you want to create a "client"-app with a server driven user experience, local storage is not necessary at all so my suggestion is: Keep it as simple as possible unless there is a real need for offline storage.
It's ideal for if you want to store data locally on the phone.
Seriously though, if you can't see a need for it for your timesheet app, then don't worry about it and don't use it.
Solving the sync problems that you would have with an "offline" mode would be detailed in your design of your app. For example - don't allow projects to be deleted. Why would you? Wouldn't you want to go back in time and look at previous data for particular projects? Instead just have a marker on the project to show it as inactive and a date/time that it was made inactive. If the data that is being synced from the device is for that project and is before the date/time that it was marked as inactive, then it's fine to sync. Otherwise display a message and the user will have to sort it.
It depends purely on your application's design whether you need to store some data locally or not, if it is a real problem or a thin GUI client around your web service. Apart from "offline" mode the other reason to cache server data on client side might be to take traffic load from your server. Just think what does it mean for your server to send every time the whole timesheet data to the client, or just the changes. Yes, it means more implementation on both side, but in some cases it has serious advantages.
EDIT: example added
You have 1000 records per user in your timesheet application and one record is cca 1 kbyte. In this case every time a user starts your application, it has to fetch ~1Mbyte data from your server. If you cache the data locally, the server can tell you that let's say two records were updated since your last update, so you'll have to download only 2 kbyte. Now you should scale up this for several tens of thousands of user and you will immediately notice the difference of the server bandwidth and CPU usage.

how can I hold initial data when introducing an iPhone app?

I am developing an iPhone app which retrieves information via NSUrlRequest and displays through UIWebView.
I want to hold initial data (such as HTML pages, images) as a cache so that users of my app can access to data without network costs at the first time.
Then, if data on my web server are updated, I would download them and update the cache.
For performance issues, I think it is better to store data on file system than on core data.
Yet, I think it's not possible to release a new app writing data on disk.
So, I am about to store initial data(or initial cache) at Core Data, and when users launch my app for the first time, I would copy the data to disk (like /Library folder).
Is it, do you think, a good approach?
Or,...hmm, can I access to Core Data using NSUrlRequest?
One more question,
I might access to file system using NSURL, which is the same as to data on the Web. (right?)
My app would compare version of the cache with version of data on my web server, and if it's old, retrieve new data.
and my app will access only to file system.
All data are actually HTML pages including script, and images. And, I want to cache them.
could you suggest a better design?
Thank you.
Is it, do you think, a good approach? Or,...hmm, can I access to Core Data using NSUrlRequest?
No.
One more question, I might access to file system using NSURL, which is the same as to data on the Web. (right?) My app would compare version of the cache with version of data on my web server, and if it's old, retrieve new data. and my app will access only to file system. All data are actually HTML pages including script, and images. And, I want to cache them.
Yes.
But you could also be more clever. And by "more clever" I mean "Matt Gallagher." Take a look at his very interesting approach in Substituting local data for remote UIWebView requests.

When and How Much Data to Load into Model Objects?

I come to iPhone programming from a web development paradigm and am having a bit of a problem understanding how to design my iPhone application.
The crux of my question is: How much data do you load into your model and when do you load it with data from the database?
In the web apps I've created, the objects on the server-side are filled by the database based off form values supplied by each request. Take the example of a simple list. You click a list value, the id for the list is sent to the server (query string), the server loads an object for just that list item, server-side code uses the object, and then destroys it before the page is returned to the user.
With iPhone apps (or I guess any app where objects persist), you could load all the list item objects into a singleton dictionary from the database before the user ever interacts with them. Then you never have to go back to the database when the user clicks on a link. You just load the object from the dictionary.
Alternatively, you could design it like a web app and just go back to the database each time and fill the object with the data requested.
Can you give me any guidance on when to use one way over the other? When do I load the data? I'm tempted to just load a bunch of data when the application starts up so that I never have to go back to the database. But this feels dirty.
For static data that isn't too large, loading it all at startup works.
In one of our products, we do this for simplicity on one of the tables (we don't expect more than a few thousand rows) and load the other table lazily (high-res images). This is a reasonable option if you don't have background threads also accessing the database.
Core Data does batched lazy loading (i.e. it will load a batch of result rows at once).
Sidenote: Writes using Core Data and an SQLite store seem exceptionally slow, to the extent that we moved processing to a background thread to avoid blocking the UI (and this is for not very much data at all) and gained some annoying concurrency issues as a result. Sigh.

iPhone long plist

I have some data i want to add in to my app...about 650 categories (includes a name + id number), each with an average of 85 items (each with a name/id number).
Will the iPhone support such a large plist? I want to first display the categories in a UITableView, when a category is selected I want to display all of the associated items. Having such a large plist, im not sure if the iPhone will lag when loading the items. At over 51,000 lines it seems like...it might.
EDIT: The raw text file is 2MB
A plist can be of arbitrary length. But a plist with 2 MB of text data is a really bad idea. Even on the desktop, Apple only recommends plists with a maximum size of a couple hundred KB:
http://developer.apple.com/mac/library/documentation/cocoa/conceptual/propertylists/AboutPropertyLists/AboutPropertyLists.html#//apple_ref/doc/uid/10000048i-CH3-54402
The reason is plists must be deserialized entirely into memory before you can access a single element from the plist. This is convenient for small plists, but extraordinarily inefficient in space and time for large plists.
You should be loading your data into a database. If you do it properly, a database will only bring in the portion of the data set you need, rather than the entire data set.
I suspect it would probably take a while to load your plist, especially if you are using an XML based plist. A binary plist may be faster. You may want to consider using CoreData or a raw sqlite database to store your data instead.
The only way to be sure is to try it and see. Nothing beats actual performance timings.
That really seems better suited to pre-loading a database with. It should be somewhat smaller for one thing...
The technique is, write code to read the plist and put it in SQLlite or CoreData. Then take the database out of the simulator directory, and add it to your app - on app launch read the database from the file you have in the project.
If you need to modify the data, preload it but first copy the database into the writable directory on first launch (or basically anytime it is not there).