从完成处理程序返回值

时间:2016-05-22 18:56:14

标签: swift

我想从api调用中返回值。

调用我的api类(我想获取res中的值):

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let t = Api_test();
        let res = t.getSomething();

        print(res)
    }
}

api课程:

import Foundation

class Api_test {

     func getAllStations(completionHandler: (response : XMLIndexer) -> ()) {

    getRequest { result in
        completionHandler(response: SWXMLHash.parse(result))
    };
}

    func getRequest(completionHandler: (result: NSData) -> ()) {
        let baseUrl = "http://api.test.com"
        let request = NSMutableURLRequest(URL: NSURL(string: baseUrl)!)
        let session = NSURLSession.sharedSession()
        request.HTTPMethod = "GET"

        let task = session.dataTaskWithRequest(request) {
            (data, response, error) in

            if data == nil {
                print("dataTaskWithRequest error: \(error)")
                return
            } else {
                completionHandler(result: data!)
            }
        }
        task.resume()
    }
}

一切都按照思想运作,但我仍然坚持将值返回给getSomething函数。数据采用xml格式。如何在res(viewDidLoad)中将结果集作为返回值?

1 个答案:

答案 0 :(得分:3)

NSURLSession是一个完全异步的网络API,理想情况下,您的视图控制器应该正常运行,而不是等待从网络返回数据。

这里有三个选项:

  1. 您可以将完成块传递给getSomething并将结果传递给块:

    func getSomething(completionHandler: (result: XMLIndexer) -> ()) {
      getRequest { result in
        completionHandler(result: SWXMLHash.parse(result))
      }
    }
    
    override func viewDidLoad() {
      ...
      t.getSomething { res in
        print(res)
      }
    }
    
  2. 如果您在视图显示到屏幕上之前迫切需要手头的XML数据,您可以让主线程等到网络操作完成执行。您可以使用dispatch_semaphore_t

    func getSomething() -> XMLIndexer? {
      var xml: XMLIndexer? = nil
      let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
      getRequest { result in
        xml = SWXMLHash.parse(result)
        dispatch_semaphore_signal(semaphore)
      }
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
      return xml
    }
    
  3. 最后一个选项是,您可以使用另一个同步进行解析的第三方。有一个很棒的名为Ono

    var error: NSError?
    let xml = ONOXMLDocument(data: result, error: &error)