如何使用 Alamofire 处理两个不同的 JSON 响应

tan*_*eek 2 swift alamofire urlsession

我正在 SwiftUI 应用程序中创建登录功能。登录成功后,JSON 响应为:

    {
    "user_id": 41,
    "token": "Token",
    "token_type": "bearer",
    "expires_in": 12096000
    }
Run Code Online (Sandbox Code Playgroud)

当登录失败时,JSON 响应为:

{
 "message": "this is a failure message"
}
Run Code Online (Sandbox Code Playgroud)

我制作了两个不同的结构来对响应进行编码

struct LoginResponseModelFailure:Codable {
    let message:String
}

struct LoginResponseModelSuccess:Codable{
    let user_id: Int
    let token: String
    let token_type : String
    let expires_in: Int
}
Run Code Online (Sandbox Code Playgroud)

我需要将这两个结构合并为一个吗?如果是这样怎么办?如何使用 alamofire 或 urlSession 处理两个不同的响应?

vad*_*ian 6

为了避免可选,我的建议是将根对象声明为具有关联值的枚举

enum Response : Decodable {
    case success(ResponseSuccess)
    case failure(ResponseFailure)
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        do {
            self = .success(try container.decode(ResponseSuccess.self))
        } catch {
            self = .failure(try container.decode(ResponseFailure.self))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

其他结构可以保持原样,除了名称变成驼峰命名法

struct ResponseFailure : Decodable {
    let message : String
}

struct ResponseSuccess : Decodable {
    let userId : Int
    let token : String
    let tokenType : String
    let expiresIn : Int
}
Run Code Online (Sandbox Code Playgroud)

switch对结果数据进行解码,data表示接收到的原始数据。添加密钥解码策略来处理snake_case密钥

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Response.self, from: data)
    switch result {
        case .success(let data): print(data)
        case .failure(let error): print(error)
    }
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)