NSFetchedResultsController depth of fetchedObjects - iphone

I have a strange problem here and I want to know, if its related to the lazy loading function.
I do a fetch on my categories. Imagine they have subcategories and these have subsubcategories also. the question right now is: Is the fetchedObjects-Array also collecting the data of the relationship from the subcategories. In short, is it possible to access data something like that: category.subcategory.subsubcategory.name or do i need to make a new fetch on the subcategories first to get access like with subcategory.subsubcategory.name?
I dont get the whole set of the subsubcategories while I am doing it with one fetch. i only get everytime 1 entry instead of 20 or whatever the count should be.
Does anyone have an idea how coredata is handling this? And is it the common way to make a fetchrequest on every new table? Wouldn't it be quite inefficient?
thanks for any help

Use setIncludesSubentities on the NSFetchRequest.
you can also use setPropertiesToFetch to go deep like category.subcategory.subsubcategory.name
propertiesToFetch I believe only works on attributes and to-one relationships however...

Related

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 find the most common record in core data?

I want to be able to look through all the attributes of an Entity and find the most popular one. I know it has something to do with NSPredicate, but I can't quite wrap my mind around to achieve it.
One possible solution:
Fetch all the entities and loop through it and sort the attributes into different arrays, from there count the items in the arrays to determine the most popular/common one.
Although this might work I'm just wondering if there's an easier or 'cleaner' way of doing it.
Update:
Thanks #Caleb. Let me clarify, I'm looking for a single attribute value that's most often used by instances of a given entity.
That is really a dirty descision.
I would suggest you to make a new entity, say, AttributeCounter, with two attributes - name and count, and every time you add an attribute to a person, change this entity.
But that would only be good descision if you have a few different attributes and lots of persons. If not, here is another approach, that is quite simple:
Get all the enteties with first attribute not nil,count,add to array
Sort it
Here you are

Alternative to NSFetchedResultsController?

Currently I have a UITableView with its data source being an NSFetchedResultsController. The most important thing the NSFetchedResultsController does is automatically update my table if there are any changes, via delegate methods. However, I no longer need to do a fetch to get my entity, call it "Pictures" for now. I have another entity called Folder, and folders have a relationship with Pictures, so every folder has an NSSet pictures.
So instead of fetching all pictures that belong to a certain folder, now I can just do folder.pictures, and that returns what I need, and I can assign that to an array and set that as my tableView source. However, this doesn't give me automatic table updates like an NSFetchedResultsController would.
My question is how can I have the functionality of an NSFetchedResultsController (that is, the delegate methods that automatically update my table) without executing a fetch? I don't need to fetch anymore since I have an NSSet with the desired NSManagedObjects.
What's wrong with the fetched results controller? Just keep it and use the dot notation for relationship sets as well - you get the best of both worlds.
The real advantage of the fetched results controller is actually hidden. It will fetch your objects (folders) alright - but maybe it will not fetch all the relationship attributes (pictures). This is called faulting. It means that core data will get the data in the background if it is needed. It is automatically optimized for speed and good memory usage. For example, the potentially huge array of your datasource will not have to be all in memory at once, something that is unavoidable with an array.
Thus, you really do not want to get rid of the FRC. She is your friend. Stay faithful to her. ;-)

Using NSFetchedResultsController Without UITableView

Is it wrong to use an NSFetchedResultsController purely for data management, i.e., without using it to feed a UITableView?
I have a to-many relationship in a Core Data iPhone app. Whenever data in that relationship changes, I need to perform a calculation which requires that data to be sorted. In Apple's standard Department/Employees example, this would be like determining the median salary in a given Department. Whenever an Employee is added to or removed from that Department, or an Employee's salary changes, the median calculation would need to be performed again.
Keeping data sorted and current and getting notifications when it changes sounds like a great job for NSFetchedResultsController. The only "problem" is that I'm not using a UITableView. In other words, I'm not displaying sorted Employees in a UITableView. I just want an up-to-date sorted array of Employees so I can analyze them behind the scenes. (And, of course, I don't want to write a bunch of code that duplicates much of NSFetchedResultsController.)
Is it a bad idea to use an NSFetchedResultsController purely for data management, i.e., without using it to feed a UITableView? I haven't seen this done anywhere, and thought I might be missing something.
I would not call it bad but definitely "heavy".
It would be less memory and CPU to watch for saves via the NSManagedObjectContextDidSaveNotification and do the calculation there. The notification will come with three NSArray instances in its userInfo and you can then use a simple NSPredicate against those arrays to see if any employee that you care about has changed and respond.
This is part of what the NSFetchedResultsController does under the covers. However you would be avoiding the other portions of the NSFetchedResultsController that you don't care about or need.
Heavy
NSFetchedResultsController does more processing than just watch for saved objects. It handles deltas, makes calls to its delegates, etc. I am not saying it is bad in any way shape or form. What I am saying is that if you only care about when objects have changed in your relationship, you can do it pretty easily by just watching for the notifications.
Memory
In addition, there is no reason to retain anything since you are already holding onto the "Department" entity and therefore access its relationships. Holding onto the child objects "just in case" is a waste of memory. Let Core Data manage the memory, that is part of the reason for using it.
There's nothing wrong with using NSFetchedResultsController without a view. Your use case sounds like a good reason to not re-invent the wheel.
To me, this sounds like an appropriate use of NSFetchedResultController. it might be a bit overkill, as its primary use IS to help populate and keep up to date tableViews, but if you are willing to put up with the added complexity, there is no reason to not use it as such. Correct use of notifications would be the other method and it is just as complex i would estimate.

NSManagedObject for temporary use, how to switch between NSObject and NSManagedObject

Im using a Core Data model for my iPhone app. I have been looking for a way to instantiate or use an Entity outside the ManagedObjectContext. (This should not be done, I know, Im also more looking for a way to not do that, but get the benefits anyway).
My challenge is that I have a view where the user can search for "Persons", all the search results are parsed and put into a Person managedObject then displayed in a list.
If the user clicks a Person from the list, then and only then would I like the Person entity to be persisted to the store, however this requires me to delete all the other results so they don't get persisted along with the desired one. Also to the best of my knowledge, if the user decides to quite the app, the store is persisted, potentially with all current search results mixed in with real user data!
Is there some way I could have a TempPerson NSObject I could use for the search list? Without, however, me having to manually pull the 45 attributes from the temp object and manually set them on the managedObject!
Sort of like:
NSManagedObject aPersonCorrectlyReturnedFromTheStore = (NSManagedObject *)tempPersonOfJustTypeNSObject
I have seen example code from Apple where they build a temporary store to facilitate undo/redo and other stuff on an object that is not yet persisted. This I feel would be overkill in my situation. I just need to display search results until the user selects a Person to persist.
Hope it is clear what Im trying to do, feeling like my Core Data vocabulary isn't quite large enough yet:)
Thanks for any suggestions.
You could create each temporary person object as an NSDictionary or NSMutableDictionary. You can then create a new Person managed object and use the fact that NSManagedObject instances are KVC compliant and use setValuesForKeysWithDictionary:.
New managed objects that are inserted are not actually persisted until you send the managed object context a save: message.
Keep track of them in a collection (set or array) -- you are probably already doing this since you are presenting the search results somehow. Then, delete (deleteObject:) them all except for the one(s) that the user selects.
The deleted managed objects will never be stored.