Я работаю над приложением в iOS, где мне нужно начать вращение UIActivityIndicatorView, загрузить изображение на сервер, и когда загрузка будет завершена, прекратите вращать индикатор активности.UIActivityIndicatorView не отображается для продолжительности async-задачи
Я сейчас использую XCode 7 Beta и тестирую приложение на iOS-симуляторе как iPhone 6 и iPhone 5. Моя проблема заключается в том, что индикатор активности не заканчивается сразу после загрузки файла, но несколько (~ 28 секунд). Где я должен поместить свои звонки, чтобы он закончился?
У меня есть функция @IBOutlet, прикрепленная к кнопке, которую я использую для запуска процесса, который содержит функцию startAnimating(), и которая вызывает метод dispatch_async, который содержит вызов uploadImage, который содержит сигнал, ожидание и stopAnimating().
Обратите внимание, что
let semaphore = dispatch_semaphore_create(0)
let priority = DISPATCH_QUEUE_PRIORITY_HIGH
определены в верхней части моего класса.
@IBAction func uploadButton(sender: AnyObject) {
self.activityIndicatorView.startAnimating()
dispatch_async(dispatch_get_global_queue(priority, 0)) {
self.uploadImage(self.myImageView.image!)
} // end dispatch_async
} // works with startAnimating() and stopAnimating() in async but not with uploadImage() in async
func uploadImage(image: UIImage) {
let request = self.createRequest(image)
let session : NSURLSession = NSURLSession.sharedSession()
let task : NSURLSessionTask = session.dataTaskWithRequest(request, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.description)
} else {
let httpResponse: NSHTTPURLResponse = response as! NSHTTPURLResponse
if httpResponse.statusCode != 200 {
print(httpResponse.description)
} else {
print("Success! Status code == 200.")
dispatch_semaphore_signal(self.semaphore)
}
}
})! // end dataTaskWithResult
task.resume()
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
self.activityIndicatorView.stopAnimating()
} // end uploadImage
Это всего лишь одна версия моего кода, я переместил несколько вещей несколькими различными способами. Я попытался это:
@IBAction func uploadButton(sender: AnyObject) {
self.activityIndicatorView.startAnimating()
dispatch_async(dispatch_get_global_queue(priority, 0)) {
self.uploadImage(self.myImageView.image!)
dispatch_semaphore_signal(self.semaphore)
} // end dispatch_async
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
self.activityIndicatorView.stopAnimating()
}
И несколько, несколько других способов перемещения моего кода, чтобы попытаться получить индикатор активности для отображения на время загрузки образа, а затем сразу же бросить курить. В некоторых случаях счетчик не появляется вообще на время выполнения программы. Я прочитал this сообщение и this вопрос, и мигрировал мой dispatch_semaphore_wait и stopAnimating() для метода uploadImage(), чтобы обойти это, но не могу найти достаточную информацию в документации UIActivityIndicatorView об обновлении пользовательского интерфейса, чтобы узнать любой другой способ ее обновления, хотя я считаю, что это может быть основной проблемой.
Все, что мне нужно для запуска счетчика, прежде чем процесс загрузки начнется (dataTaskWithRequest) и закончится, как только он сработает или завершится с ошибкой. Что я делаю не так?
Это исправляет проблему, хотя я невероятно расстроен, почему именно семафоры не работают. Есть ли причина в моем коде? – Jthami05
Я не знаю достаточно о семафорах, чтобы ответить на это. Имея ограниченные знания, ваш код выглядит правильно. Но иногда GCD просто облегчает жизнь. – keithbhunter
Я ничего не думаю о том, что код семафора, который вы используете, вызывает вызов 'self.activityIndicatorView.stopAnimating', который должен выполняться в основном потоке. Правильный ответ - решение Кита об использовании 'dispatch_async (disptach_get_main_queue()' (проголосовало) –