完成处理程序swift 3从函数返回一个variables

在swift 3中,我很困惑周围的完成处理程序的语法。

在下面的函数中,从Web服务调用中parsingxml文件后,它应该返回一个variables(一个array [String:String] )。
我的尝试是在下面,但显然这是不正确的。

  enum HistoryKey { case success([String:String]) case failure(String) } private func getHistoryKeys(searchterm: String, completion: @escaping () -> HistoryKey) { let url = PubmedAPI.createEsearchURL(searchString: searchterm) let request = URLRequest.init(url: url as URL) let task = session.dataTask(with: request) { (data, response, error) in if let theData = data{ let myParser = XMLParser.init(data: theData) myParser.delegate = self myParser.parse() } } task.resume() if keys.isEmpty { return .failure("no historyKeyDictionary") }else{ return .success(keys) } }// End of func 

我想要使​​用这个function如下

  let result = self.getHistoryKeys(searchTerm) 

两个问题:

  • 完成处理程序传递一个HistoryKey实例并且没有返回值,所以签名必须是相反的。
  • 完成处理程序的调用必须位于数据任务的完成块内。

为了能够在完成块之外parsing接收到的数据,返回成功的data

 enum ConnectionResult { case success(Data) case failure(Error) } private func getHistoryKeys(searchterm: String, completion: @escaping (ConnectionResult) -> ()) { let url = PubmedAPI.createEsearchURL(searchString: searchterm) let task = session.dataTask(with: url) { (data, response, error) in if let error = error { completion(.failure(error)) } else { completion(.success(data!)) } } task.resume() } 

并称之为

 getHistoryKeys(searchterm: String) { connectionResult in switch connectionResult { case .success(let data): let myParser = XMLParser(data: data) myParser.delegate = self myParser.parse() // get the parsed data from the delegate methods case .failure(let error): print(error) } } 

你没有使用completion块。
像这样使用它:

 private func getHistoryKeys(searchterm: String, completion: @escaping (_ keys: Array) -> Void) { //do the magic completion(keys) } 

那么你可以调用这个函数:

 getHistoryKeys(searchterm: "str") { (keys) in print("\(keys)") } 
  enum HistoryKey { case success([String: String]) case failure(String) } private func getHistoryKeys(searchterm: String, completion: @escaping (_ result: HistoryKey) -> Void) { let url = PubmedAPI.createEsearchURL(searchString: searchterm) let request = URLRequest.init(url: url as URL) let task = session.dataTask(with: request) { (data, response, error) in if let theData = data{ let myParser = XMLParser.init(data: theData) myParser.delegate = self myParser.parse() } if keys.isEmpty { completion(.failure("no historyKeyDictionary")) } else { completion(.success(keys)) } } task.resume() } // End of func 

就是这样 更改@escaping声明并做一个完成而不是返回。

希望能帮助到你。

从我所看到的,应该是

 private func getHistoryKeys(searchterm: String, completion: @escaping (HistoryKey) -> ()) 

也应该使用completion(.failure("no historyKeyDictionary"))completion(.success(keys))而不是return

在完成处理程序中返回结果作为参数:

 private func getHistoryKeys(searchterm: String, completion: @escaping (result: HistoryKey) -> Void) { let url = PubmedAPI.createEsearchURL(searchString: searchterm) let request = URLRequest.init(url: url as URL) let task = session.dataTask(with: request) { (data, response, error) in if let theData = data{ let myParser = XMLParser.init(data: theData) myParser.delegate = self myParser.parse() } //DispatchQueue.main.async { // if you want to do UI stuff dispatch calls to completion() on the main queue if keys.isEmpty { completion(.failure("no historyKeyDictionary")) } else{ completion(.success(keys)) } //} } task.resume() } 

并像这样调用它:

 getHistoryKeys("searchMe") { (result: HistoryKey) in print(result) }