jeudi 29 octobre 2015

KVC Swift 2.1 Reflection

I'm attempting to implement a KVC equivalent is Swift (inspired by David Owens) using reflection.

valueForKey is fairly trivial, using reflection to get all the children names and retrieve the appropriate value. setValueForKey has proved to be quite tricky however, as Swift reflection appears to be read-only (since readwrite would break reflections dogma)

protocol KVC {
    var codeables: [String: Any.Type] { get }
    mutating func setValue<T>(value: T, forKey key: String)
    func getValue<T>(key: String) -> T?
}


extension KVC {
    var codeables: [String: Any.Type] {
        var dictionary: [String: Any.Type] = [:]
        let mirror = Mirror(reflecting: self)
        for child in mirror.children {
            if let label = child.label {
                 dictionary[label] = Mirror(reflecting: child.value).subjectType
             }
         }
        return dictionary
    }

    mutating func setValue<T>(value: T, forKey key: String) {
        if let valueType = self.codeables[key] where valueType == value.dynamicType {

        }
    }

    func getValue<T>(key: String) -> T? {
        let mirror = Mirror(reflecting: self)
        for child in mirror.children {
            if let label = child.label, value = child.value as? T where label == key {
                return value
            }
        }
        return nil
    }
}

Is there anyway in Swift at all to set a dynamic keypath value without using the Objective-C runtime or enforcing that the conformer is a subclass of NSObject? It seems like the answer is no but there are some clever workarounds such as ObjectMapper, although I'm not a fan of the responsibility its on the conformer.





Aucun commentaire:

Enregistrer un commentaire