在Swift中解析json,AnyObject类型
我试图解析一个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,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 [“天气”]! if let dict = json as? [String: AnyObject] { println(dict) if let weatherDictionary = dict["weather"]! as? [AnyObject] { println("nWeather dictionary:nn(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") } } }
这对我在操场和终端使用env xcrun swift工作得很好
UPDATED FOR SWIFT 3.0 我更新了Swift 3的代码,还展示了如何将解析的JSON包装到对象中。感谢所有的投票! import Foundation struct Weather { let id: Int let main: String let description: String let icon: String } extension Weather { init?(json: [String: Any]) { guard let id = json["id"] as? Int,let main = json["main"] as? String,let description = json["description"] as? String,let icon = json["icon"] as? String else { return nil } self.id = id self.main = main self.description = description self.icon = icon } } var jsonStr = "{"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],}" enum JSONParseError: Error { case notADictionary case missingWeatherObjects } var data = jsonStr.data(using: String.Encoding.ascii,allowLossyConversion: false) do { var json = try JSONSerialization.jsonObject(with: data!,options: []) guard let dict = json as? [String: Any] else { throw JSONParseError.notADictionary } guard let weatherJSON = dict["weather"] as? [[String: Any]] else { throw JSONParseError.missingWeatherObjects } let weather = weatherJSON.flatMap(Weather.init) print(weather) } catch { print(error) } – 上一个答案 – import Foundation var jsonStr = "{"weather":[{"id":804,}" var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding,allowLossyConversion: false) var localError: NSError? var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data!,error: &localError) if let dict = json as? [String: AnyObject] { if let weather = dict["weather"] as? [AnyObject] { for dict2 in weather { let id = dict2["id"] let main = dict2["main"] let description = dict2["description"] println(id) println(main) println(description) } } } 因为我仍然拿起来投票的这个答案,我想我会重新审视它的Swift 2.0: import Foundation var jsonStr = "{"weather":[{"id":804,allowLossyConversion: false) do { var json = try NSJSONSerialization.JSONObjectWithData(data!,options: NSJSONReadingOptions.MutableContainers) if let dict = json as? [String: AnyObject] { if let weather = dict["weather"] as? [AnyObject] { for dict2 in weather { let id = dict2["id"] as? Int let main = dict2["main"] as? String let description = dict2["description"] as? String print(id) print(main) print(description) } } } } catch { print(error) } 最大的区别是变量json不再是可选类型和do / try / catch语法。我也去了键入id,main和description。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |