Определить нулевое значение в 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 в рамках быстрого закрытия

Другие вопросы по тегам