I am searching 350 dictionary objects. Would it be more efficient to store the data in Core Data or a plist for searching?
Basically, each object is a dictionary with 8 key-values. The 350 objects are stored online in a JSON feed. I would like to download the feed when the app first launches, and then store the data into either core data or plist. In the app, there is a table with several object as default. A user is then able to add/delete these items. When a user clicks add, I want to display to the user all of the 350 objects, as well as provide a search mechanism.
In that case, should I store the JSON feed into a Plist or using Core Data?
It depends. If you aren't running into an actual performance issue, do whichever is more readable and appropriate for your application. For example, if you are saving data for which the user can add records of some sort, core data handles common situations for that and can be used with a fetched data controller to manage a table quite smoothly. It can also easily bind to your object model so you don't have to do key lookups.
If you have a reasonable amount of static data or editable values to a static list of keys and you always need to load all of it, go ahead and load a plist for convenience. Post more information about your specific situation and I can update my answer.
UPDATE:
I think you'll probably want to use Core Data for a few reasons. First, if each of these objects have the same 8 keys, you'll want to represent each one with a bound object instead of a dictionary. Second, Core Data is meant to be searched, sorted, and filtered. Third, with NSFetchedResultsController it isn't much harder to bind it to a table (with right indexes) or scroller selector. If you name the properties of your NSManagedObject the same as your 8 keys, it'll be pretty easy to load from JSON as well using KVC.
You could use a plist, but will have to do more leg-work.
As with many things in life, it depends. I would say a plist would probably be fine as long as the data is not too large to keep in memory. Also, if the data is static, I would lean toward plist. CoreData is better if you have a lot of data or a lot of related data objects and that data changes over time.
Based on your edits. I agree that Core Data is the way to go. Whenever you are adding/updating/deleting/sorting/searching/filtering data on a frequent basis, I prefer Core Data and that is Apple's recommended method as well.
Related
I am at a real loss.. For the past two weeks I have been working on fine tuning the way data is parsed, displayed and held in my app.
I have two view controllers, the first has four tables that when selected load a uitableview full of data that is parsed from an xml file. each xml file is different but have key fields that relate to each other. I need to speed up the way I display this data in the uitableview as when I do my second search when I check my ManufactureID against every single modle avalible to all manufactures.. it take a considrible amount of time to load.
I would like to do this behind the scenes before the view is even about to load and I have heard the best way to achieve this will be to use core data.. but I am not sure how to get this to work with the way I am doing things now.
If you have any examples, suggestions or anything that might help me I could seriously use someones input right about now as I am just abit stuck. For instance how do I get the data that are in my .xml files into the coredata? how to I create the relation ship ID's? etc.
First off, is there any reason to keep the information in XML files? Everything will be a lot easier (and faster!) if you just move it all to a CoreData datastore from the start instead of parsing/preloading everything to an in-memory store at launch (or whatever).
As to how to model your relationships, you could always set your CoreData model to exactly match your XML data. So, say, one Entity per file and one Attribute per record in said file. There's no reason you have to use CoreData Relationships to model the relationships in your XML. If you have IDs in the files already, just make an Attribute called xmlId or something and fetch based on that just like you were doing a SQL query. You'd miss out on a lot of automatic ORM-ness of CoreData, but if you've been dealing with XML this whole time, I doubt you'll notice.
If you really want to set up the relationships between your CoreData-managed objects, you'll have to somehow match up objects by their IDs in the XML either by importing the IDs into CoreData and then doing the math, or by somehow taking care of this when you parse. Hard to give any specific advice here without knowing more about how your data are modeled.
There's some sample code that does half of what you want (it reads XML into a in-memory CoreData store, but doesn't model any relationships). Check out TopSongs (http://developer.apple.com/library/ios/#samplecode/TopSongs)
I have an application that tracks a user and shows where they've been using MKOverlay. How can I save this information into Core Data so that when the user wants to see where they went yesterday they can load the map/overlay from Core Data?
I have a similar project. Mine is for cycle paths. Here is how I structure my core data model:
I use an order parameter so I can work out how the points connect up. But i think you can just check the 'ordered' property of the relationship now although im not entirely sure how it works. The min / max attributes are for more efficient searches. I store the lat long values as integers to save space after a suggestion to one of my posts. You might find this useful too.
You probably want to add some attributes to the Way such as Date.
You can save any object in a core data model, but if they are not the default type like string, int, etc. you won't be able to query on them.
So you have to construct your entity with property that you will be able to query.
So I see 2 options, you save every information in an entity, but this way you will need to alloc again all objects.
Or you only save the property you will need to query and archive your object in a transformable or in a Binary Data property.
I don't know what would be best.
How do I retain the values after switching to another view and returning back to the same view?
Is there a way to retain the array even after the view disappears?
My Array shows the values in console first time, but second time when it returns from other view the array shows (null)
EDIT:
I am using this array to use it into my core-plot.
This array contains the plot points for the core-plot
Generally speaking you have a few options to maintain data persistence between views. In no particular order:
Pass the array back and forth between the views. This involves creating a property on each view and setting it. You can use properties directly but you might have an easier time using NSNotifications to pass the data around.
Store the data in Core Data, loading lazily as needed. This is the most powerful option and may be a bit much. Core Data is not the correct way to "pass data between views", but often may be what you need. As an added bonus, your data stays saved across app launches.
Store the data in your delegate. This is similar to using NSNotofications. All of your objects can access the delegate more easily than passing references to each other all over the place.
Store the array in NSUserDefaults, assuming your data is compatible. This is similar to Core Data in that it offers persistence, but is much more "lightweight" and less powerful. Note that some objects are incompatible with NSUserDefaults.
Edit:
For storing an array of points, I would serialize it into either Core Data or NSUserDefaults, depending on how the user interacts with the data and how much data there actually is. If the points change often and there are many of them, look into Core Data. Although, you can do just fine with an array in NSUserDefaults. You just end up doing more array manipulation.
I have a list of objects that can sometimes change, and I want to keep a persistent cache on the device whenever the app is closed or move to the background.
Most of the objects in the list will not change, so i was wondering what is the best way to save the list. I have two major options i think about:
Using NSKeyedArchiver / unArchiver - This is the most convenient method, because the objects i'm serializing hold other custom objects, so this way i can just write a custom encode method for each of them. The major problem is that i didn't find on Google how to serialize only the changed objects, and serializing the entire list every time seems very wasteful.
Using SQLite - this is what i'm currently using, and the worst problem here is that adding \ changing properties of the objects is very complicated, and much less elegant.
Is there any way that i can enjoy the convenience of NSKeyedArchiver but only serialize the changed objects?
Like Adam Ko I would suggest using Core Data:
This kind of problem is what it's really good at, after all!
If your cache items are independent from each other, this could be achieved by simply wrapping your cache-items by a thin layer of NSManagedObject (i.e. you could benefit from Core Data with only minor changes to your app).
This wrapper entity could store an archived version of a cache item in an attribute of type NSBinaryDataAttributeType and provide access to the unarchived object through a transient property.
See Non-Standard Persistent Attributes for an example.
I have an iPhone Core Data app with a pre-populated sqlite "baseline" database. Can I add a second smaller sqlite database with the same tables as my pre-populated "baseline" database but with additional / complementary data such that Core Data will happily union the data from both databases and, ultimately, present to me as if it was all a single data source?
Idea that I had is:
1) the "baseline" database never changes.
2) I can download the smaller "complementary" sqlite database for additional data as and when I need to (I'm assuming downloading sqlite database is allowed, please comment if otherwise).
3) Core Data is then able to union data from 1 & 2. I can then reference this unified data by calling my defined Core Data managed object model.
Hope this makes sense.
Thanks in advance.
Core Data is designed to handle multiple data files via the – addPersistentStoreWithType:configuration:URL:options:error: method. This will allow you to combine all of the data files together and then access them via a single NSManagedObjectContext.
Your only issue, and it may not even be an issue for you, is that the store files cannot directly reference each other. Therefore you will need to reference data between files "manually" via unique identifiers. However I suspect you are already aware of that limitation.
Manual Relationships
The idea is that when both objects in a "relationship" are in one model and one file, Core Data does its magic and handles all of the referential integrity for you. However when they are in different files and/or models this doesn't happen automatically anymore.
The solution to this issue is to use a fetched property that looks up some unique identifier to retrieve the entity (or entities) that you want to be on the other side of the relationship. This will give you a "weak" relationship between files.
One thing to note though when doing this. The fetched property does not get updated automatically when something changes. This means when data changes that would cause that relationship to change, your application will not be automatically made aware of it and you will need to request that property again to get the updated relationship information.
Hopefully that makes it a bit clearer.
Co-existance of fetched properties and relationships
They can definitely co-exist but realize that they are two separate properties. If you want your controller code to see them as one, then I would suggest building a subclass for that entity and then adding a convenience method in there that hits both the relationship and the fetched property and then rolls them up into one NSArray or NSSet before returning it back to your controller code.
You can attach the downloaded database with ATTACH DATABASE statement and operate with unions of tables.