Swift : JSONSerialization.jsonObject 不适用于 json 进入 json
Swift : JSONSerialization.jsonObject not working for json into json
我正在使用此代码从 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"}}
你应该像这样使用 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) }
Using as! [String:String]
你是说字典中所有的值都是String类型,但是state key相关的嵌套JSON显然不是String
使用 as? [String: Any]
,然后根据需要转换您的其他属性。 result["error"] as String
使用这种方法会使获取嵌套数据变得比需要的更困难:
if let state = result["state"] as? [String: String] {
let name = state["name"]
let value = state["value"]
}
备注
- 当使用 Swift 4 或更高版本时,您应该使用 Codable 协议
- 你不应该强制展开,使用条件展开(
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)
你可以使用这个 code.This 代码应该适用于你的 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
如有其他问题请评论我!
我正在使用此代码从 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"}}
你应该像这样使用 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) }
Using as! [String:String]
你是说字典中所有的值都是String类型,但是state key相关的嵌套JSON显然不是String
使用 as? [String: Any]
,然后根据需要转换您的其他属性。 result["error"] as String
使用这种方法会使获取嵌套数据变得比需要的更困难:
if let state = result["state"] as? [String: String] {
let name = state["name"]
let value = state["value"]
}
备注
- 当使用 Swift 4 或更高版本时,您应该使用 Codable 协议
- 你不应该强制展开,使用条件展开(
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)
你可以使用这个 code.This 代码应该适用于你的 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
如有其他问题请评论我!