web-dev-qa-db-ja.com

NSDictionaryでNull値を検出する

APIサーバーからのJSON応答から生成されたNSDictionaryがあります。この辞書のキーの値はNullである場合があります

指定された値を取得し、表示するためにテーブルセルの詳細テキストにドロップしようとしています。

問題は、値をNSStringに強制しようとするとクラッシュすることです。これは、私thinkNullを文字列に変換しようとしています。

これを行う正しい方法は何ですか?

私がやりたいことは次のようなものです:

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では機能していないようです。

39
Jeff

オプションの値を返すas?演算子を使用できます(ダウンキャストが失敗した場合はnil

if let latestValue = sensor["latestValue"] as? String {
    cell.detailTextLabel.text = latestValue
}

Swiftアプリケーションでこの例をテストしました

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!"を出力します。

86

isを使用して、nullの存在を確認することもできます。

if sensor["latestValue"] is NSNull {
    // do something with null JSON value here
}
33
iraxef

私はそれらの組み合わせを使用しています。さらに、その組み合わせは、オブジェクトが"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
}

拡張機能ほどきれいではありませんが、魅力として機能します:)

11
Błażej

NSNullは、他のクラスと同様のクラスです。したがって、isまたはasを使用して、AnyObject参照をテストできます。

したがって、ここで私のアプリの1つでは、すべてのエントリがCardまたはNSNullであるNSArrayを使用しています(NSArrayにnilを配置できないため)。 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に変換された動作中のアプリからのものであり、完全な一般的なテクニックを示しています。

9
matt

今の私の解決策:

func isNull(someObject: AnyObject?) -> Bool {
    guard let someObject = someObject else {
        return true
    }

    return (someObject is NSNull)
}

これまでのところ、テストはよく見えます...

tests look good so far

7
André Slotta

私は非常に似た問題を抱えており、元のNSDictionary値の正しいタイプにキャストすることでそれを解決しました。サービスがこのような混合型JSONオブジェクトを返す場合

{"id":2, "name":"AC Vent Temp", ...}

そのような値を取得する必要があります。

var id:int = sensor.valueForKey("id") as Int;
var name:String? = sensor.valueForKey("name") as String;

これで私の問題は解決しました。 Swift閉鎖)内のBAD_INSTRUCTION を参照してください

3
loopmasta