Определить нулевое значение в NSDictionary
У меня есть NSDictionary
это заполняется из ответа JSON от сервера API. Иногда значения для ключа в этом словаре Null
Я пытаюсь взять данное значение и вставить его в подробный текст ячейки таблицы для отображения.
Проблема в том, что когда я пытаюсь привести значение в NSString
Я получаю сбой, который я думаю, потому что я пытаюсь заставить Null
в строку.
Какой правильный способ сделать это?
Что я хочу сделать, это что-то вроде этого:
cell.detailTextLabel.text = sensor.objectForKey( "latestValue" ) as NSString
Вот пример словаря:
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";
}
Если мне просто нужно обернуть все это в условное выражение, это нормально. Я просто не смог понять, что это за условие. Назад в мир Objective-C я бы сравнил [NSNull null]
но это не похоже на работу в Swift.
6 ответов
Вы можете использовать as?
оператор, который возвращает необязательное значение (nil
если удручает неудача)
if let latestValue = sensor["latestValue"] as? String {
cell.detailTextLabel.text = latestValue
}
Я проверил этот пример в быстром приложении
let x: AnyObject = NSNull()
if let y = x as? String {
println("I should never be printed: \(y)")
} else {
println("Yay")
}
и это правильно печатает "Yay"
, в то время как
let x: AnyObject = "hello!"
if let y = x as? String {
println(y)
} else {
println("I should never be printed")
}
печать "hello!"
как и ожидалось.
Вы также можете использовать is
проверить наличие нулевого значения:
if sensor["latestValue"] is NSNull {
// do something with null JSON value here
}
Я использую эту комбинацию. Кроме того, эта комбинация проверяет, не является ли объект "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
}
Это не так красиво, как расширение, но работает как шарм:)
NSNull это класс, как и любой другой. Таким образом, вы можете использовать is
или же as
проверить ссылку AnyObject против него.
Таким образом, здесь, в одном из моих приложений, у меня есть NSArray, где каждая запись является либо Card, либо NSNull (потому что вы не можете положить nil в NSArray). Я выбираю NSArray в качестве массива и перебираю его, переключая вид объекта, который я получаю:
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!
}
}
Это не идентично вашему сценарию, но оно из рабочего приложения, преобразованного в Swift, и иллюстрирует полную общую технику.
Мое решение на данный момент:
func isNull(someObject: AnyObject?) -> Bool {
guard let someObject = someObject else {
return true
}
return (someObject is NSNull)
}
тесты выглядят хорошо до сих пор...
У меня была очень похожая проблема, и я решил ее путем приведения к правильному типу исходного значения NSDictionary. Если ваш сервис возвращает объект JSON смешанного типа, как этот
{"id":2, "name":"AC Vent Temp", ...}
вам придется получить такие значения.
var id:int = sensor.valueForKey("id") as Int;
var name:String? = sensor.valueForKey("name") as String;
Это действительно решило мою проблему. Смотрите BAD_INSTRUCTION в рамках быстрого закрытия