In Swift, you can either use class or struct to define your custom class. Most likely in the later development, you would need to have an array of such custom model
somewhere in the project, and each of the custom model
in the array are unique, in other words, you want an array/dictionary/set only includes non-duplicated custom model
objects. So the following are the complete guide of some examples showing how to do compare your own custom model
:
In Swift, you can either use class or struct to define your custom class. Here are some examples.
Struct Model
// Struct
struct NoteModel {
let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String
}
In the case above, we are assuming if two notes have different username, latitude, longitude and text, they are two different notes, so if you want to make two of above objects can be comparable, add the following code:
struct NoteModel: Equatable {
let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String
// compare whether two notes are same
static func == (lhs: NoteModel, rhs: NoteModel) -> Bool {
return lhs.createDateTime == rhs.createDateTime &&
lhs.text == rhs.text &&
lhs.userName == rhs.userName &&
lhs.latitude == rhs.latitude &&
lhs.longitude == rhs.longitude
}
}
Class Model
Sometimes we are using class for the model, see the following code for the same functionality:
class NoteModel: Equatable {
let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String
init(userName: String, latitude: Double, longitude: Double, text: String, createDateTime: String) {
self.userName = userName
self.latitude = latitude
self.longitude = longitude
self.text = text
self.createDateTime = createDateTime
}
static func == (lhs: NoteModel, rhs: NoteModel) -> Bool {
return lhs.createDateTime == rhs.createDateTime &&
lhs.text == rhs.text &&
lhs.userName == rhs.userName &&
lhs.latitude == rhs.latitude &&
lhs.longitude == rhs.longitude
}
}
Class Model inherited from NSObject
Sometimes we have the special requirements that model class must inherited from NSObject
, so you have to override the isEqual
. See the following code for the same functionality:
class NoteModel: NSObject {
let userName: String
let latitude: Double
let longitude: Double
let text: String
let createDateTime: String
init(userName: String, latitude: Double, longitude: Double, text: String, createDateTime: String) {
self.userName = userName
self.latitude = latitude
self.longitude = longitude
self.text = text
self.createDateTime = createDateTime
}
override func isEqual(_ object: Any?) -> Bool {
guard let _object = object else { return false }
guard let rhs = _object as? NoteModel else { return false }
return (self.createDateTime == rhs.createDateTime &&
self.text == rhs.text &&
self.userName == rhs.userName &&
self.latitude == rhs.latitude &&
self.longitude == rhs.longitude
)
}
}
Why do we need to override?
With overriding isEqual
or ==
, you can make use a lot of inner-built methods such as contains
, filter
etc, an example of showing contains:
let note1 = NoteModel(userName: "testing user 2", latitude: 0.0, longitude: 0.0, text: "testing notes", createDateTime: "04/12/2020 18:12:03")
let note2 = NoteModel(userName: "testing user 2", latitude: 0.0, longitude: 0.0, text: "testing notes", createDateTime: "04/12/2020 18:12:03")
let array = [note1]
XCTAssertEqual(array.contains(note2), true) // true
Conclusion
- Custom Struct/Class: need to extend Equatable and override the operand ==.
- Custom Class inherited from NSObject: need to override
isEqual.