gpt4 book ai didi

swift - 捕获模式更改回调签名

转载 作者:行者123 更新时间:2023-11-28 15:15:59 27 4
gpt4 key购买 nike

我正在尝试使用 JSONDecoder使用 Alamofire 解码来 self 的服务器的 json 响应。当我用 guard 解码响应时,它可以正常工作。这种方法的副作用是,当解码实际上失败时,我无法判断问题出在哪里。

guard let result: TResponseData = try? decoder.decode(TResponseData.self, from: response.data!) else {
self.logger.error("Unable to decode the response data into a model representation.")
return
}

所以我想使用 do { } catch { }但我不知道我应该如何在 Alamofire 中使用它 responseJSON回调。

这是我目前得到的:

Alamofire.request(completeUrl, method: .post, parameters: parameters, encoding: encoding, headers: headers)
.validate()
.responseJSON { (response) -> Void in
self.logger.info("POST Response: \(String(describing:response.response?.statusCode))")
switch response.result {
case .success(_):
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(Date.toTMDBDate)

do {
let _ = try decoder.decode(TResponseData.self, from: response.data!)
} catch DecodingError.dataCorrupted(let error) {
self.logger.error(error.underlyingError)
return
}

completion(result)
return
case .failure(let error):
//....
}

然而,我得到的这段代码是关于 .responseJSON { (response) -> Void in 的编译器错误。行。

Invalid conversion from throwing function of type '(_) -> Void' to non-throwing function type '(DataResponse) -> Void'.

守卫代码工作正常,如果我更改 trytry?或强制解包,它会编译 - 我只是没有让我的 catch 处理实际错误。

如果我更改 catch block 以便它不包含任何模式,然后代码编译。

catch {
return
}

这对我的 guard 没有任何帮助在给我。我真的很想捕获 decode 遇到的错误手术。我使用了错误的模式吗?为什么使用 DecodingError.dataCorrupted模式似乎改变了回调签名?

最佳答案

JSONDecoder可以抛出 DecodingError.dataCorrupted 以外的错误;您需要能够处理任意 Error 的情况被抛出。所以,如果你想处理那个错误,你需要一个无条件的 catch {} block 。

您还可以:

  • 使用responseData而不是 responseJSON当您使用 JSONDecoder 进行自己的反序列化时.
  • 使用unwrap() Alamofire 上的方法 Result如果需要,键入以便合并网络错误和解码错误。

这是它的样子:

Alamofire
.request(
completeUrl, method: .post, parameters: parameters,
encoding: encoding, headers: headers
)
.validate()
.responseData { response in

self.logger.info(
"POST Response: \(response.response?.statusCode as Any)"
)

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(Date.toTMDBDate)

do {
let result = try decoder.decode(
TResponseData.self, from: response.result.unwrap()
)
completion(result)
} catch {
self.logger.error(error)
}
}

尽管这里要注意的一件事是您没有调用 completion如果请求失败;我会亲自改变你所做的,并通过 completion 传播错误拿个Result<TResponseData>参数。

在这种情况下,您可以使用 ResultflatMap(_:)方法而不是 unwrap()和一个 catch {} block :

func doRequest(_ completion: @escaping (Result<TResponseData>) -> Void) {

let completeURL = // ...
let parameters = // ...
let encoding = // ...
let headers = // ...

Alamofire
.request(
completeURL, method: .post, parameters: parameters,
encoding: encoding, headers: headers
)
.validate()
.responseData { response in

self.logger.info(
"POST Response: \(response.response?.statusCode as Any)"
)

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(Date.toTMDBDate)

// if response.result is successful data, try to decode.
// if decoding fails, result is that error.
// if response.result is failure, result is that error.
let result = response.result.flatMap {
try decoder.decode(TResponseData.self, from: $0)
}
.ifFailure {
self.logger.error($0)
}

completion(result)
}
}

关于swift - 捕获模式更改回调签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46868600/

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