Reflection y typeChecking para opcionales
swift2 (1)
En base a esta respuesta , recomiendo usar if case Optional<Any>.some(_)
.
Hice algo recientemente para asegurarme de tener al menos un conjunto opcional en mi estructura. Puedes pegar en los patios de recreo:
struct ErrorResponse: Codable {
let message: String?
let authorizationException: [String: String]?
let validationException: String?
let generalException: String?
var isValid: Bool {
var hasAtLeastOneNonNilErrorValue = false
Mirror(reflecting: self).children.forEach {
if case Optional<Any>.some(_) = $0.value {
hasAtLeastOneNonNilErrorValue = true
}
}
return hasAtLeastOneNonNilErrorValue
}
}
let errorTest = ErrorResponse(message: "some message", authorizationException: nil, validationException: nil, generalException: nil)
let errorTest2 = ErrorResponse(message: nil, authorizationException: nil, validationException: nil, generalException: nil)
print("is valid: /(errorTest.isValid)") //is valid: true
print("is valid: /(errorTest2.isValid)") //is valid: false
Jugando con reflejos en swift 2.0 Estoy tratando de escribir verifique un valor hijo.
El problema: cada elemento de la matriz de elementos secundarios en el elemento Mirror of Any no es opcional, pero su tipo puede ser opcional ... Lo que sucede es que, por supuesto, tengo el valor secundario incluso si el valor es nulo
Tal vez no está claro, así que puse aquí un código para explicar mejor.
Para mayor comodidad, definí un subíndice en una extensión Mirror que busca el objeto secundario con una etiqueta determinada
extension Mirror {
public subscript(key: String)->Child?{
var child = children.filter {
var valid = false
if let label = $0.label {
valid = label == key
}
return valid
}.last
if child == nil,
let superMirror = superclassMirror() {
child = superMirror[key]
}
return child
}
}
perfecto, ahora digamos que tengo esta clase
class Rule: NSObject, AProtocol {
var hello: String?
var subRule: Rule?
}
Ok, ahora el problema
let aRule = Rule()
let mirroredRule = Mirror(reflecting:aRule)
if let child = mirroredRule["subRule"] {
//child.value always exists
//i can''t do child.value is AProtocol? because child.value is not optional
//child.value is AProtocol of course returns false
//child.dynamicType is Optional(Rule)
if let unwrapped = unwrap(child.value) where unwrapped is AProtocol {
//This of course works only if child.value is not nil
//so the unwrap function returns an unwrapped value
//this is not a definitive solution
}
}
child.value no se ha inicializado, por lo que es nulo, y no puedo verificar su tipo utilizando la función unwrap. Estoy escribiendo un deserializador, así que también necesito verificar la var si es nula porque en el diccionario que se usará para la deserialización podría definirse.
private func unwrap(subject: Any) -> Any? {
var value: Any?
let mirrored = Mirror(reflecting:subject)
if mirrored.displayStyle != .Optional {
value = subject
} else if let firstChild = mirrored.children.first {
value = firstChild.value
}
return value
}
Espero que el problema esté claro. ¿Alguna sugerencia?