Reputation: 537
I'm trying to compare 2 Realm Objects in Swift.
// Object 1 Prints:
currentObject: Optional(ObjectClass {
order = 0;
number = 010;
temp = 903;
state = 6;
})
// Object 2 Prints:
lastObject: Optional(ObjectClass {
order = 0;
number = 010;
temp = 903;
state = 6;
})
Obviously the values are equal. But the Objects are not.
print(lastObject?.number == currentObject?.number) // Prints True
print(lastObject == currentObject) // Prints False
I tried to implement equatable in the object class. But Xcode isn't liking it due to Realm.
Redundant conformance of 'ObjectClass' to protocol 'Equatable'
How can I compare the variables of lastObject to currentObject? I imagine theres a better way than checking each object's variable against each other. But I don't know what it is.
Object Class:
import UIKit
import RealmSwift
class ObjectClass: Object {
@objc dynamic var order = 0
@objc dynamic var number = ""
@objc dynamic var temp = 0
@objc dynamic var state = 1
}
Upvotes: 0
Views: 1784
Reputation: 1630
Realm objects already conform to Equatable and Hashable since they are subclasses of NSObject. The only thing you need to do is override the isEqual method:
import RealmSwift
class ObjectClass: Object {
@objc dynamic var order = 0
@objc dynamic var number = ""
@objc dynamic var temp = 0
@objc dynamic var state = 1
override func isEqual(_ object: Any?) -> Bool {
if let object = object as? ObjectClass {
return self.order == object.order && self.number == object.number
&& self.temp == object.temp && self.state == object.state
} else {
return false
}
}
}
Upvotes: 3
Reputation: 35657
tl;dr
Change your object class to include a primary key and == will work to see if they are the same object. If they are the same object then their property variables will always be the same
class ObjectClass: Object {
@objc dynamic var object_id = UUID().uuidString
@objc dynamic var order = 0
@objc dynamic var number = ""
@objc dynamic var temp = 0
@objc dynamic var state = 1
override static func primaryKey() -> String? {
return "object_id"
}
}
If you want to just compare the objects properties, then it's a straightforward property to property comparison (or implement isEqual and use == per the other answer)
Discussion
When comparing Realm objects we need to understand what we're comparing; are you looking too see if the objects properties have the same values or are you looking to see if they are the same objects?
If other words take a Realm object
class RealmObject: Object {
@objc dynamic var text = ""
}
if two objects are created
let o0 = RealmObject()
o0.text = "Hello"
let o1 = RealmObject()
o1.text = "Hello"
and we compare the objects
print( o1 == o0 )
will print false because o0 and o1 are two separate objects.
Whereas if we compare a property
print( o0.text == o1.text )
would produce true because those properties are equal.
Along those same lines, after Realm 3.8 I believe you cannot test to see if two objects are the same using Equatable without a primary key. Check this out
let o0 = ObjectClass()
o0.order = 1
try! realm.write {
realm.add(o0)
}
let o1 = realm.objects(ObjectClass.self).first!
print( o1 == o0 ) //prints false
print( o1.isSameObject(as: o0) ) //prints true
However, if we add a primary key to the ObjectClass
class ObjectClass: Object {
@objc dynamic var object_id = UUID().uuidString
@objc dynamic var order = 0
override static func primaryKey() -> String? {
return "object_id"
}
}
and run the code again, they both print true
print( o1 == o0 ) //prints true
print( o1.isSameObject(as: o0) ) //prints true
Upvotes: 1