I have 3 structs:
struct Address: Codable {
var addressLine1: String
}
struct Person: Codable {
var name: String
}
struct Order: Codable {
var person: Person?
var address: Address?
}
In my ViewController class I am using Mirror to access each of the properties within Order:
let address = Address(addressLine1: "Some unknown address")
let person = Person(name: "Some unknown name")
let order = Order(person: person, address: address)
let newOrderMirror = Mirror(reflecting: order)
newOrderMirror.children.forEach {
display(child: $0.value)
}
In ViewController I have implemented 3 display functions:
func display(child: Any) {
// this should never get called
print(child)
}
func display(child: Person) {
print(child)
}
func display(child: Address) {
print(child)
}
In above case it is always invoking func display(child: Any)
, however I want it to invoke the functions with specific parameter. Is there any way to achieve this without type casting?:
Off-course this will work:
newOrderMirror.children.forEach {
if let bs = $0.value as? Person {
display(child: bs)
} else if let addr = $0.value as? Address {
display(child: addr)
}
display(child: $0.value)
}
Is there any other elegant way to achieve the desired behavior without using if-let + typecasting
?
Update 1:
Found something related over here - How to call the more specific method of overloading
Update 2:
I can achieve a more concise solution by following these steps:
- Declare Displayable protocol with func display()
- Let each Modelimplement this protocol
- Within forEach on each children I can just bind and typecast to the protocol and invoke display method on it
However this looks like an ugly solution to me as Model is now serving 2 responsibilities - i. Handle/ Store data, ii. Handle how the data is displayed. The 2nd responsibility looks to me like more reasonable for a controller or presenter class to implement rather than the model class, hence I want to avoid that path