2

我正在使用此代码从 url 获取 json 数据:

URLSession.shared.dataTask(with:request, completionHandler: { (data, response, error) in
 guard let data = data, error == nil else { return }

 do {           
   let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:String]
   completion(json)              
 } catch _ as NSError {
   completion(nil)
 }
}).resume()

如果我的 json 是{"error":"true","message":"no"}它工作正常

但是,如果我将 json 用于 json,它就不起作用:

{"error":"true","message":"no","state":{"id":"1","name":"empty"}}
4

3 回答 3

2

使用as! [String:String]你是说字典中的所有值都是字符串类型,但是与状态键相关的嵌套 JSON 显然不是字符串

使用 as? [String: Any]然后根据需要转换您的其他属性。result["error"] as String

使用此方法会使获取嵌套数据变得比实际需要的更加困难:

if let state = result["state"] as? [String: String] {
    let name = state["name"]
    let value = state["value"]
}

笔记

  1. 使用 Swift 4 或更高版本时,您应该使用 Codable 协议
  2. 您不应该强制展开,使用条件展开 ( as? [String: Any])

编辑:

一个如何使用 Codable 以及如何使用它的示例。

操场代码

// you dont need this part, I am not making network request
let jsonData = """
{"error":"true","message":"no","state":{"id":"1","name":"empty"}}
""".data(using: .utf8)

struct ErrorState: Codable
{
    let id: String
    let name: String
}

struct ErrorResponse: Codable
{
    let error: String
    let message: String
    let state: ErrorState
}

guard let data = jsonData else { fatalError() }

let errorResponse = try? JSONDecoder().decode(ErrorResponse.self, from: data)
print(errorResponse?.state.name)
于 2018-04-25T10:12:24.650 回答
0

你应该像这样使用 Codable 协议

 var json = [String:Any]()

    struct List : Decodable {

        let error : String
        let message : String

        private enum CodingKeys : String, CodingKey { case name = "error", score = "message" }

    }


    var list = [List]()

    let jsonString = """

                      {"error" : "true", "message" : "no"}

                     """

    let data = Data(jsonString.utf8)

    do {
        list = try JSONDecoder().decode([List].self, from: data)
        let error = list.object(forKey: "error") as? String ?? ""
        print(error)
    } 
   catch { print(error) }
于 2018-04-25T10:10:27.733 回答
0

您可以使用此代码吗?此代码应该适用于您的 json 响应。

let error = json["error"]! as! NSString
print(error) // it prints true

let message = json["message"]! as! NSString
print(message) // it prints no

guard let state = json["state"] as? [String: String],

let id = state["id"],      
let name = state["name"]

else  {
  return
}

print(id)  // it prints 1
print(name) // it prints empty

如果还有其他问题欢迎评论我!

于 2018-04-25T12:19:09.717 回答