Reputation: 35
I’ve just started using Core Data and NSFetchedResultsController and I'm kind of stuck. I've a Book entity which has a category attribute of type String. The data is loaded into a collection view and grouped by sections based on this category. All’s working fine this way, but the problem is that a Book should be able to appear in multiple categories (and collection view sections). I could change the category’s type to an Array of String, but how would I do the sorting then?
let request = Book.fetchedRequest() as NSFetchRequest<Book>
let categorySort = NSSortDescriptor(key: #keyPath(Book.category)), ascending:true)
request.sortDescriptors = [categorySort]
do {
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: #keyPath(Book.category)), cacheName: nil)
try fetchedResultsController.performFetch()
} catch let error as NSError {
print(“Could not fetch. \(error), \(error.userInfo)”)
}
Should I just give up on using NSFetchedResultsController or is it possible to make this work?
Upvotes: 3
Views: 192
Reputation: 539745
... a Book should be able to appear in multiple categories (and collection view sections).
Should I just give up on using NSFetchedResultsController or is it possible to make this work?
What you describe cannot be achieved with a fetched results controller.
NSFetchedResultsController
takes all fetched objects (which are possibly
filtered by a predicate), sorts them according to the sort descriptors, and
groups them according to the sectionNameKeyPath
argument.
There is no way that a fetched results controller provides the same object multiple times (in the same or in different sections).
Upvotes: 3
Reputation: 1586
I don't think there is any problem in keeping the category attribute as a string. Just change the way you approach the array of Books.
Make an array of categories like
var booksInCategories: [[Book]] = []
This variable will hold all the books in one category inside each array. Let's assume your array of books are called books
.
var books: [Book] = []
Then put each book in each of the categories and add it to the booksInCatogories
object. Lets assume you have all the categories as another array of strings.
var categories = ["Fiction", "Science", "Children", "Education"] // just an example
If there are n categories, then there would be n arrays of books in booksInCatogories
.
for category in categories {
var booksInCategory: [Book] = []
for book in books {
if book.category.range(of: category) != nil { // checks if category string contains particular category
booksInCategory.append(book)
}
}
if booksInCategory.count > 0 { // to exclude empty array if a category doesn't have any books under it
booksInCategories.append(booksInCategory)
}
}
You can now use booksInCategories array to display all the books which belong to each category under each section using each array in booksInCategories
.
Upvotes: 0