Отмените загрузку файла Alamofire, если этот файл уже существует
Как отменить запрос Alamofire, если загруженный файл уже существует в папке с документами?
Вот код для запроса:
Alamofire.download(.GET, fileUrls[button.tag], destination: { (temporaryURL, response) in
if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
let fileURL = directoryURL.URLByAppendingPathComponent(response.suggestedFilename!)
self.localFilePaths[button.tag] = fileURL
if NSFileManager.defaultManager().fileExistsAtPath(fileURL.path!) {
NSFileManager.defaultManager().removeItemAtPath(fileURL.path!, error: nil)
}
return fileURL
}
println("temporaryURL - \(temporaryURL)")
self.localFilePaths[button.tag] = temporaryURL
return temporaryURL
}).progress { _, totalBytesRead, totalBytesExpectedToRead in
println("\(totalBytesRead) - \(totalBytesExpectedToRead)")
dispatch_async(dispatch_get_main_queue()) {
self.progressBar.setProgress(Float(totalBytesRead) / Float(totalBytesExpectedToRead), animated: true)
if totalBytesRead == totalBytesExpectedToRead {
self.progressBar.hidden = true
self.progressBar.setProgress(0, animated: false)
}
}
}.response { (_, _, data, error) in
let previewQL = QLReaderViewController()
previewQL.dataSource = self
previewQL.currentPreviewItemIndex = button.tag
self.navigationController?.pushViewController(previewQL, animated: true)
}
Я также пытался создать переменную запроса var request: Alamofire.Request?
а затем отменить request?.cancel()
это если этот файл существует, но он не работает.
Может кто-нибудь помочь мне решить эту проблему?
2 ответа
Вместо того, чтобы отменить запрос, IMO, вы не должны делать это в первую очередь. Вы должны выполнить проверку файла ДО того, как вы запустите запрос Alamofire.
Если вы абсолютно уверены, что вам нужно запустить запрос, вы всегда можете отменить его сразу после запуска.
var shouldCancel = false
let request = Alamofire.request(.GET, "some_url") { _, _ in
shouldCancel = true
}
.progress { _, _, _ in
// todo...
}
.response { _, _, _ in
// todo...
}
if shouldCancel {
request.cancel()
}
TL; Д.Р.: Отмена запроса во многих случаях немного обременительна. Даже Alamofire, насколько я знаю, не гарантирует, что запрос будет отменен по вашему запросу, немедленно. Тем не менее, вы можете использовать dispatch_suspend
или же NSOperation
чтобы преодолеть это.
Большая Центральная Диспетчерская (GCD)
Этот способ использует функциональное программирование.
Здесь мы освещаем наш путь с низкоуровневым программированием. Apple представила хорошую библиотеку, известную как GCD, для программирования на уровне потоков.
Вы не можете отменить блок, если... вы не приостанавливаете очередь (если она не является основной или глобальной очередью).
Существует функция C под названием dispatch_suspend
(из справочника Apple по GCD)
void dispatch_suspend(dispatch_object_t object);
Приостанавливает вызов блочных объектов для объекта отправки.
И вы также можете создавать очереди (кто dispatch_object_t
с) с dispatch_queue_create
,
Таким образом, вы можете выполнять свою задачу в созданной пользователем очереди, и вы можете приостановить эту очередь, чтобы процессор не делал ненужных действий.
NSOperation (также NSThread)
Этот способ использует функциональное программирование через объектно-ориентированный интерфейс.
Apple также представила NSOperation
где объектно-ориентированное программирование может быть объектным, тогда как с ним легче справиться.
NSOperation
является абстрактным классом, который связывает код и данные, согласно документации Apple.
Чтобы использовать этот класс, вы должны либо использовать один из его определенных подклассов, либо создать свой собственный подкласс: особенно в вашем случае, я полагаю, NSBlockOperation
единственный.
Вы можете обратиться к этому блоку кода:
let block = NSBlockOperation { () -> Void in
// do something here...
}
// Cancel operation
block.cancel()
Тем не менее, это также не гарантирует прекращение того, что он делает. Apple также заявляет, что:
Этот метод не заставляет ваш код операции останавливаться. Вместо этого он обновляет внутренние флаги объекта, чтобы отразить изменение состояния. Если операция уже завершена, этот метод не имеет никакого эффекта. Отмена операции, которая в данный момент находится в очереди операций, но еще не выполняется, позволяет удалить операцию из очереди раньше, чем обычно.
Если вы хотите воспользоваться флагами, вам следует прочитать больше: Ответ на команду отмены