我试图解析一个JSON,但在数据类型,特别是AnyObject类型和下转型方面遇到了一些困难。
考虑以下JSON(它是完整JSON的一个摘录)。
{ "weather":
[
{
"id":804,
"main":"Clouds",
"description":"overcast clouds",
"icon":"04d"
}
],
}
对我来说,json可以描述为以下内容:
- json: Dictionary of type [String: AnyObject] (or NSDictionary, so = [NSObject, AnyObject] in Xcode 6 b3)
- "weather": Array of type [AnyObject] (or NSArray)
- Dictionary of type [String: AnyObject] (or NSDictionary, so = [NSObject, AnyObject] in Xcode 6 b3)
我的json的类型是AnyObject!(我使用JSONObjectWithData
从URL获取JSON)。
然后,我想访问天气字典。这是我编写的代码。
var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &localError)
if let dict = json as? [String: AnyObject] {
if let weatherDictionary = dict["weather"] as? [AnyObject] {
// Do stuff with the weatherDictionary
}
}
这里是我遇到的错误
Playground execution failed: error: <EXPR>:28:56: error: '[AnyObject]' is not a subtype of '(String, AnyObject)'
if let weatherDictionary = dict["weather"] as? [AnyObject] {
我不明白为什么将 dict["weather"] 与 (String, AnyObject) 的子类型进行比较,而不是 AnyObject。我将字典声明为 [String: AnyObject],所以当我使用 String 键访问一个值时,应该得到 AnyObject,对吗?
如果我使用 NSDictionary 而不是 [String: AnyObject],它可以工作。
如果我使用 NSArray 而不是 [AnyObject],它也可以工作。
- The Xcode 6 beta 3 release notes tell that "NSDictionary* is now imported from Objective-C APIs as [NSObject : AnyObject].".
- And the Swift book: "When you bridge from an NSArray object to a Swift array, the resulting array is of type [AnyObject]."
编辑
我忘记强制解包 dict["weather"] 了!
if let dict = json as? [String: AnyObject] {
println(dict)
if let weatherDictionary = dict["weather"]! as? [AnyObject] {
println("\nWeather dictionary:\n\n\(weatherDictionary)")
if let descriptionString = weatherDictionary[0]["description"]! as? String {
println("\nDescription of the weather is: \(descriptionString)")
}
}
}
请注意,我们应该仔细检查第一个Optional是否存在。
if let dict = json as? [String: AnyObject] {
for key in ["weather", "traffic"] {
if let dictValue = dict[key] {
if let subArray = dictValue as? [AnyObject] {
println(subArray[0])
}
} else {
println("Key '\(key)' not found")
}
}
}
[AnyObject]
时,非常努力地将dict["weather"]
解释为对subscript (i: DictionaryIndex<KeyType, ValueType>) -> (KeyType, ValueType) { get }
的调用。但我不确定原因是什么... 你可能想要提交一个bug报告。 - jtbandes