NSPredicate for Nested Relationships (many to many) iOS - ios

I've been struggling for several hours and thought I'd reach out to SO. In my app's data model, I have an entity, SubCategory, which has many CreatedTask, and each CreatedTask can have many User:
Say I have an User entity variable, called userObject.
I want to fetch all SubCategories, where tasks.assignees has userObject. How do I do this?
Here is what I've tried so far:
let userFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SubCategory")
let predicate = NSPredicate(format: "%# IN tasks.assignees", userObject)
fetchedResultsController.fetchRequest.predicate = predicate
However I am generating a nasty error:
unimplemented SQL generation for predicate.
Any help would be greatly appreciated.
Full Error Output:

Thanks to yan's help I was able to figure it out, just had to place the user object into an array.
let users: [User] = [userObject]
let predicate = NSPredicate(format: "SUBQUERY(tasks, $m, ANY $m.assignees IN %#).#count > 0", users)

Related

NSPredicate: search for an array of values in relation, NOT

I'm a bit lost, and I hope you can help me.
I have two arrays
let stars = ["Paul", "Ringo"]
let visitors = ["bob", "mary"]
Then I have Core Data entities Rockstar and Person. And a one-to-many relation fans between the two.
Now I want to find a couple of specific Rockstars, and make sure that they don't have visitors as fans.
I try to do that with a compound predicate, roughly like this:
let starsPredicate = NSPredicate(format: "id IN %#", stars)
let fansPredicate = NSPredicate(format: "NOT (fans.personid CONTAINS %#)", visitors)
and finally
let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [starsPredicate, fansPredicate])
I'm afraid this results in two questions:
What is the correct syntax for the fansPredicate? It works fine with one value, but it crashes on an array
Is this possible with a compound predicate at all? I think if the Person entity is empty, I get zero records from the compoundPredicate.
This can be achieved with a “SUBQUERY”:
let fansPredicate = NSPredicate(format: "SUBQUERY(fans, $f, $f.personid IN %#).#count = 0",
visitors)
The predicate is true for all Rockstar objects which have no related Person object whose personId is in the given list.

coredata fetch with predicate for object relation using swift

I'm trying to perform a fetch for an entity in coreData. This entity has a one to one relation with another entity. I want to only get the items in the first entity that have a relation to a particular item in the second entity. I'm trying this predicate which I know is incorrect:
let fetchRequest: NSFetchRequest<ItemA> = NSFetchRequest(entityName: "ItemA")
fetchRequest.predicate = NSPredicate(format: "itemA.itemB.itemBId == %d", Int(itemB.itemBId))
Currently you are using itemA.itemB.itemBId , here you are using a new entity of itemA , where as you dont need to give its name, since this predicate will be applied on itemA entity, so either you can use only itemB.itemBId inside predicate or you can use SELF.itemB.itemBId (I am not sure about SELF or self, obviously you can look it up).
So I think you can get the items of type itemA whose relation itemB has an id of itemBId like this:
let fetchRequest: NSFetchRequest<ItemA> = NSFetchRequest(entityName: "ItemA")
fetchRequest.predicate = NSPredicate(format: "itemB.itemBId == %d", Int(itemB.itemBId))

CloudKit - NSPredicate for finding all records that contains multiple CKReferences in a reference list

I'm working on Joke app that uses CloudKit
Each joke has a reference list to some categories/tags.
I'm trying to query all jokes that has some specific tags. For instance I want to find all jokes that is in the categories of Animal and Doctor.
Right now I have tried with the following code
let tagRecords = tags.map { CKReference(record: $0.record, action: .None) }
let predicate = NSPredicate(format: "tags CONTAINS %#", tagRecords)
let query = CKQuery(recordType: "Jokes", predicate: predicate)
Basically what the above does is first of all creating an array of references and then make a predicate to find the tags the contains those references
Unfortunately this doesn't work
I get the following error
server message = "Internal server error""
So the question is: How do you find all records that contains all references in a reference list?
Assuming that tags is a relationship or an array of strings, you could try with the following predicate:
let predicate = NSPredicate(format: "ANY tags IN %#", tagRecords)
Hope this helps.

Realm query to exclude results from relations

I have
class Person: Object {
let friends = List<Person>()
let family = List<Person>()
}
I have person instance, which includes links to some other persons in person.friends list.
And I want to query all other Person objects, not including person.friends and person.
I can make two for in loops to check if the query doesn't contain persons from the list, but it seems like not the best way to do that.
P.S. In CoreData I did it with predicate:
let predicate = NSPredicate(format: "SELF != %# AND NOT SELF IN %#",person, person.friends),
But Realm gives me an error:
Predicate expressions must compare a keypath and another keypath or a
constant value
.
Unfortunately, this predicate is currently unsupported in Realm -- you can follow https://github.com/realm/realm-cocoa/issues/1328 for updates.

Predicate for filtering by specific managed object - Swift

I have one to many relationship in my core data model ('Client'<-->>Assessment') and in my assessment tableview I am currently filtering assessments by client name.
func assessmentFetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Assessment")
let sortDescriptor = NSSortDescriptor(key: "nsDateOfAssessment", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format: "client.name == %#", self.client.name)
return fetchRequest
}
I would like to know how, or if its possible, to filter by the specific managed object instead of an attribute of the managed object ('name' in this case). I've tried changing my predicate to this:
fetchRequest.predicate = NSPredicate(format: "client.objectID == %#", self.client.objectID)
but I just get a crash with an uncaught exception.
I'm wanting to change this because it seems bad practice to filter by name since two clients may have the same name and therefore the same filter results.
So I am going to guess that for you sort descriptor the key name of 'nsDateOfAssessment' is not the actual name of the core data attribute. The key should be the actual name of attribute. Also, I wouldn't say that filtering by first name is bad practice. Perhaps add an additional param to your predicate that can help pinpoint the correct items. Of course, if you are storing a unique identifier for each entity, it would be a cleaner way to go about it.

Resources