Syncing up Core Data with a NSMutableArray - iphone

I know this is probably a pretty basic question, but I'm working with Core Data and a UITableView. I import all the data from Core Data to various mutable arrays. When a user rearranges the items in the table, it's easy enough to swap the items in the mutable arrays I obtained from core data earlier, but is there an easy way to sync the new mutable array with the existing core data? Any help is appreciated!

I think your question is actually how to persist the order of the data in your table view rows in Core Data.
The answer is you have to introduce a new integer / NSNumber attribute to keep track. I have done this in a simple app managing a to-do list.

Use a NSFetchedResultsController. It greatly simplifies using a table view and Core Data together. No need worrying about intermediary arrays.

Lion added support for ordered to-many relationships, which is much easier than storing the indices within the entities. If you're targeting Lion you can mark the relationship Ordered and access it using a new class NSOrderedSet, which will persist its order, like an array.

Related

iOS / Core Data - Best way to return an array from a NSSet relationship?

I'm creating an app and I'm storing the data using core data. It works fine but I was wondering what's the best way to return a sorted array from an set ?
For example, I have an entity A (Button) that contains a list of entity B (Image). As we all know core data is storing the to-many relationship using an NSSet. But I want to keep track of the initial order so I added a property "order" for that purpose.
The problem is that in my code I need the list of images sorted so in a category file (Button+Create) I created a method like this one :
- (NSArray*)imagesArray
{
return [self.images sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDeacriptorWithKey:#"order" ascending:YES]]];
}
But I don't think that's the best way to do because if a need to access this list from multiple area in my code (different classes) then I need to sort the set x times ...
Is there a way to add an array (property) in my category in order to sort once and then only retrieve the property ?
What are your thoughts about that ?
Thanks
You can add properties to categories:
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
Here is another example:
How to add properties to NSMutableArray via category extension?
But
Be aware that you will be responsible to observe changes (e.g. via KVO) to the initial coredata NSSet property.
So if changes occur you have to "recalculate" your property properly...
If your target was iOS 5.0 or higher, I would recommend to use Ordered Sets, but due to the fact that you are not, I could imagine using the way described in the links above
I think your approach with order property is correct. I'd rather create a method in my model something like -(NSArray *)sortedItems which would have an NSFetchRequest with appropriate sort descriptor. If you want you can cache the result - save this array in memory. Your NSManagedObject can also have properties that are not stored in the database, just in memory. But I really don't think this is necessary considering the speed and performance of Core Data.

Referencing nsmutablearray to Data Model

I have a design issue which I am trying to analyze in my current project and thought maybe someone could help me figure this out. I have an nsarray object which I filter through predicate, and I want to set that object as my data model through view controller. First, is this a good practice of doing so? Since, I want to have an access of that object through out my transaction. I am not dealing with any database, plist, or core data model at current, these are just custom data model class I have created.
Thanks.
It's very common for a view of some sort to be backed by an NSArray, or an NSMutableArray. (Particularly, a UITableView, which can provide a single cell for each object in your array.)
Depending on the scope of your project, you can either investigate using Core Data for binding your model to your data:
CocoaDevCentral Core Data Overview
Or, for something a bit easier but less robust, you can look into implementing the methods defined in the UITableViewDelegate and UITableViewDataSource protocols, if you want to populate the cells of your table on a per-request basis.

Searching Core Data vs. Plist

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.

Modelling entity types using Core Data

I'm working on my first app using Core Data and I need to assign a type (with an associated name attribute) to a couple of entities.
Below is my object model so far.
The room and item types will be updated from time to time over the network.
Is this the best way to implement this using Core Data? Thanks :)
Edit: To try to explain better: for example, rooms may be Bedrooms, Kitchens etc. Items can be Aircon, Security Camera etc. The only difference between the different room and item types is the name text. The list of valid name texts will be updated so I don't want to hard code it in the app. Also, the user can create multiple rooms and items of the same type, which is why they are numbered (roomNumber,itemNumber)
improved Core Data Model Image http://img42.imageshack.us/img42/8458/picture6c.png
Nick, try and avoid the temptation of thinking of Core Data as a database. Design your model from the point of view looking at using the objects in your code.
i.e. your relationship properties are collections (or singluars) of the related thing.. you should rename the relationship JobLocation.JobLocationToRoom as just JobLocation.rooms
And yes, using Core Data will be quite straight forward, but it's hard to give you a definitive answer with such a vague question.
Perhaps my question wasn't clear, but I found the answer in the Apple iPhoneCoreDataRecipes demo code
The relationship I wanted to model is similar to Recipe -> RecipeType.
In addition to the other answers, you don't need to model separate ID attributes. Core Data managed objects automatically have managed object IDs that are handled for you entirely behind-the-scenes by the framework.

Saving to Core Data with NSMutableArray

Been having a bit of a headache with this one and was wondering if someone could offer some advice!
Im implementing persistent storage with Core Data.
I have two Entities Car and Driver. A car can have many drivers.
In one view i am collecting the drivers and storing them to a NSMutableArray
This array is getting passed to another view and at some point i will be saving it against a Car
What i would like to do is save each driver from the array in a seperate row in the table of drivers (Just their name (NSString) which will be assigned to a Car.
I can create an entry in the database for Car but am struggling with saving each driver in a seperate row in the driver table assigned to that car.
Any suggestions or pointers in the right direction would be greatly appreciated!
Cheers :)
It would be difficult to encapsulate a complete solution to your answer, as your question is fairly broad without seeing your code.
Try to walk through Apple's excellent Books and Recipes sample applications, which cover the Core Data concepts you'll need to progress with your own project.
You mention that you have both Car and Driver entities, yet it sounds like you're trying to save your driver names directly as attributes of a car. Why are you just saving their NSString *name to the car?
Instead of doing that, you should simply update the relationships between your car and its drivers. If you implement your entities as custom classes (and I highly recommend it - see this ADC guide), then when you want to update who drives what car, you can simply say: [car addDriversObject:driver] or [car removeDriversObject:driver].
Like Alex said, you may want to ensure you have a firm grasp on Core Data before heading out on your own too far.
i'm not a pro in using core data, but you can try to get data from your array using NSKeyArchiver and save returned NSData object to your database. it works fine with sqllite databases.