kakubei kakubei - 7 months ago 105
Swift Question

iOS 8 Swift NSFetchResult predicate with Core Data relationship can't access internal ID

Very new to Core Data but I've read that I can fetch data that uses Entity relationships. Now, coming from Mysql maybe I'm making too many assumptions, but I have 2 Entities set up with a Relationship between them and I can't fetch the proper data.

Here are my 2 models:

@objc(Categories)
class Categories: NSManagedObject {
@NSManaged var category: String
@NSManaged var exp: String
@NSManaged var order: NSNumber
}

@objc(Techniques)
class Techniques: NSManagedObject {
@NSManaged var korean: String
@NSManaged var order: NSNumber
@NSManaged var spanish: String
@NSManaged var categories: Categories
}


After I created a Relationship from Techniques to Categories, Core Data added this field to the Sqlite DB:

ZCATEGORIES - INTEGER


Let's say I want to fetch all Techniques that belong to the category #3 (with internal ZID: 3)

If I do this:

request.predicate = NSPredicate(format: "categories == %@", 3)


It works. But if I do:

request.predicate = NSPredicate(format: "categories == %@", category.category)


It doesn't work. I understand that it doesn't work because
category.category
is a String, not an Integer.

My question is:

Do I have to create my own relationhip IDs field in the Category Entity and set that, then reference the Technique like:

request.predicate = NSPredicate(format: "categories == %@", category.categoryID)


?

Isn't there a way to access the Category's internal ID to get this relationship to work?

Or better yet, it would seem to me that there should be an internal mechanish to retrieve these relationships without writing a SQL-like query but just using the Object, something like:
Techniques.categores
.

Thanks. I haven't found a good answer anywhere.

Answer

You are missing an attribute name, so the predicate knows which attribute of the category class to compare. This way you won't need to use the internal unique ID. Although it can be derived (and would work) it's not the way to go with Core Data, who is trying to abstract that information for you.

let categoryPredicate = NSPredicate(format: "categories.category == %@", category.category)

As mentioned setting up an inverse relationship is recommended. It allows Core Data to maintain the consistency of the object graph, and can be used to go from a category to it's techniques.