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).
Related
I'm making an app where the user can take a picture and add a title and description. But now I need to store the picture and the titles. I’ve tried making an object that contains title, description and image properties.
When it’s done I save an array of custom objects with the information on it with UserDefaults. My idea is showing in another view a table view with all the content and pictures the user has taken on the cells. I tried getting back the information with user defaults. It was working well until the user saves too many pictures. When the viewController with the tableview loads, then my app gets slower, and eventually it crashes.
I suppose the problem is when I load all the array with all custom objects, all the pictures are loaded into memory although they aren’t used and displayed for users. So I think it isn’t the best way to make what I want to make.
Is there any way better to make what I’m making or store data more efficiently and use it in tableview without using all the memory of the device?
I’m making the app from 0 again.
Can you show me how to store data and images efficiently?
There are several options for permanently storing user data on the device such that it will survive app and phone restarts. NSUserDefaults typically is for small amounts of data, such as user preferences.
When it comes time to store a lot of data, in particular big binary objects like photos, you need to decide which design you want to use. One option:
store all the photos in one directory in your apps documents and then use some simple lookup store (perhaps Core Data, or SQLite, or even a flat file) to index the photos and their metadata. Or if you don't care about indexing you can read the list of file names from the directory and sort them by time.
The other problem you are maybe having is that you are trying to load all of the photos at once for the user. As you have discovered, once you have more than a handful of photos this system falls apart. You need some mechanism to load only a few photos at a time, preferably only the ones the user needs to be displayed at that moment.
So, for example, if you are displaying the photos in a tableview, you want to only load the 10-15 photos that are visible in the table at any given time.
When storing this kind of data, you have 2 options (In fact you have more than 3 options, but saving image to the disk is IMHO complicated for this.) -
UserDefaults
Database like CoreData/Realm/FireBase...
The first one is recommended when there is not much data to save... For operating with more data, I would use database - CoreData...
For you operation you can use CoreData and NSFetchedResultsController (which is designed especially for fetching objects from the database)...
you can read the FetchedResultsController doc here... and core data basics here
Wish you best luck!
I am working an app which stores some large amount of data (hundreds of mbs) in application's own library.
can anyone tell me if there is any size limit for an app to store data?
I also want to know the good method to store my data.Currently i am using pList to store name of my data files and the actual files are stored under "Document/"..
Should i use Blob or any other suggestion ..?
Not so sure but you can have a look on it - Memory Management.
For saving large amounts of data you should probably look at Core Data or SQLite (a good source is Mobile Tuts, plist wouldn't be a good choice. And so far I don't really know if there is a limit but if the total amount of data saved in your app is over 500MB it would be very unresponsive, so maybe you should save it to a server or something.
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.
I'm currently working on an application that users a number of different views to obtain user information and I have just hit a snag.
My current method saves each user detail against a key value in a plist file, the problem is that when the user switches to another view and saves their data again, the old keys and data are overwritten.
So my question is what is more efficient, to a) have a different plist for each different view or b) read all the existing data from the file first then save the data back to the file along with the new details.
Bearing in mind eventually I will want to export all of this information as XML, though it shouldn't be too difficult to read form multiple files.
thanks in advance!
It would probably be more efficient to use multiple files. The most scarce resource on the iPhone is memory, and loading a huge plist could potentially use up a lot. Using multiple files means you don't have to load all of the plists into memory at once. If you have a lot of data, I'd also suggest taking a look at Core Data eventually.
I have created an app which displays information in a organized manner about cultural places.
The information is subject to changes, so I want it to be downloaded from the web. But not everytime. Only once in a while, because information doesn't change often.
What I want to do is, the first time the user opens the application, it downloads all data from the web. For the moment, I parse it from an xml (which is about 100Ko), and I get a NSMutableArray of "CulturalPlace" objects. but it is very slow. And what I would like to do is, to store this data locally (in case the user has an iPod touch an is not on a wifi, or if he is on EDGE and does not want to redownload all). So the user updates data only by clicking an "update button" on the top right of the screen. Otherwise it reads it from disk.
I really don't know what could be the best solution. I thought about Core Data, but I have several Tableview imbricated (Rootviewcontroller > ListofPlacesViewController > PlaceViewController) and I really cannot find good tutorial for a simple use like mine. (the iTunes "TopSongs" sample code seems too complex).
I thought also about not parsing the xml, but instead try an NSURLConnection and get a plist file. But I never managed to read anything from the local file.
So my main question is, should I keep the xml parsing method, or should I use another format to tranfert the data from the web? And what is the best way to store and read data like an NSMutableArray of custom Objects ?
Thanks in advance for your help, sorry for my approximate english.
You could use HTML5' localStorage. It's supported by Chrome and FF on the PC and Safari on Mac OS and iPhone (to the best of my knowledge). It acts like a local database. Bear in mind that if the user selects to clear all cookies (or "private settings"), your storage goes away.
You could opt to store the XML locally, and store in NSUserDefaults the date when last updated - then on app launch you can check to see if you have a new file.
ASIHTTPRequest makes it pretty easy to say "Save the contents of this URL to a file". So you'd always save the XML to a file, and always read from that file or fetch XML if it was not yet there.
In my experience XML is indeed much slower to parse than plist, even though they're technically the same thing. Fortunately, plist's are pretty easy to deal with and the API's take care of all of the archiving and de-archiving.
Once you have your data in memory, it probably wouldn't be too hard to convert it to the much faster plist representation, check out this doc for more info: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Archiving/Archiving.html
If your app is divided into different pages, you might also consider splitting the file into separate files, and only parsing / de-archiving the information you need when you need it (if you did this on a separate thread and displayed a UIProgressView on the main thread, the delay would probably be barely an issue to the user).