gpt4 book ai didi

json - 在 Swift 中解析 json,AnyObject 类型

转载 作者:IT老高 更新时间:2023-10-28 12:47:19 26 4
gpt4 key购买 nike

我正在尝试解析 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")
}
}
}

最佳答案

这对我在 Playground 和终端中使用 env xcrun swift

来说都很好

针对 SWIFT 4 和 CODABLE 进行了更新

这是一个使用 Codable 协议(protocol)的 Swift 4 示例。

var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"

struct Weather: Codable {
let id: Int
let main: String
let description: String
let icon: String
}

struct Result: Codable {
let weather: [Weather]
}

do {
let weather = try JSONDecoder().decode(Result.self, from: jsonStr.data(using: .utf8)!)
print(weather)
}
catch {
print(error)
}

为 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,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, 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,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, 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 语法。我还继续输入了 idmaindescription

关于json - 在 Swift 中解析 json,AnyObject 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24671249/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com