Setting a limit to a fetched property in Core Data - iphone

I have a one to many relationship between two objects, lets call them Gallery and Images.
Each Image belongs to a Gallery and each Gallery has many Images.
I would like to add a fetched property to my Gallery model which would return one and only one Image object.
Is there a way to do this with fetched properties?

For a fetched property, a predicate is your only option.
See the Predicate Programming Guide - Aggregate Operations section. You'll want to use array[FIRST].
Note, you'll likely get a different image each time, since there is no support for ordered sets in Core Data. You'd normally get around this by maintaining your Images' sort order in a "sortOrder" key and setting sort descriptors on your fetch, but I don't think it's possible to give sort descriptors on a fetched property.
Update for Lion: Support for ordered sets has been added to Core Data in 10.7 and above, making an extra "sortOrder" attribute unnecessary for apps targeting 10.7 and up.

A fetched property is represented by the NSFetchedPropertyDescription class. You can modify properties in code up until the point when the managed object model is actually used. So, in the code that loads up your managed object model, you can find your fetched property description and replace the fetch request with something that better matches what you're trying to do. You should be able to set a fetch limit on it in this way.

Related

Is it possible to fetch the data of only one attribute of an Entity in Core Data?

I have an entity in Core Data with multiple attributes. In order to increase the performance of the app, I would like to fetch only one attribute of that entity. Is that possible to do and if so, then how? Or should I just use predicates to fetch the entities that I need and from them access the values of their attributes? Thanks.
It depends on a few things; how many entities are you fetching, do you ever want anything else, what is your real performance problem?
First of all use Instruments to make sure that your problem is actually where you think it is. Core data uses faulting and batching to make it very memory and performance efficient. An entity's attribute data is not brought into memory until it is accessed.
If you really want to only fetch a single attribute from your entities then you can make a fetch request with the propertiesToFetch value set to the attributes you care about. If you do this with a managed object resultType, then AFAIK I know this will use more memory, as it will make all the result objects be a partial fault (with those properties populated) rather than full faults.
If you use the dictionary resultType, then you'll get back no managed objects at all, just an array of dictionaries with the relevant attribute populated.
You can get the single property. Here is the Apple's way

Core Data Fetch

I have an entity, and I want to fetch a certain attribute.
For example,
Let's say I have an entity called Food, with multiple attributes. I want to select all categories, which is an attribute on each food item. What's the best way to accomplish this in Core Data?
Just run your fetch request and then use valueForKey: to extract all of the attribute values. If your model contains lots of objects, you can set the fetch limit and offset (and sort descriptor) to page through the items. When doing this you should also set the fetch request to not return objects as faults.
Just remembered there is an alternative. You can set the properties to fetch and then set the result type to NSDictionaryResultType. You still need to do the iteration but this will return the minimum data possible.
EDIT: I think I misunderstood your question. It seems that you only want to fetch a property of an object, not the object itself (e.g. the attribute but not the entity)? I don't believe core data is going to work that way...it's an object graph rather than a database, as the person above mentioned. Research how Core Data "faults", automatically retrieving dependent objects as they are needed. I left the advice below in case it still applies, though I'm not sure it will.
You can add a predicate to your search in order to fetch only objects which meet certain criteria; it works like an "if" statement for fetching. Here's Apple's documentation:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html
And a tutorial:
http://www.peterfriese.de/using-nspredicate-to-filter-data/
All that said, the necessity really depends on how many objects you're fetching. If it's not causing any performance hit, there's not necessarily anything wrong with fetching a few un-needed objects. Solve problems, in other words--don't "optimize" things that were working fine. If your model contains a ton of objects, though, it could be expensive to fetch them all and you would want to use a predicate.
You can only fetch whole objects, but you can only fetch objects that have a perticlar attribute using nspredicate in your fetch request. See the code snippet in Xcode in the snippet section. Look for fetch request in the find field and drag out the snippet with the nspredicate code. You can set the predicate to only find the objects that satisfy this predicate. Hope this helps!

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.

Save MKOverlay to Core Data

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.

Keep ordered images for entity in Core Data

I have an entity called "Person" and a set of UIImages for it (One-To-Many).
When the user enters the images, he's asked to do so in a chronological order to the person's life.
When I save & restore the data from Core Data, I need to keep the images order.
How would you suggest me to do it?
10x
Add and maintain a sortOrder attribute on your image entity. Add a sort descriptor for this attribute to keep images sorted by it. Core Data doesn't support ordered collections for performance reasons.
In this case, the datetime the image was added is data that you're interested in, so it should be included in your model somewhere.