mercredi 16 septembre 2015

Swift Reflection Type Checking

I'm currently experimenting with Swift reflection and subscripting. In my class, I have the following function to check whether a given key/variable exists:

func getMirror(key: String) -> MirrorType? {
    let mirror = reflect(self)
    for i in 0..<mirror.count {
        let (name,type) = mirror[i]
        if name == key { return type }
    }
    return nil 
}

Then, in the subscript declaration, I do the following:

subscript(key: String) -> AnyObject? {
   ...
   set(newValue) {
        if let mirror : MirrorType = getMirror(key) {
            var type : Any.Type = mirror.valueType
            // Check here whether newValue is castable as type
        }
   }
}

The question is now whether there's a possibility to check if newValue can be safely set for the respective variable via

self.setValue(newValue, forKey: key)

which returns an exception if the value is not settable. If a have a Swift.Int or Swift.Double variable

println(type)

or

toString(type)

gives me exactly these names of the types. But is there a way to probe casting of newValue to these types? I can't directly compare strings because

newValue.dynamicType

returns Swift.Optional or __NSCFNumber for instance if unwrapped. I've tried with NSClassFromString, but it doesn't seem to work with Swift native types. Is there a way to do this?

Thanks!

Edit:

One thing in additional: I've also tried the following

if let convertedValue: AnyObject = mirror.value as? AnyObject {
    var type = convertedValue.dynamicType
}

and then I could for instance use

newValue!.isKindOfClass(type)

However, if I have an optional in the class which is not yet instantiated, this doesn't work, as mirror.value is nil. Also, newValue might still be convertable to the required type.





Aucun commentaire:

Enregistrer un commentaire