Reputation: 61774
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
:
Upvotes: 4
Views: 4094
Reputation: 285059
As already mentioned you cannot search in a transformable attribute.
An alternative to an extra entity is to save the string array joined with an unique separator as one string and declare a computed property to convert the string to array and vice versa
@NSManaged var favourites: String
private let uniqueSeparator = "®¥ð"
var favs : [String] {
get { return favourites.components(separatedBy: uniqueSeparator) }
set { favourites = newValue.joined(separator: uniqueSeparator)}
}
Then you can simply write
favs.contains("a")
Upvotes: 0
Reputation: 539685
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")
Upvotes: 10
Reputation: 270790
According to the cheatsheet, CONTAINS
is for comparing strings. e.g. "Hello" CONTAINS "e"
.
For collections, you should use IN
:
NSPredicate(format: "%@ IN favourites", "a")
Upvotes: 4