我有一个查询某个用户的函数,以便访问该用户的数组。我返回用户,我可以访问他们的数组。但是,调用是异步的,返回的是nil。 all上的函数有一个完成处理程序,但是,里面有一个查询调用,默认情况下该查询返回Void。
func _getAllMatches(completionHandler: ((UIBackgroundFetchResult) -> Void)!) -> Int{
var toReturn = [GTLUserUser]()
let query = GTLQueryUser.queryForUserList()
query.userBucket = "messages-20-messagestabletes-1465782960"
service.executeQuery(query, completionHandler: {(ticket, response, error) -> Void in
if error != nil{
self._showErrorDialog(error)
return
}
else{
let userCollection = response as! GTLUserCollection
if let newUsers = userCollection.items() as? [GTLUserUser]{
toReturn = newUsers
completionHandler(UIBackgroundFetchResult.NewData)
}
}
})
return toReturn[0].likedArray.count
}
如何等待此查询返回并分配给“toReturn”,以便它实际返回一些内容而不是返回任何内容。
答案 0 :(得分:1)
由于它是一个异步方法,因此您无法返回该值,而是遵循完成处理程序模式,包括作为参数返回的数据:
func performAllMatchesQueryWithCompletionHandler(completionHandler: (UIBackgroundFetchResult, [GTLUserUser]?, ErrorType?) -> ()) {
let query = GTLQueryUser.queryForUserList()
query.userBucket = "messages-20-messagestabletes-1465782960"
service.executeQuery(query) { ticket, response, error in
guard error == nil else {
completionHandler(.Failed, nil, error)
return
}
if let userCollection = response as? GTLUserCollection, let newUsers = userCollection.items() as? [GTLUserUser] {
completionHandler(.NewData, newUsers, nil)
} else {
completionHandler(.NoData, nil, nil)
}
}
}
我从您使用UIBackgroundFetchResult
推断出您正在进行后台提取。如果是这样,您的performFetchWithCompletionHandler
可能会如此:
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
performAllMatchesQueryWithCompletionHandler { fetchResult, users, error in
switch fetchResult {
case .Failed:
// do whatever you want if there was an error
case .NoData:
// do whatever you want when there is no data
case .NewData:
// do whatever you want with `users`, presumably updating your model or what have you
}
completionHandler(fetchResult)
}
}
然后,您可以从viewDidLoad
或适用于您应用的任何地方调用此方法。
注意,我删除了方法名称的前导下划线,因为它不是Swift中的常用约定,但是无论你想要什么,都可以调用你的方法。我将_getAllMatches
重命名为performAllMatchesQueryWithCompletionHandler
,因为它更清楚地表明您正在执行异步查询。
在评论中,您说您没有进行后台获取,而是填充表格。所以你可以这样做:
func retrieveDataForTableView(tableView: UITableView) {
performAllMatchesQueryWithCompletionHandler { fetchResult, users, error in
switch fetchResult {
case .Failed:
// do whatever you want if there was an error
case .NoData:
// do whatever you want when there is no data
case .NewData:
// do whatever you want with `users`, presumably updating your model or what have you
// once you've updated your model, you can reload the table:
tableView.reloadData() }
}
}
注意,我假设此完成处理程序正在主线程上运行。如果没有,您需要dispatch_async(dispatch_get_main_queue()) { ... }
更新模型的代码并调用reloadData
。
就个人而言,如果我没有真正进行背景提取,我不会倾向于UIBackgroundFetchResult
用于我的performAllMatchesQueryWithCompletionHandler
。我可能会使用自己的枚举,以避免对此代码的意图产生任何混淆。
答案 1 :(得分:0)
您可以添加中间completionHandler。这样清洁。这里只是一个例子:
func application(application: UIApplication!, performFetchWithCompletionHandler completionHandler: ((UIBackgroundFetchResult) -> Void)!) {
Use_it_here() {
completionHandler(UIBackgroundFetchResult.NewData)
println("Background Fetch Complete")
}
}
func Use_it_here(completionHandler: (() -> Void)!) {
//....
//DO IT
//....
completionHandler()
}
答案 2 :(得分:0)
因为我试图将数据查询到tableview,我的解决方案是查询数据,然后只需重新加载数据。非常简单,无需完成处理程序
func getMathces(){
let query = GTLQueryUser.queryForUserList()
query.userBucket = "bucketname"
service.executeQuery(query, completionHandler: {(ticket, response, error) -> Void in
if error != nil{
self._showErrorDialog(error)
return
}
else{
let userCollection = response as! GTLUserCollection
if let newUsers = userCollection.items() as? [GTLUserUser]{
for mat in newUsers[0].likedArray{
let name: String = (mat as? String)!
self.matches.append(name)
}
}
}
self.tableView.reloadData()
})
}