我有一个包含多个“ Dozzs”对象的Json文件。
在每个“ Dozzs”对象内部是一个或多个“ Dozz”对象。因此,我将“ Dozzs”对象与一个“ Dozz”对象混合在一起,将“ Dozzs”对象与一个“ Dozz”对象数组混合在一起。
但是我不能在结构Route::group(['prefix' => 'auth'], function () {
Route::post('login','AuthController@login');
Route::post('signup','AuthController@signup');
Route::group(['middleware' => 'auth:api'], function () {
Route::get('logout','AuthController@logout');
Route::get('user','AuthController@user');
});
});
中说,如果是这种情况,JSONDecoder不想将一个“ Dozz”解析为一个“ Dozz”数组。
是否有一种方法(如果Dozzs中只有一个Dozz对象)将其解析为数组? 因此,我始终在结构中包含一个或多个对象的Dozz-Array,并且JSONDecoder不会崩溃。
这是我当前的结构:
let doz: [Dozz]
这是json:
struct Dozzs : Codable {
let doz : Dozz?
//let doz: [Dozz]?
}
帮助会很棒?
答案 0 :(得分:1)
我整理了一个样本,希望对您有所帮助。
let json1 = """
{
"doz": {
"dozProp1": "prop1",
"dozProp2": "prop2"
}
}
"""
let json2 = """
{
"doz": [
{
"dozProp1": "prop1",
"dozProp2": "prop2"
},
{
"dozProp1": "prop1_23",
"dozProp2": "prop2_34"
}
]
}
"""
public struct Doz: Decodable {
var dozProp1: String
var dozProp2: String
}
public enum JSONValue: Decodable {
case arrayDoz([Doz])
case doz(Doz)
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let value = try? container.decode([Doz].self) {
self = .arrayDoz(value)
} else if let value = try? container.decode(Doz.self) {
self = .doz(value)
} else {
throw DecodingError.typeMismatch(JSONValue.self, DecodingError.Context(codingPath: container.codingPath, debugDescription: "Not doz"))
}
}
}
public struct DecodingDoz: Decodable {
var doz: JSONValue
}
let parsed1: DecodingDoz = try JSONDecoder().decode(DecodingDoz.self, from: json1.data(using: .utf8)!)
let parsed2: DecodingDoz = try JSONDecoder().decode(DecodingDoz.self, from: json2.data(using: .utf8)!)
print(parsed1.doz)
print(parsed2.doz)
一个简短的解释,所以我用Doz的两个可能值创建了一个枚举,并做了一个是否让json解析出Doz类型的检查,我发现匹配项是否则,将引发异常。
快乐编码
答案 1 :(得分:0)
您应该覆盖解码器中的init并解码JSON。在下面的代码中,我首先尝试解码单个Doz
对象,如果结果为nil,然后尝试解码Doz数组。
struct Dozzs : Decodable {
let doz : [Dozz]?
// Coding Keys
enum MyDozzsKeys: String, CodingKey {
case doz
}
// Overriding init
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: MyDozzsKeys.self)
if let doz = try? container.decode(Dozz.self, forKey: .doz) {
self.doz = [doz]
} else {
let doz = try container.decode([Dozz].self, forKey: .doz)
self.doz = doz
}
}
}
更新: 根据您的JSON,模型应该是这样的:
struct Dozzs : Decodable {
let dozzs : [Doz]?
enum MyDozzsKeys: String, CodingKey {
case dozzs
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: MyDozzsKeys.self)
if let doz = try? container.decode(Doz.self, forKey: .dozzs) {
self.dozzs = [doz]
} else {
let doz = try container.decode([Doz].self, forKey: .dozzs)
self.dozzs = doz
}
}
}
struct Doz: Decodable {
let doz: DozData
}
struct DozData: Decodable {
let type: String
let key: String
enum CodingKeys: String, CodingKey {
case type = "-type"
case key = "-key"
}
}
struct Test: Decodable {
let test: [Dozzs]?
}
并像这样解码:
try JSONDecoder().decode(Test.self, from: jsonTest)