I think you'll find that simply switching to filter blocks instead of string predicates might stop the crash, but will not produce the expected results.
This is because IsRecordDeleted
never gets saved to the database. It is not a type that can be represented in Objective-C, therefore it cannot be dynamic
, so Realm ignores it.
Take as an example the following class:
@objcMembers class MyObject: Object {
dynamic var id = ""
dynamic var testBool: Bool? = false
override static func primaryKey() -> String {
return "id"
}
}
And say we initialize them like this:
let obj1 = MyObject()
obj1.id = "1"
obj1.testBool = true
let obj2 = MyObject()
obj2.id = "2"
obj2.testBool = false
let realm = try? Realm()
try? realm?.write {
realm?.add(obj1, update: true)
realm?.add(obj2, update: true)
}
If we query Realm for these objects using realm.objects(MyObject.self)
, you'll get something like this
Results<MyObject> <0x7fe410c0ad90> (
[0] MyObject {
id = 1;
},
[1] MyObject {
id = 2;
}
)
And you'll see that in the database, there indeed is no property named testBool
, which was our optional Bool
.
You can easily see that the optional Bool
may cause problems if you write it out like this instead:
class MyObject: Object {
@objc dynamic var id = ""
@objc dynamic var testBool: Bool? = false // This line will not compile.
override static func primaryKey() -> String {
return "id"
}
}
I'm curious why the IsRecordDeleted
needs to be optional in the first place, since it seems to have a value from the get-go. If it doesn't, then something like this will work as expected:
@objcMembers public class MyCustomModel: Object {
dynamic var Id: String = ""
dynamic var ProductId: String? = ""
dynamic var IsRecordDeleted: Bool = false
dynamic var ProductBarcode: String? = ""
override public class func primaryKey() -> String? {
return "Id"
}
}
and you can query via string like you were trying to do in the first place.
If it has to be optional, then Realm provides a RealmOptional
for this exact case, that you can look into here.