Я использую API Twitter для получения списка твитов. Метод должен возвращать список твитов, но проблема в том, что он возвращается до завершения запроса, что приводит к возврату пустого списка. Как это исправить? Вот исходный код метода:Функция возвращается до завершения асинхронного запроса
// Call to search through twitter with a query
func searchQuery(query: String) -> [Tweet] {
var tweets: [Tweet] = []
var query_URL = query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
if let query_URL = query_URL {
TwitterClient.sharedInstance.GET("https://api.twitter.com/1.1/search/tweets.json?q=\(query_URL)", parameters: nil, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
tweets = parseJSON(response)
println(tweets.count)
}, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
})
}
println("ret: \(tweets.count)")
return tweets
}
В приведенном выше коде, результат будет
ret: 0
15
Я попытался с помощью отправки группы, но я не мог заставить их работать. Вот что я сделал с GCD:
// Call to search through twitter with a query
func searchQuery(query: String) -> [Tweet] {
var tweets: [Tweet] = []
var query_URL = query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
var group = dispatch_group_create()
if let query_URL = query_URL {
dispatch_group_enter(group)
TwitterClient.sharedInstance.GET("https://api.twitter.com/1.1/search/tweets.json?q=\(query_URL)", parameters: nil, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
tweets = parseJSON(response)
dispatch_group_leave(group)
}, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
dispatch_group_leave(group)
})
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
return tweets
}
Но этот код, кажется, ждет вечно.
Для справки, Tweet
- это структура для сохранения данных, относящихся к твиту. Я использую его для перемещения большого количества данных более компактным образом. parseJSON заполняет и возвращает массив твитов, основанный на ответе JSON. В идеале этот возвращенный массив будет сохранен в tweets
, который затем должен вернуться из метода, но этого не произойдет.
Любые идеи или методы для преодоления этого будут высоко оценены!
Редактировать: @Hamza Ансари Вот фактическая функция:
// Call to search through twitter with a query
func searchQuery(query: String, completionHandler:(returntweets: [Tweet]) -> Void) {
var query_URL = query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
if let query_URL = query_URL {
TwitterClient.sharedInstance.GET("https://api.twitter.com/1.1/search/tweets.json?q=\(query_URL)", parameters: nil, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
var tweets:[Tweet] = parseJSON(response)
println("size in method: \(tweets.count)")
completionHandler(returntweets: tweets)
}, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
})
}
}
Но при вызове в другой метод, используемый для инициализации источника данных:
// Initializes the data source
func initialize(query: String) {
self.query = query
searchQuery(query, { (returnTweets) -> Void in
self.searches = returnTweets
})
println("size when called: \(searches.count)")
}
Выход (в по заказу):
size when called: 0
size in method: 15
Посмотрите на аналогичный вопрос, заданный вчера: http://stackoverflow.com/questions/31794542/ios-swift-function-that-returns-asynchronously-retrieved-value – vadian
Вот подсказка: метод GET что вы используете для извлечения твитов, делает именно это (асинхронная выборка некоторых данных), вы можете smd + щелкнуть по нему и получить представление о том, как это работает. Также обратите внимание, что асинхронные функции (почти) никогда не возвращают что-то (в конце концов, это идея асинхронности) – Alladinian
Вам нужно вызвать какой-то метод из закрытия, чтобы обработать полученные твиты. – Paulw11