Swift 2.0 Get Mirrored Superclass Properties

后端 未结 6 1816
盖世英雄少女心
盖世英雄少女心 2020-12-20 16:16

I need to get the properties of my class as a dictionary. For simplicity, I created a protocol which has a default implementation as follows:

protocol ListsP         


        
6条回答
  •  时光取名叫无心
    2020-12-20 17:17

    Here is my Implementation

    • supports chain of inheritance
    • supports nested objects
    • unwraps optionals if .some
    • supports enums with rawValue
    • supports arrays

    .

    public protocol Serializable {
        func serialize() -> [String: Any]
    }
    
    extension Serializable {
        public func serialize() -> [String: Any] {
            var result = [String: Any]()
            var enumeratingMirror: Mirror? = Mirror(reflecting: self)
    
            while true {
                guard let mirror = enumeratingMirror else { break }
    
                for child in mirror.children {
                    guard let label = child.label else { continue }
    
                    switch child.value {
                    case let serializable as Serializable:
                        if case .some(let value) = optional {
                            result[label] = value
                        }
    
                    case let rawRepresentable as RawRepresentable:
                        result[label] = rawRepresentable.getValueAsAny()
    
                    case let optional as Optional:
                        if case .some(let value) = optional {
                            result[label] = value
                        }
    
                    default:
                        result[label] = child.value
                    }
                }
    
                enumeratingMirror = mirror.superclassMirror
            }
    
            return result
        }
    }
    
    extension Collection where Iterator.Element: Serializable {
        public func serialize() -> [[String: Any]] {
            return map { $0.serialize() }
        }
    }
    
    extension RawRepresentable {
        public func getValueAsAny() -> Any {
            return rawValue
        }
    }
    

    Usage

    class BaseUser: Serializable { let id: Int = 1 }
    class User: BaseUser { let name: String = "Aryan" }
    
    let user = User()
    print(user.serialize())   // {"id": 1, "name": "Aryan"}
    print([user].serialize()) // [{"id": 1, "name": "Aryan"}]
    

提交回复
热议问题