ios - Detectar un valor nulo en NSDictionary
swift nsnull (6)
Tengo un NSDictionary
que se rellena desde una respuesta JSON desde un servidor API. A veces los valores para una clave en este diccionario son Null
Estoy intentando tomar el valor dado y soltarlo en el texto de detalle de una celda de la tabla para su visualización.
El problema es que cuando intento forzar el valor en un NSString
, se NSString
un bloqueo, lo que creo que es porque estoy tratando de forzar a Null
formar una cadena.
¿Cuál es la forma correcta de hacer esto?
Lo que quiero hacer es algo como esto:
cell.detailTextLabel.text = sensor.objectForKey( "latestValue" ) as NSString
Aquí hay un ejemplo del Diccionario:
Printing description of sensor:
{
"created_at" = "2012-10-10T22:19:50.501-07:00";
desc = "<null>";
id = 2;
"latest_value" = "<null>";
name = "AC Vent Temp";
"sensor_type" = temp;
slug = "ac-vent-temp";
"updated_at" = "2013-11-17T15:34:27.495-07:00";
}
Si solo necesito envolver todo esto en un condicional, está bien. Simplemente no he podido averiguar qué es ese condicional. De vuelta en el mundo de Objective-C, compararía con [NSNull null]
pero eso no parece estar funcionando en Swift.
Estoy usando esa combinación. Además, esa combinación verifica si el objeto no es "null"
.
func isNotNull(object:AnyObject?) -> Bool {
guard let object = object else {
return false
}
return (isNotNSNull(object) && isNotStringNull(object))
}
func isNotNSNull(object:AnyObject) -> Bool {
return object.classForCoder != NSNull.classForCoder()
}
func isNotStringNull(object:AnyObject) -> Bool {
if let object = object as? String where object.uppercaseString == "NULL" {
return false
}
return true
}
No es tan bonito como extensión pero funciona como encanto :)
NSNull es una clase como cualquier otra. Por lo tanto, puede usar is
o as
prueba de una referencia de AnyObject contra él.
Por lo tanto, aquí en una de mis aplicaciones tengo una NSArray donde cada entrada es una Tarjeta o NSNull (porque no puedes poner nula en una NSArray). Traigo el NSArray como un Array y lo recorro, activando qué tipo de objeto obtengo:
for card:AnyObject in arr {
switch card { // how to test for different possible types
case let card as NSNull:
// do one thing
case let card as Card:
// do a different thing
default:
fatalError("unexpected object in card array") // should never happen!
}
}
Eso no es idéntico a su escenario, pero es de una aplicación en funcionamiento convertida a Swift, e ilustra la técnica general completa.
Puedes usar el as?
operador, que devuelve un valor opcional ( nil
si falla el downcast)
if let latestValue = sensor["latestValue"] as? String {
cell.detailTextLabel.text = latestValue
}
He probado este ejemplo en una aplicación rápida
let x: AnyObject = NSNull()
if let y = x as? String {
println("I should never be printed: /(y)")
} else {
println("Yay")
}
y se imprime correctamente "Yay"
, mientras que
let x: AnyObject = "hello!"
if let y = x as? String {
println(y)
} else {
println("I should never be printed")
}
impresiones "hello!"
como se esperaba.
También puedes usar is
para verificar la presencia de un nulo:
if sensor["latestValue"] is NSNull {
// do something with null JSON value here
}
Tuve un problema muy similar y lo resolví con la conversión al tipo correcto del valor original de NSDictionary. Si su servicio devuelve un objeto JSON de tipo mixto como este
{"id":2, "name":"AC Vent Temp", ...}
Tendrás que buscar sus valores así.
var id:int = sensor.valueForKey("id") as Int;
var name:String? = sensor.valueForKey("name") as String;
Esto resolvió mi problema Ver BAD_INSTRUCTION dentro de cierre rápido