Using predicates in array objects in Swift returns an error

When I filter an array of custom Swift classes using Predicate, I get an error:

*** NSForwarding: warning: object 0x78ed21a0 of class 'Plantivo1_6.Seed' does not implement the SignatureForSelector method: - the problem is ahead
Unrecognized selector - [Plantivo1_6.Seed valueForKey:]

If I remember correctly, this will work in Objective-C. What is my mistake?

let names = ["Tom","Mike","Marc"] println(names) let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", "om") let array = (names as NSArray).filteredArrayUsingPredicate(searchPredicate) println(array) println() let mySeed1 = Seed() // Seed is a class with a `culture` String property let mySeed2 = Seed() let mySeed3 = Seed() mySeed1.culture = "Tom" mySeed2.culture = "Mike" mySeed3.culture = "Marc" let mySeeds = [mySeed1,mySeed2,mySeed3] println(mySeeds) let searchPredicate1 = NSPredicate(format: "SELF.culture CONTAINS[c] %@", "om") let array1 = (mySeeds as NSArray).filteredArrayUsingPredicate(searchPredicate1) println(array1) 
+6
source share
4 answers

Does your seed class inherit from NSObject?

If not, this is the message you will receive.

Decision:

 class Seed: NSObject { ... 

Edit: stklieme is correct - to use NSPredicate, your object class must implement -valueForKey , as defined by the NSKeyValueCoding protocol . You can either define your own implementation -valueForKey , or simply inherit your class from NSObject, which will take care of this for you.

This is defined in Apple docs for NSPredicate ,

You can use predicates with any object class, but the class must support key encoding for the keys that you want to use in the predicate.

+12
source

valueForKey - a method of encoding key values. Declare the Seed class as a subclass of NSObject that corresponds to KVC

+1
source

If you do not want to inherit from NSObject , you can implement the value(forKey key: String) -> Any? independently:

 extension Model { @objc func value(forKey key: String) -> Any? { switch key { case "id": return id // Other fields default: return nil } } } 

Note < @objc method prefix: it is important because it allows NSPredicate to see that the method is implemented. You still get a loss does not implement methodSignatureForSelector: without it.

Or even better, your objects conform to this protocol:

 @objc protocol UsableInPredicate { @objc func value(forKey key: String) -> Any? } 
+1
source

Just,

You need to inherit the NSObject model class and your problem will be fixed.

 class Seed: NSObject { ... } 

Reason: -valueForKey, as defined by the NSKeyValueCoding protocol. You can either define your own implementation -valueForKey, or simply inherit your class from NSObject

0
source

Source: https://habr.com/ru/post/989742/


All Articles