aryaxt aryaxt - 1 month ago 9
Swift Question

Casting to protocol and using value?

Basically the issue is the RawRepresentable part of the code, I need to be able to get the value of it, but because I need to cast to a protocol it doesn't allow me to use the rawValue. Any workaround for this?

public protocol Serializable {
func dictionary() -> [String: Any]
}

extension Serializable {
func dictionary() -> [String: Any] {
var result = [String: Any]()
let mirror = Mirror(reflecting: self)

for child in mirror.children {
guard let label = child.label else { continue }

switch child.value {
case let serializable as Serializable:
result[label] = serializable.dictionary()

// Compile error here
case let rawRepresentable as RawRepresentable:
result[label] = rawRepresentable.rawValue

default:
result[label] = child.value
}
}

return result
}
}

Answer

I think this comes down to issues trying to use an associatedType outside of the enum.

I fixed it like this:

public protocol Serializable {
    func dictionary() -> [String: Any]
}

extension Serializable {
    func dictionary() -> [String: Any] {
        var result = [String: Any]()
        let mirror = Mirror(reflecting: self)

        for child in mirror.children {
            guard let label = child.label else { continue }

            switch child.value {
            case let serializable as Serializable:
                result[label] = serializable.dictionary()

            case let rawRepresentable as RawRepresentable:
                let value = rawRepresentable.getValueAsAny()
                result[label] = value

            default:
                result[label] = child.value
            }
        }

        return result
    }
}

extension RawRepresentable {
    func getValueAsAny() -> Any {
        return rawValue as Any
    }
}
Comments