Search code examples
iosswiftcore-datanspredicate

How to create NSPredicate with array contains element


I simply have Address entity with property favourites of type [String]

Address

@objc(Address)
class Address: NSManagedObject, Observer {
    @NSManaged var favourites: [String]
}

Suppose I have some addresses:

1: favourites: ["a", "b", "c"]
2: favourites: ["b", "c"]
3: favourites: ["a", "c"]
4: favourites: ["a"]
5: favourites: ["b"]

Now I need to fetch all addresses with a inside favourites. SO the result should be: 1, 3, 4

In other words I need to check if ANY element in array is equal to specific string then object should be returned.

The following doesn't work:

NSPredicate(format: "favourites CONTAINS %@", "a")

This is how it is defined in xcdatamodel:

enter image description here


Solution

  • You cannot search in an array defined as transformable attribute with a predicate. Better define another entity

    @objc(Favourite)
    class Favourite: NSManagedObject {
        @NSManaged var name: String
    }
    

    and a one-to-many relationship from "Address" to "Favourite".

    The you can fetch all addresses which have any (i.e.: at least one) favorite equal to the string "a" with the predicate

    NSPredicate(format: "ANY favourites.name == %@", "a")
    

    or better with a compiler-checked key path literal:

    NSPredicate(format: "ANY %K == %@", #keyPath(Address.favourites.name), "a")
    

    For a case-insensitive comparison you can use

    NSPredicate(format: "ANY %K ==[c] %@", #keyPath(Address.favourites.name), "a")