首页 > 解决方案 > 如何在 URLSession 中调用 completionBlock

问题描述

我正在尝试学习如何使用 Rest API。我想先使用 Github API 从 iPhone 登录。

这是我的模型(尚未完成):

mutating func gettingAceess(completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void ) throws {
    guard username != "", password != "" else {
        throw loginError.emptyUsernameOrPassword
    }

    let loginString = "\(self.username):\(self.password)"
    let resourceUrl = "https://\(loginString)@api.github.com"
    guard let loggingUrl = URL(string: resourceUrl) else {fatalError()}

    let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
        if error != nil {
            print("\(String(describing: error))")
        }
    }

    logging.resume()
}

在控制器中,我希望当用户点击登录按钮时,应该调用获取访问功能。

@IBAction func pressLoginBtn(_ sender: UIButton) {
    if let username = usernameInput.text,  let password = passwordInput.text {
        var logginInformation = LogginReguest(username: username, password: password)
        do {
            try logginInformation.gettingAceess(completionBlock: ...)
        } catch {
  }

前面的代码try,不知道该写什么。谁能帮我?还是我做错了整个事情?

标签: swifturlsession

解决方案


do {
  // if completion block is last argument; you can use trailing syntax
  try logginInformation.gettingAceess() { (data, response, error) in
     // as your completion block have this signature
     // completionBlock: @escaping (_ data : Data?, _ response : URLResponse?, _ error : Error?) -> Void)

  }
} catch {

您还需要更新gettingAceess方法。

let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
  if error != nil {
     print("\(String(describing: error))")
   }
   // This line passes this completion block to caller who can read it
   completion(data, response, error)
}

上面的细节是如何让完成块在您的示例中工作。建议不要URLSession直接通过完成块;而是处理它。

enum NKError: Error {
  case networkError
}

func gettingAceess(completionBlock: @escaping (Result<[String: Any], NKError>) -> Void ) {
  let logging = URLSession.shared.dataTask(with: loggingUrl) { (data, response, error) in
    if error != nil {
      print("\(String(describing: error))")
      completion(.failure(NKError.networkError))
    }

    // Now I can check for status or data
    if let data = data {
      // parse the result and then return
      if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
        completion(.success(json))
      }
    }
  }
}

在这种情况下,我试图将erroror传递json给调用者。


推荐阅读