gpt4 book ai didi

swift - 可解码返回对象

转载 作者:可可西里 更新时间:2023-11-01 01:59:18 25 4
gpt4 key购买 nike

我有一个可解码类:

struct AuthenticationResponse : Decodable {
var status: String
var error: Error
var access_token: String? = ""
var expires_in: Double? = 0
var token_type: String? = ""
var scope: String? = ""
var refresh_token: String? = "
}

struct Error : Decodable {
var desc: String
var code: String
}

在我的错误类中:

为了解码到这个类,我有:

 URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
if let jsonData = data{
let decoder = JSONDecoder()
print("hey")
print("response: \(String(data:jsonData, encoding:.utf8))")
completion(try! decoder.decode(AuthenticationResponse.self, from: jsonData))
}
}.resume()

因为我收到的一些响应是(成功响应):

{
“status”: “SUCCESS” “error”: null, "access_token":
"MWVmOWQxMDYwMjQyNDQ4NzQyNTdkZjQ3NmI4YmVjMGZjZGM5N2IyZmNkOTA1 N2M0NDUzODEwYjM5ZWQyNGNkZg",
"expires_in": 3600, "token_type": "bearer", "scope": null,
"refresh_token":
"ZGEwOGZiOWZhMzhhYjBmMzAyOGRmZTA5NjJhMjY2MTk3YzMyMmE1ZDlkNWI2N mJjYmIxMjNkMjE1NWFhNWY0Mg"
}

然后失败的响应只包含一个错误对象,其中包含 desc 和代码。

我想要实现的是一个适用于两种情况(当响应成功和失败时)的可解码类,但我不确定如何实现这一点。我知道我可以制作 2 个单独的可解码类,但这会使事情变得更困惑,因为我必须确定响应是否为错误并填充以返回不同的类。

有谁知道我应该怎么做>

最佳答案

我会试一试尝试,但首先我们需要理清我认为有点粗制滥造的问题。由于 Error 是(著名且广泛使用的)协议(protocol) 的名称,因此应该重命名它,并且您希望能够在 AuthenticationResponse< 中将其留空 它显然必须是一个可选的(问题是为什么它在 Response 中,但我将把它放在一边)。这给我们留下了以下内容:

struct AuthError : Decodable {
var desc: String
var code: String
}

struct AuthenticationResponse : Decodable {
var status: String
var error: AuthError?
var access_token: String? = ""
var expires_in: Double? = 0
var token_type: String? = ""
var scope: String? = ""
var refresh_token: String? = ""
}

然后我们需要有关两个相关案例的一些示例数据,我使用了:

let okData = """
{
"status": "SUCCESS",
"error": null,
"access_token":
"MWVmOWQxMDYwMjQyNDQ4NzQyNTdkZjQ3NmI4YmVjMGZjZGM5N2IyZmNkOTA1N2M0NDUzODEwYjM5ZWQyNGNkZg",
"expires_in": 3600,
"token_type": "bearer",
"scope": null,
"refresh_token":
"ZGEwOGZiOWZhMzhhYjBmMzAyOGRmZTA5NjJhMjY2MTk3YzMyMmE1ZDlkNWI2NmJjYmIxMjNkMjE1NWFhNWY0Mg"
}
""".data(using: .utf8)!

let errData = """
{
"desc": "username or password incorrect",
"code": "404"
}
""".data(using: .utf8)!

现在我们可以定义一个单一的 enum 返回类型,它允许我们所有的情况:

enum AuthResult {
case ok(response: AuthenticationResponse)
case authError(error: AuthError)
case parseError(description: String)
case fatal
}

这最终允许我们为接收到的身份验证数据编写parse 函数:

func parse(_ jsonData:Data) -> AuthResult {
let decoder = JSONDecoder()
do {
let authRes = try decoder.decode(AuthenticationResponse.self, from: jsonData)
return .ok(response: authRes)
} catch {
do {
let errRes = try decoder.decode(AuthError.self, from: jsonData)
return .authError(error: errRes)
} catch let errDecode {
return .parseError(description: errDecode.localizedDescription)
}
}
}

Playground 中的所有这些都将允许使用

switch parse(okData) {
case let .ok(response):
print(response)
case let .authError(error):
print(error)
case let .parseError(description):
print("You threw some garbage at me and I was only able to \(description)")
default:
print("don't know what to do here")
}

与您在大多数其他语言中造成的困惑相比,这仍然是优雅的,但是调用仍然是在将 AuthenticationResponse 定义为(常规)返回是否更有意义parse 函数的类型,并通过 throwing 一些 enum(符合 Error)和一些合适的方法来提供其余部分有效负载。

(主要)来自 Java 我仍然避免将异常用作“某种程度上”的常规控制流(如在“常规”登录失败中),但考虑到 Swifts 处理异常的更合理方法,这可能必须重新考虑。

无论如何,这为您提供了一个函数来解析您的服务回复的任何一种情况,并以一种“统一”的方式处理它们。由于您可能无法修改处理您的请求 的服务的行为,这可能是唯一可行的选择。但是,如果您能够修改服务,您应该努力获得“统一”的回复,只需调用一次 JSONDecoder.decode 即可解析该回复。你仍然需要解释可选值(就像你在上面的例子中应该做的那样,因为使用它们仍然很痛苦,即使 Swifts 出色的编译器支持迫使你“做正确的事”),但它会使你的解析不易出错。

关于swift - 可解码返回对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47885117/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com