Catch模式更改回调签名

时间:2017-10-21 22:10:01

标签: swift swift4 decodable do-catch

我正在尝试使用JSONDecoder使用Alamofire解码来自我的服务器的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回调中使用它。< / p>

这就是我目前所得到的:

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行上的编译器错误。

  

投掷类型&#39;(_)的功能无效转换 - &gt;虚空&#39;到非投掷功能类型&#39;(DataResponse) - &gt;空隙&#39;

守卫代码工作正常,如果我将try更改为try?或强制解包,它会编译 - 我只是不能让我的捕获处理实际的错误

如果我更改catch块以使其不包含任何模式,则代码将编译。

catch {
    return
}

这并不能解释我guard给我的东西。我真的想捕获decode操作遇到的错误。我使用错误的模式吗?为什么使用DecodingError.dataCorrupted模式似乎会改变回调签名?

1 个答案:

答案 0 :(得分:1)

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

你也可以:

  • 当您使用responseData进行自己的反序列化时,请使用responseJSON代替JSONDecoder
  • 在Alamofire的unwrap()类型上使用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>参数来传播错误。

在这种情况下,您可以使用Result的{​​{1}}方法,而不是flatMap(_:)unwrap()块:

catch {}