I have a problem with Core Data which has left me at the end of my tether. So I was wondering if any of you wonderful people could help.
Basically, I have two entities in a Core Data project. These are:
Author {authorName, dateOfBirth}
Book {bookName, pages}There is a one-to-many relationship from author to books called 'authors', and an inverse relationship called 'books'. I have exported the subclasses of these entities, and created my fetch controller. Do I now have to define the relationship programatically?
A list of authors is currently displayed in my table view. At the moment, I can only display a list of ALL the books in my Core Data project when I tap on an author. How would I go about accessing a list of books from a particular author? I am presuming I would use an NSPredicate, the logic I have for that so far is:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY authors.bookName LIKE[cd] %@", authorName];
... but I am pretty sure that is incorrect.
I have been crawling the web for hours for an answer and remain confused. So any help would be greatly appreci开发者_JS百科ated.
Many thanks :)
It's likely that you have something like the following:
@interface AuthorListController : UITableViewController {
UITableView *table;
NSArray *authors; // array of NSManagedObjects
}
@property (nonatomic, retain) IBOutlet UITableView *table;
@property (nonatomic, retain) NSArray *authors;
And in your implementation you have:
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
NSManagedObject *author = [authors objectAtIndex:indexPath.row];
// create and show your book-level view here
}
Now that you've got the selected author object, you can get the books (assuming you've set up the one-to-many relationship in the Data Modeler) directly:
NSSet *books = author.books;
But if you didn't have the author object loaded, for whatever reason, you might build a new search and use the books->authors relations in your predicate:
NSManagedObjectContext *objectContext = self.managedObjectContext;
NSEntityDescription *entity = [NSEntity entityForName:@"Books" inManagedObjectContext:objectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"author.name == %@", authorName];
[fetch setPredicate:predicate];
// ... create your error object and execute the fetch, etc
The member variable "books" exists in your Author class and points to an NSSet of NSManagedObject records, all of which will be Book objects.
Obviously you're able to get an author object, so to get a list of books by that author given the author object:
NSManagedObject *author = [self getSelectedAuthor];
NSSet *booksByAuthor = [author valueForKey:@"books"];
NSArray *booksArray = [booksByAuthor allObjects];
You can then use the NSArray to populate a UITableView.
XCode has the ability to automatically create Managed Object Classes for your Core Data entities. Open your xcdatamodel file, select one of the Entities, then File -> New. You should see Managed Object Class as an option. This will let you create Author and Book classes as subclasses of NSManagedObject. Those classes have each attribute of the entity defined as a property, which means the code above could read:
Author *author = [self getSelectedAuthor];
NSSet *booksByAuthor = author.books;
NSArray *booksArray = [booksByAuthor allObjects];
精彩评论