Я пытаюсь разобрать json, но у меня есть некоторые трудности с типами данных и, в частности, с типом AnyObject + downcasting.
Рассмотрим следующий 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
, чтобы получить JSON из URL-адреса).
Затем я хочу получить доступ к словарю погоды. Вот код, который я написал.
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, no?
Если я использую 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)")
}
}
}
Обратите внимание, что мы должны дважды проверить наличие первого Необязательного.
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")
}
}
}