问题描述
我的JSON结构如下:
{
"data": [
{
"value":["val1","val2","val3"]
},{
"value":"val"
}
]
}
那么我将如何在此处解析“值”字段?有时它是一个字符串数组,有时它只是一个字符串。我将为它分配什么类型?
解决方法
使用SwiftyJSON,您可以检查value
属性的值是简单字符串还是字符串数组,如下所示:
let jsonString = """
{
"data": [
{
"value":["val1","val2","val3"]
},{
"value":"val"
}
]
}
"""
let json = JSON(parseJSON: jsonString)
json["data"].array?.forEach { dataItem in
if let dataArray = dataItem["value"].array {
print("array: \(dataArray)")
print("array first item: \(dataArray.first?.string ?? "nil")")
} else if let dataString = dataItem["value"].string {
print("string: \(dataString)")
}
}
,
您需要以某种方式抽象数据数组中的字典值。然后,在访问对象时,可以对它们进行类型检查,或者在解码时进行类型检查。
这是我使用本地JSONDecoder解决此问题的方法。重要的是您需要为解码器提供严格的对象类型。 Any,AnyObject
类不符合Decoder
协议,因为它们没有要解码的类型容器。
enum B: Decodable {
private enum CodingKeys: CodingKey {
case value
}
enum BDecodingError: Error {
case decoding(String)
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let val = try? container.decodeIfPresent(Array<String>.self,forKey: .value) {
self = .array(val)
return
}
if let val = try? container.decodeIfPresent(String.self,forKey: .value) {
self = .string(val)
return
}
throw BDecodingError.decoding("B Decoding Error")
}
case array(Array<String>)
case string(String)
}
B枚举负责将对象保留在字典中。您可以在此处指定可能的类型,然后检查对该类型的解码是否成功。
struct A: Decodable {
let data: [B]
}
结构只是将字典的对象保存在data
数组中。