I have an object in core data which contains an NSArray filed. This is an array of categories (just strings).
ANd i need to get all objects for certain category. So if an object has an array of categories "film", "music" and i need to get all the film objects - this object is what i need.
so how to write fetch request which wiil search for the value in some array field?
You should consider creating another object in your model called Category. Create relationships between the two objects. Make both of them To-Many relationships.
In your Category object create a string attribute called name. This will be where you set it to film, music, etc. You should then be able to pull back all the objects that match the film category using a predicate such as this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY categories.name == %#", category];
Please watch from Standford Uni. CS193p Video Lectures, the Core Data is explained greatly
Related
Suppose I saved the Following Restaurant Details like id, name, address like that in core data , then how can i check wether Restaurant with particular id exist or not in core data data base.
Create an NSFetchRequest for the appropriate entity.
Assign an NSPredicate to the request with format id == %#, currentID.
Perform a fetch.
If the returned array is not empty the item exists.
I have an CoreData model with the entity Person and an attribute called name. I store 4 strings into name (Pete, Paul, Dan and Jo). Now I'd like to find out which indexPath Paul has. How can I do this?
My CoreData model:
To display Core Data entities in a table view, you should use a NSFetchedResultsController. One requirement is that the entities you fetch must be sorted, so the index path is unequivocal.
To find the index path of a Person object in your fetched results controller driven table view, use
let indexPath = self.fetchedResultsController.indexPathForObject(person)!
How does one retrieve the NSManagedObjectID when saving an object to Core-Data?
I have a series of objects to save to Core-Data and I need to have each ones objectID as I am saving on another thread.
I would then like to pass this array to the main thread and fetch the objects for the array of IDs.
You can use key value coding which is very convenient:
NSArray *objects; // the objects you are saving
NSArray *objectIDs = [objects valueForKeyPath:#"objectID"];
However, this does not make too much sense. Why don't you just pass the array of objects right away? You could also retrieve them from the store with a suitable predicate.
In my iPhone app, I try to have a TableViewController to display a list of photos those share one same tag (currentTag in code below). Photo and tag are "many to many" relationship in database. Each photo has an attribute named "tags", which type is NSSet. Each tag has an attribute named "photos", which type is NSSet, too. Tag has an attribute called "name".
I'm trying to do the following code:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Photo"];
request.predicate = [NSPredicate predicateWithFormat:#"tags contains %#",currentTag];
The problem is I can't do many things inside predicateWithFormat for the reason of quotation marks. And the key word "contains" not working here, they are for strings only. I also tried
[NSPredicate predicateWithFormat:#"%# IN tags",currentTag]
no luck either...
One more, I found someone has a similar question at here, then I try the following code, still nothing displays in the table view controller. However, if I comments the line, all photos shows up.
[NSPredicate predicateWithFormat:#"self in %#",[currentTag photos]]
Can someone give help please?
Use ANY:
[NSPredicate predicateWithFormat:#"ANY tags == %#",currentTag];
I am trying to do exactly same thing as post in NSFetchResultsController + sectionNameKeyPath + section order, i.e. basically use 2 tables, let's say Categories <-->> Events. Category table consists of category field only, while Event consists of name, dateTimestamp.
I defined relationship 'category' in Events table and try to use that relationship as sectionNameKeyPath when creating fetchedResultsController:
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"category.category" cacheName:#"Root"];
Finally, I pre-populated Category table with some categories upon loading of the app (and verified with .dump that table is populated correctly)
Yet, I simulator fails on:
return [[self.fetchedResultsController sections] count];
I did extensive search and most people either suggest using one of the fields in the table as sectionNameKeyPath (this works!) or transient property (works too!) However, I just want to use relationship as it seems very logical to me in this case where events belong to some categories and there could be categories without events. Am I wrong in my assumption that relationship can be used as sectionNameKeyPath? The original link at the top of the question suggests it works, but guy does not know why or how. Documentation is very weak on what can be used as sectionNameKeyPath, so any help will be highly appreciated.
A relationship gets you a pointer to a managed object. It seems logical, though, that the sectionNameKeyPath parameter should be a key path that leads to a string, since NSFetchedResultsSectionInfo's name property is a string. The fetched results controller will follow that key path for each fetched object and group the objects into sections based on what they return for that key path, and it'll also use those strings as the names of their respective sections. You can't use a managed object for the name -- you have to use some string property of the managed object.
So, your Category entity must have an attribute that distinguishes one category from another, right? Use that as the key path and (as you've seen) everything will work out.
BTW, I think it's useful to try to get out of the database (rows/fields) mindset and try to think in object-oriented terms like entity and attribute. A big selling point of Core Data is that it provides an abstraction layer that hides the storage mechanism. Thinking in terms of tables is like thinking about blocks and sectors when you're reading or writing a file.
Caleb, thank you for your answer. I do believe my understanding was wrong to some degree. What I had was an entity Category and entity Event. Category has a string field 'category', thus 'category.category' path (first 'category' is relationship in the Event entity)
What I did not take in account, though, is that if there are no events, fetchresultscontroller cannot fetch anything (similar to 'left join')
What I wanted is to show categories even if there are no events. Relationship 'category' will not return anything in this case as there is nothing to return/sort/categorize.
What I had to do (wrong or right - not sure yet) is to treat [managed] object created from Category entity as a separate object in case there are no events and place in the table. When there is one event per category, I can switch to the original method of [automatic] showing events sorted by categories.
This is interesting issue of starting point (empty entities with relationships) where I feel core data is more confusing than traditional relationship database. I also believe that's why all books/articles/reports carefully stay away from this topic. In other words, I could not find analog of "left join" in core data. May be I am wrong because I am relatively new to all this. Below is the description of the entities:
Category <-->> Event
Category - parent
Category.category - attribute of type String
Category.event - relationship to Event entity
Event - child
Event.name - attribute of type String
Event.category - relationship to Category entity
Each event belongs to one category. Category may have multiple events.
Categories should be shown even if there are no events for this category.
I was trying to put Events under fetchresultscontroller. May be I should switch to Category first and then calculate cell based on category.event relationship, not the other way around - did not try that yet.