如何准备API响应以便在swift中与jsonDecoder一起使用



当我调用API并使用Alamofire从服务器获得响应时,我希望使用json 中的"数据"对象

这些数据来自API

{
"code": 200,
"hasError": false,
"data": [
{
"userSession": "43a1bd70-26bf-11e9-9ccd-00163eaf6bb4"
}
],
"message": "ok"
}

我想把data映射到我的AuthModel

这是我的AuthModel:

struct AuthModel: Codable {
let userSession: String
enum CodingKeys: String, CodingKey {
case userSession = "userSession"
}
}

我编码了这些行,但不起作用:

if let responseObject = response.result.value as? Dictionary<String,Any> {
if let hasError = responseObject["hasError"] as? Bool {
guard !hasError else { return }
do {
let decoder = JSONDecoder()
let authModel = try decoder.decode(AuthModel.self, from: responseObject["data"])
} catch {
print("Parse Error: ",error)
}
}
}

这不起作用,因为responseObject["data"]不是NSData类型

无法将类型为"[String:Any]"的值转换为预期的参数类型"Data">

我认为您的API响应是一种模式,表明:

  • 我们有什么问题(错误)吗
  • 我们有预期的数据吗

基于这些,我们可以使用EnumGenerics。例如:

class ResponseObject<T: Codable>: Codable {
private var code        : Int
private var hasError    : Bool
private var message     : String
private var data        : T?
var result: Result {
guard !hasError else { return .error(code, message) }
guard let data = data else { return .error(0, "Data is not ready.") }
return .value(data)
}
enum Result {
case error(Int, String)
case value(T)
}
}

并且我们可以将ResponseObject与我们期望的data:一起使用

let responseString = """
{
"code": 200,
"hasError": false,
"data": [
{
"userSession": "43a1bd70-26bf-11e9-9ccd-00163eaf6bb4"
}
],
"message": "ok"
}
"""
class AuthObject: Codable {
var userSession : String
}
if let jsonData = responseString.data(using: .utf8) {
do {
//ResponseObject<[AuthObject]> means: if we don't have error, the `data` object in response, will represent `[AuthObject]`.
let responseObject = try JSONDecoder().decode(ResponseObject<[AuthObject]>.self, from: jsonData)
//Using ResponseObject.Result Enum: We have error with related code and message, OR, we have our expected data.
switch responseObject.result {
case .error(let code, let message):
print("Error: (code) - (message)")
case .value(let authObjects):
print(authObjects.first!.userSession)
}
} catch {
print(error.localizedDescription)
}
}

获取Data响应,而不是反序列化的Dictionary,例如

Alamofire.request(url).responseData { response in

并解码

let decoder = JSONDecoder()
let authModel = try decoder.decode(AuthModel.self, from: response.data!)

进入这些结构

struct AuthModel : Decodable {
let code : Int
let hasError : Bool
let message : String
let data : [Session]
}
struct Session : Decodable {
let userSession: String
}

所有编码键都是合成的。

相关内容

  • 没有找到相关文章

最新更新