Отмените загрузку файла 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 также заявляет, что:

Этот метод не заставляет ваш код операции останавливаться. Вместо этого он обновляет внутренние флаги объекта, чтобы отразить изменение состояния. Если операция уже завершена, этот метод не имеет никакого эффекта. Отмена операции, которая в данный момент находится в очереди операций, но еще не выполняется, позволяет удалить операцию из очереди раньше, чем обычно.

Если вы хотите воспользоваться флагами, вам следует прочитать больше: Ответ на команду отмены

Другие вопросы по тегам