Swift guard else called on dictionary key with NULL value

a 夏天 提交于 2019-12-10 11:57:38

问题


If I have a Dictionary returned from a NSNotification containing the following

print(notificationObj.object)
Optional({
    age = "<null>";
    names =     (
        David
    );
})

Then the guard else is called when trying to assign this to a variable:

guard let categories = notificationObj.object as? [String:[String]] else {
  // Gets to here
  return
}

How can I handle the case where a Dictionary key is null.


回答1:


Your dictionary does contain ...

Optional({
    age = "<null>";
    names =     (
        David
    );
})

... and ...

  • age = ... is String = String (value is single String),
  • names = ( ... ) is String = [String] (value is array of Strings).

You can't cast it to [String:[String]] because the first pair doesn't fit this type. This is the reason why your guard statement hits else.

Hard to answer your question. Dictionary contains names, you want categories, names key does contain David, which doesn't look like category, ... At least you know why guard hits else.




回答2:


Your questions is not very clear.

However IF

  • You have a dictionary declared as follow [String:[String]]
  • And you want manage the scenario where a given key is not present

Like this

let devices : [String:[String]] = [
    "Computers": ["iMac", "MacBook"],
    "Phones": ["iPhone 6S", "iPhone 6S Plus"]
]

Then you can at least 2 solutions

1. conditional unwrapping

if let cars = devices["Car"] {
    // you have an array of String containing cars here 
} else {
    print("Ops... no car found")
}

2. guard let

func foo() {
    guard let cars = devices["Car"] else {
        print("Ops... no car found")
        return
    }
    // you have an array of String containing cars here...
    cars.forEach { print($0) }
}



回答3:


It appears that your printed notificationObject.object is constructed from a JSON string that looks like this:

"{ \"age\": null, \"names\":[\"David\"] }"

The reason that you are hitting your else clause is because age is actually a nil, and not a valid String array. I tried using [String: [String]?] and [String: NSArray?] neither of which seem to work. The type is actually an NSNull (which inherits from NSObject).

So you can cast to [String: AnyObject] and check for NSArray like this:

if let categories = j as? [String: AnyObject] where (categories["age"] is NSArray) {
    print("age was array")
} else {
    print("age is probably null")
}

You might be better off if your notification object simply omitted the "age" property when the value is null. Then you would be able to cast to [String: [String]].



来源:https://stackoverflow.com/questions/34051886/swift-guard-else-called-on-dictionary-key-with-null-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!