我有一个调用API的框架,它返回一个JSON给我。问题是我的SDK中有一个函数,它使用NSURLSession并调用DataTaskWithRequest来获取数据。问题是我的函数甚至在正确获取数据之前返回值。我已经尝试使用具有DataTaskWithRequest的Completion Handler并且当前使用while循环来等待接收数据。还有其他可能的方法吗
代码
public func getDetails() -> AnyObject {
if Reachability.isConnectedToNetwork()
{
received = false
let baseUrl = "API_URL Here"
let url = NSURL(string: baseUrl)
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
print("Starting the connection")
let task = session.dataTaskWithRequest(request, completionHandler : {
(data, response, error ) in
//Proper JSON Form
do
{
self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
}
catch
{
print("Error")
return
}
self.received = true
})
task.resume()
print("Going through the loop")
while(!received)
{
print("Searching")
}
print(JSON)
return JSON
}
else
{
let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
return 0
}
}
答案 0 :(得分:0)
是的,使用另一个线程监视进程并让它通过您的协议发送消息。
newQueue = NSOperationQueue()
let operation2 = NSBlockOperation(block: {
})
operation2.completionBlock = {
print("Operation 2 completed")
}
let operation1 = NSBlockOperation(block: {
})
operation1.completionBlock = {
self.newQueue.addOperation(operation2)
}
operation1.qualityOfService = .UserInitiated
newQueue.addOperation(operation1)
}
以下是代码的概述。简而言之,您将使用块1启动会话,并在完成时使用block2启动下载验证。 block1在完成时[几乎立即按你所说]触发block2,但是在下载了块1中完成的数据结构之前,块2不会触发。
答案 1 :(得分:0)
您的问题是您正在尝试将异步转换为同步的东西。在伪代码中总结一下,你这样做: -
let myData = getDetails(blah)
doSomeAction(myData)
接近它的方法是使用完成块作为指示器本身并使所有内容异步。 此代码尚未经过测试
public typealias CompletionHandler = (success: Bool, message: String, json: JSON?, error: NSError?) -> Void
func getDetailsAsync(completion: CompletionHandler) {
if Reachability.isConnectedToNetwork()
{
received = false
let baseUrl = "API_URL Here"
let url = NSURL(string: baseUrl)
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
print("Starting the connection")
let task = session.dataTaskWithRequest(request, completionHandler : {
(data, response, error ) in
//Proper JSON Form
if error != nil {
completion(false, "error", nil, error)
}
else {
do
{
self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
completion(true, "OK", self.JSON, nil)
}
catch
{
print("Error")
completion(false, "JSON parsing failed", nil, nil)
}
}
})
task.resume()
}
else {
completion(false, "No network", nil, nil)
}
}
这样称呼:
getDetailsAsync() {
(success, message, json, error) in
if success == true {
print(json)
}
else {
// Do your alert here
print(message)
print(error)
}
}
This回答可能会有所帮助。