我正在创建一个非常基本的应用程序,它有一个搜索字段来获取传递给tableview的数据。
我想要做的是运行异步任务来获取数据,如果成功获取数据,则转到下一个视图,在加载期间,屏幕不得冻结这就是为什么需要异步部分。
当用户按下搜索按钮时,我运行以下代码以获取我的
中的数据override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
方法
var valid = true
let searchValue = searchField.text
let session = NSURLSession.sharedSession()
let url = NSURL(string: "https://someapi.com/search?query=" + searchValue!)
let task = session.dataTaskWithURL(url!, completionHandler: {(data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
if let theData = data {
dispatch_async(dispatch_get_main_queue(), {
//for the example a print is enough, later this will be replaced with a json parser
print(NSString(data: theData, encoding: NSUTF8StringEncoding) as! String)
})
}
else
{
valid = false;
print("something went wrong");
}
})
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
task.resume()
return valid;
我删除了一些检查连接/更改文本的代码,以显示应用程序正在加载数据以使代码更具可读性。 这是我遇到问题的部分,在所有检查之后,我确定在这部分我有连接等。
它会返回true(我可以看到这是因为视图已加载),但也会记录"出错了"来自else声明。
我理解这是因为返回有效(在最后一行)在valid设置为false之前返回有效。 如果成功获取数据,我怎么才能返回true(更改视图),如果出现错误则不显示下一个视图?
答案 0 :(得分:1)
因为您希望数据提取是异步的,所以不能返回值,因为返回值是sync(当前线程必须等到函数返回然后使用该值)。你想要的是使用回调。因此,在获取数据时,您可以执行操作。为此,您可以使用闭包,因此您的方法将是:
func shouldPerformSegue(identifier: String, sender: AnyObject?, completion:(success:Bool) -> ());
只需在completion(true)
块中调用completion(false)
或session.dataTaskWithURL
,具体取决于是否成功,当您调用函数时,为completion
添加一个块您可以根据success
参数执行或不执行segue。这意味着您无法override
该方法可以满足您的需求,您必须实现自己的机制。