如何在Swift中使用尾随闭包语法处理抛出闭包?

时间:2019-04-18 18:45:50

标签: swift alamofire

我正在使用Alamofire进行HTTP请求。

try Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    let error = response.error;

   if (error != nil) {
     throw MyError(message: "No good")
   }


   // This line is from Alamofire docs and causes no issue 
   let json = try! JSONSerialization.jsonObject(with: response.data!, options: [])

   // do more goodies here which may also throw exceptions
}

自从我添加了抛出之后,我得到了错误Invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(DefaultDataResponse) -> Void'。我以前已经掌握了这一点,并且知道我只需要在正确的位置添加try。我认为在Alamofire.request前面这样做可能会成功,但没有成功。

我也尝试过

let req = Alamofire.request(url, headers: headers).validate();
try req.response { response in

我在Google上搜索“在尾随闭包内抛出”时也找不到任何有关此的信息。

3 个答案:

答案 0 :(得分:0)

根据上面的评论,我不能直接扔。我最终这样做:

try Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    do {
      let error = response.error;

      if (error != nil) {
        throw MyError(message: "No good")
      }

      // more logic

      if (anotherCondition == true) {
        throw AnotherError(message: "Error Parsing return data that I expected");
      }

    }
    catch let error {
      uiMessage = "";
      if error is errorThatUserShouldSeeSomething {
        uiMessage = error.localizedDescription;
      }
      ErrorHandler.handle(error: error, uiMessage: uiMessage); 
    }
}

说实话,我原本打算进行ErrorHandler.handle调用,这始终是我的自定义处理程序。不过,将其放在堆栈中更高会很好。

答案 1 :(得分:0)

问题是您不允许传递给Alamofire的闭包。如果您问自己“如果抛出此函数,谁来处理它,这是有道理的”。扔到您从中调用函数的范围是行不通的(也就是在try前面添加Alamofire.request),因为在异步操作之后将要调用闭包,并且您可能已经离开了完全范围。如果Alamofire在您的关闭过程中有一个do-catch块,那将使您不能排在第一位的目的就无法实现,因为Alamofire不知道如何处理您抛出的错误,而只能吃掉它(或通过某种形式的关闭或通知将其传回给您,现在我们走了一个圈。在这种情况下,我认为解决问题的最佳方法是调出您在catch块中放置的任何内容,以处理可能会Alamofire.request引发的错误。

Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    let error = response.error;

   if (error != nil) {
     DaveSteinErrorHandler.handleError(MyError(message: "No good"))
   }


   // This line is from Alamofire docs and causes no issue 
   let json = try! JSONSerialization.jsonObject(with: response.data!, options: [])

   // do more goodies here
}

为了将来参考,这里有一些术语和代码来定义您编写的代码在这种情况下所执行的行为。 rethrows关键字表示您正在调用的函数将接受闭包作为参数,并且该函数将抛出的唯一错误是来自您抛出闭包的错误。

答案 2 :(得分:0)

您应遵循do-try-catch语法。

因此,您应该做更多类似的事情:

do {
    try Alamofire.request(url, headers: headers)
    /* Rest of the try */
} catch {
    /* Runs if the `try` fails
}

该错误非常容易引起误解。