Swift Core Data Predicate

I want to filter Core Data using "NSPredicate" using relationship property value (each sublist has one origin list and each list has many sublists)

The sublist entity

@NSManaged public var addedDate: Date?
@NSManaged public var id: UUID?
@NSManaged public var index: Int16
@NSManaged public var title: String?
@NSManaged public var origin_List: ListOfTasks?   // its optional and I need to filter sublist using its id property
@NSManaged public var tasks: NSSet?

The List entity

@NSManaged public var id: UUID? // filter sublist using this id
@NSManaged public var index: Int16
@NSManaged public var title: String?
@NSManaged public var comments: NSSet?
@NSManaged public var groupSublists: NSSet?
@NSManaged public var origin_Group: ListOfTasks?
@NSManaged public var sublists: NSSet?   // The sublists

So I need to be sure the origin_list is not nil and for origin_list.id I have wrappedId then find if the id equal to specific id, In swift it will be like the following code

    if sublist.origin_List != nil && sublist.origin_List!.wrappedId == someId {
        // get all the matched sublists
    }

But I don't know how pass that to "NSPredicate"


Solution 1:

Checking for nil is done using "%K != nil" so the first part of the predicate would be

NSPredicate(format: "%K != nil", #keyPath(Sublist.origin_List))

(Replace Sublist with the actual name of that entity)

The second part would use a similar dot notation as in swift

NSPredicate(format: "%K = %@", 
            argumentArray: [#keyPath(Sublist.origin_List.id), someId])

This can then be put together into a compound predicate

NSCompoundPredicate(andPredicateWithSubpredicates: [
        NSPredicate(format: "%K != nil", #keyPath(Sublist.origin_List)),
        NSPredicate(format: "%K = %@", 
                    argumentArray: [#keyPath(Sublist.origin_List.id), someId])
    ])

That being said you should first try with only the second predicate since I suspect the nil check is redundant in SQL. So hopefully the answer is simply

NSPredicate(format: "%K = %@", 
            argumentArray: [#keyPath(Sublist.origin_List.id), someId])