0

I have my current code as listed below:

class ViewController:UIViewController{

ovveride func viewDidLoad(){
 filterData()
}

func filterData(){
  var usersArray = [User(name:"John",userId:1),User(name:"Ed",userId:2),User(name:"Ron",userId:3)]

 let filteredData = (userArray as NSArray).filtered(using:NSPredicate(format: "userId=1"))
}
}

The above code throws throws the following Exception (NSUnknownKeyException):

The Object Type '[<ViewController.User 0x6000000afa20> valueForUndefinedKey:]':
this class is not key value coding-compliant for the key userId.

The document of Apple for filter(using:) does not specify any changes that could be causing this issue.

How can I use NSPredicate in Swift 4.0?

Also, as requested, I tried using @objc. But, still the same error.

@objc
class User:NSObject{
 var name:String!
var userId:Int!

init(name:String,userId:Int){
self.name = name
self.userId = userId
}
}

With Further Comments received for this question, on adding @objc attribute to the userId I receive the below message. property cannot be marked @objc because its type cannot be represented in Objective-C

@objc
class User:NSObject{
 @objc var name:String!
var userId:Int! //@objc here results in error 

init(name:String,userId:Int){
self.name = name
self.userId = userId
}
}

String property NSPredicate it works completely fine. - Add @objc to class - Also, add @objc to property

NNikN
  • 3,720
  • 6
  • 44
  • 86
  • 3
    Possible duplicate of https://stackoverflow.com/questions/44390378/how-can-i-deal-with-objc-inference-deprecation-with-selector-in-swift-4 – did you add `@objc` to expose the `userId` property to Objective-C? – Martin R Oct 21 '17 at 14:58
  • 1
    Unrelated but why do you declare the properties as implicit unwrapped optionals although they are clearly initialized with non-optional values? Don't do that. Remove the exclamation marks. Yes, you won't get a compiler error. `@objc` before the class does not affect the members. Either use `@objcMembers` or add `@objc` before each member you need. Nevertheless there is no reason to use `NSPredicate`. – vadian Oct 21 '17 at 15:33
  • 1
    Did you try adding `@ojbc` to the `userID` property itself? Swift 4.0 is a bit more picky about `@objc` behaviour than previous versions. – Matusalem Marques Oct 21 '17 at 15:34

1 Answers1

4

Why not just use filter? It's much more "Swift-y" and doesn't involve converting your array to an NSArray.

let filteredData = usersArray.filter { $0.userId == 1 }
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
  • I am trying to use NSPredicate vs the filter{}, the one which you have mentioned. Don't know why would it not work with NSPredicate - No compile time error? – NNikN Oct 21 '17 at 15:01
  • Is there a specific reason that you want to use `NSPredicate`? [Martin R](https://stackoverflow.com/users/1187415/martin-r) already wrote a possible solution for this in the comments. – Tamás Sengel Oct 21 '17 at 15:03