Swift 从完成处理程序返回值
我想从api调用返回值 调用我的api类(我想获取res中的值): api类:Swift 从完成处理程序返回值,swift,Swift,我想从api调用返回值 调用我的api类(我想获取res中的值): api类: import Foundation class Api_test { func getAllStations(completionHandler: (response : XMLIndexer) -> ()) { getRequest { result in completionHandler(response: SWXMLHash.parse(result))
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)中的返回值获取?
NSURLSession
是一个完全异步的网络API,因此理想情况下,视图控制器应该正确运行,而不是等待数据从网络返回
这里有三个选项:
getSomething
,并让它将结果传递给块:
func getSomething(completionHandler: (result: XMLIndexer) -> ()) {
getRequest { result in
completionHandler(result: SWXMLHash.parse(result))
}
}
override func viewDidLoad() {
...
t.getSomething { res in
print(res)
}
}
是否要使整个程序等待从
getRequest
函数获得响应?将完成闭包传递给getSomething
?然后可以在getResult
的完成处理程序中调用它。@ozgur是,因为程序需要数据。或者我应该在另一个线程上运行整个类?@originaluser2如何执行该操作?@da1lbi3让您的getSomething
执行(whateverTypeYourDataIs)->()
闭包,并从getRequest
完成闭包中调用它。与您使用getRequest
执行的操作完全相同。作为一般规则,您不应该让您的程序等待某些东西,除非它真的必须等待,即使如此,它也不应该在主线程上等待。虽然根据你告诉我们的情况很难给出建议,但你能提供一点关于你在这里实际要做什么的背景吗?我完全同意这个答案。。。方法2除外。你真的不应该在主线程上等待。从编程和用户体验的角度来看,这都不是一个好主意。我强烈建议只做一个异步请求,并在加载时向用户显示一条加载消息(可以在视图上显示)。这样用户就不会惊慌失措,认为应用程序只是冻结了。我知道,这就是为什么我说理想情况下视图控制器应该正确运行,直到数据从网络返回。我只是告诉他有办法,而不是告诉他应该这么做。啊,好吧,略过你的第一段,我的错!尽管现在确实在考虑它,dispatch\u sync
无论如何都不会等待请求完成,因为getResult
方法本身是异步的。你必须使用信号灯,尽管同样的健康警告仍然适用。是的,你完全正确。我将相应地更新我的代码。我完全忽略了一个事实,即getRequest将立即在分派块中返回。那里需要信号量或调度组。谢谢你发现了!
func getSomething(completionHandler: (result: XMLIndexer) -> ()) {
getRequest { result in
completionHandler(result: SWXMLHash.parse(result))
}
}
override func viewDidLoad() {
...
t.getSomething { res in
print(res)
}
}
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
}
var error: NSError?
let xml = ONOXMLDocument(data: result, error: &error)