Does NSKeyedArchiver overwrite the entire file every time you archive? - iphone

I need to store various types of data and update it from different parts of my application at different times. I was under the impression I could use NSKeyedArchiver to do this and just update parts of the data using the appropriate key when necessary...much like a database. It seems that NSKeyedArchiver overwrites the entire file every time you archive.
Am I correct in that NSKeyedArchiver overwrites the entire file and if so, is there a strategy you would suggest for dealing with this (other than using SQLLite or CoreData..I'll probably have to upgrade to this for the next release). I can separate out the data into different files but that seems like a lot of work.

Yes, NSKeyedArchiver replaces the data on disk with its data. To do what you want will probably take SOME sort of database solution, though not necessarily SQLite. How large is your data set? Is re-writing the whole thing that slow?

Related

Load and perform search on large amount of data

I need a suggest how to operate with large amount of data on iPhone. Let say I have xml file with ~120k text records. I need to perform search on this data. The solution i have tried is to use Core Data to store information in sorted order in caches. And then use binary search which works fast. But the problem is to build this caches. On first launch application takes about 15-25 seconds to build this caches. Maybe I need to use different approach to search the data?
Thanks in advance.
If you're using an XML file with the requirement that you can't cache, then you're not going to succeed unless you somehow carefully format your XML file to have useful data traversal properties -- but then you may as well use a binary file that's more useful unless you have some very esoteric requirements.
Really what you want is one of the typical indexing algorithms (on disk hash, B-tree, etc) from the get-go.
However...
If you have to read in and parse your XML text file, then you can skirt using a typical big and slow generic XML parser and write a fast hackish version since most of the data records you'll need to recognize are probably formatted the same way over and over. Nothing special, just find where the relevant data fields start, grab the data until it ends, move on to the next data field.
Honestly, 120k of text isn't very much-- sounds like whatever XML parser you're using is just slow. (I use this trick all the time for autogenerated XML data that just represents things like tables or simple data records -- my own parser is faster than any generic XML parser.)
This is probably the solution you actually want since you sound fairly attached to the XML file format. It won't be as error-proof as a generic XML parser if you're not careful, however it will eat that 120KB file up like nobody's business. And it's entry level CS work -- read in a file with certain specific formatting and grab the data values from it. Regexps are your friend if you have access to them.
Try storing and doing your searches in the cloud. (using a database stored on a server somewhere)
Unless you specifically need ALL of the information on the device..

How to load data into Core Data?

thanks for you help.
I'm attempting to add core data to my project and I'm stuck at where and how to add the actual data into the persistent store (I'm assuming this is the place for the raw data).
I will have 1000 < objects so I don't want to use a plist approach. From my searches, there seems to be xml and csv approaches. Is there a way I can use SQL for input?
The data will not be changed by the user and the data file will be typed in by hand, so I won't need to update these files during runtime, and at this point I am not limited in any type of file - the lightest on syntax is preferred.
Thanks again for any help.
You could load your data from an xml/csv/json file and create the DB on the first lunch of your application (if the DB is not there, then read the data and create it).
A better/faster approach might be to ship your sqllite DB within your application. You can parse the file in any format you want on the simulator, create a DB with all your entities, then take it from the ApplicationData and just add it to your app as a resource.
Although I'm sure there are lighter file types that could be used, I would include a JSON file into the app bundle from which you import the initial dataset.
Update: some folks are recommending XML. NSXMLParser is almost as fast as JSONKit (but much faster than most other parsers), but the XML syntax is heavier than JSON. So an XML bundled file that holds the initial dataset would weight more than if it was in JSON.
Considering Apple considers the format of its persistent stores implementation details, shipping a prefabricated SQLite database is not a very good idea. I.e. the names of fields and tables may change between iOS versions/phones/whatever hidden variable you can think of. You should, in general, not concern yourself with how this serialization of your data is formatted.
There's a brief article about importing data on Apple's developer site: Efficiently Importing Data
You should ship initial data in whatever format you're comfortable with (XML allows you to do incremental parsing efficiently, which reduces memory footprint) and write an import routine to run if you need to import data.
Edit: With EliBud's comment in mind, I still consider the approach a bit "iffy"... The format of the SQLite database used by Core Data is not something you'd want to generate by yourself (it's weird, simply put, and still not something you should really rely on).
So you'd want to use a mock app running on the Simulator and use Core Data to create the database (as per EliBud's answer). But you'd still have to import the data into that mock-app! And while it might make sense to do this once on a "real" computer instead of a lot of times on a mobile device (i.e. copying a file is easy, importing data is hard), you're essentially using the Simulator as an administration tool.
But hey, if it works...

Performance issue - plist vs sqlite in iOS

I need to keep track of some variables and to save them very frequently. I don't need complex search and sort, just simple read/write.
What is the difference in read/write performance between plist and sqlite ?
Besides the above two methods, should I use core data ?
Please give me some hints.
Thanks.
In SQlite you can perform all functions related SQL like create,delete..and also store large amount of data.But in Plist its you jst store .
Plist and SQLite have different use as below..
PList is a file format used to store a small amount of structural data (less than a few hundred kilobytes), typically a dictionary. PList doesn't have sorting capabilities in and of itself, although code can easily be written to sort it.
A property list is probably the easiest to maintain, but it will be loaded into memory all at once. This could eat up a lot of the device's memory
SQLite is a full-fledged database. File sizes (on an iphone) are essentially unlimited. Sorting capabilities are built in. Querying and relational table designs are possible. Performance should be as good as any sorting algorithm you might come up with.
An sqlite database, on the other hand, will load only the data you request. I'm not sure how your data is structured, but you could quite easily create key-value pairs with a single database table. (A single table with a key column and a value column) Then, if it were me, I'd write an Objective-C class to wrap the database queries so I can write easy statements like:
NSString *welcomeText = [[MyData sharedData] dataWithKey:#"WelcomeText"];
Getting the data into the database in the first place doesn't have to be difficult. You can use the command line sqlite3 utility to bulk load your data. There's a command called .import that will import your data from a text file.
From the answer provided by #Robert Harvey in this previous SO question plist or sqlite
PList is a file format used to store a
small amount of structural data (less
than a few hundred kilobytes),
typically a dictionary. PList doesn't
have sorting capabilities in and of
itself, although code can easily be
written to sort it.A property list is
probably the easiest to maintain, but
it will be loaded into memory all at
once. This could eat up a lot of the
device's memory.
SQLite is a full-fledged database.
File sizes (on an iphone) are
essentially unlimited. Sorting
capabilities are built in. Querying
and relational table designs are
possible. Performance should be as
good as any sorting algorithm you
might come up with.An sqlite database,
on the other hand, will load only the
data you request. I'm not sure how
your data is structured, but you could
quite easily create key-value pairs
with a single database table.
If you are storing "huge data" then
you will benefit from sqlite.
Especially if you are going to be
performing complex queries,
extraction, searching and sorting
etc..
If you are going to do operations like search, sort you have to use sqlite. In sqlite we can able to store large amount of data but it is not possible in plist.I dont know about the performace between this.

Saving fetched data on disk

I'm creating an iPhone app, which fetches information from a server every time it is started. However, i'm planning on using the fetched data of the last month/few months/year to calculate some averages.
I had been thinking about saving them to NSUserDefaults using dictionaries (associating a date with a value), but i just remembered there also exists something like core data. Seeing that i do not have any experience with core data, i don't know if it's better. If it wouldn't, i could save the
time i'd use learning it otherwise.
The data comes in in XML format, and i get several sets of the same response each time (for different locations on a map). The amount of sets can change, as the user can add more locations. I currently only save the raw data to the disk to load if the load fails next time it starts. However, i also want to save some specific values from that XML in a way that i can easily access it. What would be the best way to do this?
Edit: I actually also need to know how fast/efficient core data is. I'm currently passing around NSArrays with NSDictionaries for the sets of data during that session. For saving the data that last longer than the session core data is ideal, i found out that much (just need to find a nice way to associate an entity with a date), i just need some advice on the efficiency.
If you're going to be working with larger amounts of data, it's probably anyway better to give Core Data a try, it's after all not that complicated and there's a plenty of good tutorials where you can learn it. There are different settings for the storage type, you can either use a sqlite database or an xml file.
According to the guys from Apple, it should be fast and memory effective to use Core Data in contrast to self-made solutions, so it's a preferred way to go.
Core data would be easier to manipulate the data and query the data using predicates. Core Data supports dates so you can even find items in date ranges.

Store XML data in Core Data

is there any easy way of store XML data into core data?
Currently, my app just pulls the values from the XML file directly, however, this isn't efficient for XML files which holds over 100 entries, thus storing the data in Core Data would be the best option. XML file is called/downloaded/parsed ever time the app opens.
With the Core Data, the XML data would be downloaded ever 3600 seconds or so, and refresh the current data in the core data, to reduce the loading time when opening the app.
Any ideas on how I can do this?
Having reviewed the developer documentation, it doesn't look very tasty.
I take that you mean you have to down load an xml file, parse it and then save the data encoded in the file? You have several options for saving such data.
If the data is relatively simple and static e.g. a repeating list of items, then you might just want to use a NSArray, NSSet or NSDictionary (or some nested combination) and then just write the resulting collection to disk as a plist using the collection classes writeToFile: methods. Then when the data is needed you just use one of the initWithFile: methods. The disadvantage of this system is that you have to read the entire file back into memory to use it. This system doesn't scale for very large data sets.
If the data is complex e.g. a bunch of separate but highly interrelated chunks of data, and moderately large, then Core Data would be better.
Of course, you always have the option of writing the downloaded file straight to disk as a string if you want.