如何解决使用Decodable解码基本JSON响应的对象类型和通用类型的数据
struct BaseModel<T:Decodable>: Decodable {
let jsonData: [T]?
let status: Bool?
let message: String?
enum CodingKeys: String,CodingKey {
case jsonData = "data"
case status = "success"
case message
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
if let string = try container.decodeIfPresent(T.self,forKey: .jsonData) {
print(string)
jsonData = [string]
} else {
jsonData = nil
}
} catch DecodingError.typeMismatch {
jsonData = try container.decodeIfPresent([T].self,forKey: .jsonData)
}
status = try container.decodeIfPresent(Bool.self,forKey: .status)
message = try container.decodeIfPresent(String.self,forKey: .message)
}
}
我在jsonData下得到两种类型的响应
- 对象
- 数组
如果我收到作为对象的响应,则在解码时出错。如果我选择let jsonData:T ?,那么在解码数组响应时就会出现问题。
我正在网络模型中使用此模型。看起来像-
func performOperation<T:Decodable>(urlEndPoint: String,method: HTTPMethod,param: Parameters?,isJsonAvailable: Bool,completion: @escaping(_ response: T?,[T]?,String?,Bool?) ->Void) {
AF.request(urlEndPoint,method: method,parameters: param,headers: header).validate(statusCode: 200..<500).responseDecodable(of: BaseModel<T>.self,decoder: decoder) { (response) in
}
在 Object -
情况下的Json响应 {
"success": true,"data": {
"heading": "Same text 1","title": "Sample Text 2","content": "Sample text 3"
},"message": "Api response received"
}
在 ArrayList -
情况下的Json响应{
"success": true,"data": [
{
"id": 1,"name": "Home"
},{
"id": 2,"name": "Profile"
}
],"message": "Menu List"
}
解决方法
您不需要通用结构。如果没有用户数组,只需创建一个可选属性来分配对象:
struct BaseModel {
let data: [User]
let post: Post?
let success: Bool
let message: String
}
struct User: Codable {
let id: Int
let name: String
}
struct Post: Codable {
let heading: String
let title: String
let content: String
}
extension BaseModel: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
data = try container.decode([User].self,forKey: .data)
post = nil
} catch DecodingError.typeMismatch {
data = []
post = try container.decode(Post.self,forKey: .data)
}
success = try container.decode(Bool.self,forKey: .success)
message = try container.decode(String.self,forKey: .message)
}
}
如果您的帖子中没有显示其他答复,您也可以使用通用结构执行上述相同方法:
struct BaseModel<T: Codable> {
let array: [T]
let element: T?
let success: Bool
let message: String
}
extension BaseModel: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
array = try container.decode([T].self,forKey: .array)
element = nil
} catch DecodingError.typeMismatch {
array = []
element = try container.decode(T.self,forKey: .array)
}
success = try container.decode(Bool.self,forKey: .message)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。