Is there a way to use predicates without @objc?

I'm learning predicates using the archived predicate guide. The code below works, but I was wondering if there's a way to use predicates without declaring every class with @objc or @objcMembers? If I don't, I get a runtime error.

import Cocoa

@objcMembers
class Department: NSObject {
    var name: String
    init(name: String) {
        self.name = name
    }
}
@objcMembers
class Employee: NSObject {
    var name: String
    var salary: Float
    var department: Department
    init(name: String, salary: Float, department: Department) {
        self.name = name
        self.salary = salary
        self.department = department
    }
}

let employees = [
    Employee(name: "John", salary: 10, department: Department(name: "IT")),
    Employee(name: "Mary", salary: 20, department: Department(name: "Physics")),
    Employee(name: "Bob", salary: 30, department: Department(name: "Math"))
]

let predicate = NSPredicate(format: "salary > %f AND department.name = %@", argumentArray: [10, "Math"])
let filtered = (employees as NSArray).filtered(using:predicate)
print(filtered)

No, there is no way to do that. NSPredicate is very obj-c class, and is incompatible with pure swift objects.

The recommended way to filter swift arrays is to use filter method which is type-safe and doesn't rely on obj-c at all.

let filtered = employees.filter { $0.salary > 10 && $0.department.name == "Math" }
2 Likes

Thank you for pointing out the recommended way. I wish Apple created more guides for the new technologies.

2 Likes