一尘不染

如何从Alamofire回报价值

swift

我正在通过使用swift创建的API进行URL调用,如下所示:

class API {

  let apiEndPoint = "endpoint"
  let apiUrl:String!
  let consumerKey:String!
  let consumerSecret:String!

  var returnData = [:]

  init(){
    self.apiUrl = "https://myurl.com/"
    self.consumerKey = "my consumer key"
    self.consumerSecret = "my consumer secret"
  }

  func getOrders() -> NSDictionary{
    return makeCall("orders")
  }

  func makeCall(section:String) -> NSDictionary{

    let params = ["consumer_key":"key", "consumer_secret":"secret"]

    Alamofire.request(.GET, "\(self.apiUrl)/\(self.apiEndPoint + section)", parameters: params)
        .authenticate(user: self.consumerKey, password: self.consumerSecret)
        .responseJSON { (request, response, data, error) -> Void in
            println("error \(request)")
            self.returnData = data! as NSDictionary
    }
    return self.returnData
  }

}

我在我调用此API时UITableViewController使用SwiftyJSON库填充表。但是,我returnData的API始终为空。Alomofire调用没有问题,因为我可以成功检索值。我的问题是我应该如何将其data转移到表视图控制器?

var api = API()
api.getOrders()
println(api.returnData) // returnData is empty

阅读 253

收藏
2020-07-07

共1个答案

一尘不染

正如mattt指出的那样,Alamofire通过“完成处理程序”模式异步返回数据,因此您必须执行相同的操作。您不能只是return立即获取值,而是要更改方法以不返回任何内容,而要使用完成处理程序关闭模式。

如今,它可能看起来像:

func getOrders(completionHandler: @escaping (Result<[String: Any]>) -> Void) {
    performRequest("orders", completion: completionHandler)
}

func performRequest(_ section: String, completion: @escaping (Result<[String: Any]>) -> Void) {
    let url = baseURL.appendingPathComponent(section)
    let params = ["consumer_key": "key", "consumer_secret": "secret"]

    Alamofire.request(url, parameters: params)
        .authenticate(user: consumerKey, password: consumerSecret)
        .responseJSON { response in
            switch response.result {
            case .success(let value as [String: Any]):
                completion(.success(value))

            case .failure(let error):
                completion(.failure(error))

            default:
                fatalError("received non-dictionary JSON response")
            }
    }
}

Then, when you want to call it, you use this completion closure parameter
(in trailing closure, if you want):

api.getOrders { result in
    switch result {
    case .failure(let error):
        print(error)

    case .success(let value):
        // use `value` here
    }
}

// but don't try to use the `error` or `value`, as the above closure
// has not yet been called
//
2020-07-07