我正在尝试使用从服务返回的JSON数据。根据JSON验证器,JSON是有效且非常简单的:
[{"ID":"SDS-T589863","TotalRisk":0.2458,"TotalScore":641.032}]
然而,试图在我的Swift 4代码中解析它,这是神秘的(至少对我来说)无效。这是我尝试解析它:
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// this is fine:
guard let ddd = String(bytes: responseData, encoding: String.Encoding.utf8) else {
print("can't")
return
}
print(ddd) // prints [{"ID":"SDS-T589863","TotalRisk":0.2458,"TotalScore":641.032}] happily
do {
// cannot serialize
guard let risk = try JSONSerialization.jsonObject(with: responseData, options: [JSONSerialization.ReadingOptions.allowFragments])
as? [String: Any]
else {
print("error trying to convert data to JSON")
return
}
print(risk)
} catch {
print("error trying to convert data to JSON")
return
}
}
task.resume()
}
假设我无法控制JSON对象或它返回给我的格式,有没有办法告诉JSON有什么问题,并且可能格式化响应以便可以正确序列化? / p>
答案 0 :(得分:4)
您应该将数据转换为[[String: Any]]
类型,因为您有响应数组。
您正在尝试转换为[String: Any]
,但您有一个[String: Any]
数组,因为您的回复位于[]
括号中。
示例:
let risk = try JSONSerialization.jsonObject(with: responseData, options: [JSONSerialization.ReadingOptions.allowFragments]) as? [[String: Any]]
或者如果您只想从响应中获取一个[String: Any]
对象,您可以写:
let risk = (try JSONSerialization.jsonObject(with: responseData, options: [JSONSerialization.ReadingOptions.allowFragments]) as? [[String: Any]])?.first
或者如果你的对象可以是数组而不是数组(但听起来有点奇怪),你可以尝试转换为几种可能的类型。
答案 1 :(得分:1)
响应类型是json对象的数组,因此您必须将其强制转换为[[String: Any]]
。由于您使用的是Swift 4,因此可以使用Decodable
类型将模型映射到响应。
let task = URLSession().dataTask(with: urlRequest) { (data, response, error) in
// check for any errors
guard error == nil else {
print(error!)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
let decoder = JSONDecoder()
let riskArray = try decoder.decode([Risk].self, from: responseData)
print(riskArray)
} catch {
print("error trying to convert data to Model")
print(error.localizedDescription)
}
}
task.resume()
您可以将模型结构定义为
struct Risk: Decodable {
let id: String
let totalRisk: Double
let totalScore: Double
enum CodingKeys: String, CodingKey {
case id = "ID"
case totalRisk = "TotalRisk"
case totalScore = "TotalScore"
}
}
您可以阅读有关可解码协议here
的更多信息