Подтвердить что ты не робот

Как возобновить загрузку, когда приложение принудительно - выйти?

Мое приложение должно загрузить довольно большой файл (390Mb), Я использую TCBlopDownloadSwift для загрузки (я преобразовал его для swift 2.0, и он отлично работает), и я сделал конфигурацию для загрузки фонового изображения. Я хочу, когда приложение перестанет работать, чтобы возобновить загрузку. Я обнаружил, что когда приложение закрывается, я все еще могу найти загруженные данные в кеше (в "com.apple.nsurlsessiond/Downloads/" + bundleIdentifier) ​​в качестве файла tmp. Но когда я пытаюсь получить данные загрузки с помощью:

func dataInCacheForName (name : String) -> NSData? {
    let PathToCache = (NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.CachesDirectory , .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("com.apple.nsurlsessiond/Downloads/" + bundleIdentifier)
    let path = (PathToCache as NSString).stringByAppendingPathComponent(name)
    let data = NSData(contentsOfFile: path)
    print("data : \(data?.length)")
    return data
}

он возвращает nil, но файл не равен nil. Я могу переместить файл, поэтому я попытался переместить файл в документы. Но если я попытаюсь возобновить загрузку с данными, я получаю ошибки:

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 

Недействительные данные возобновления для загрузки фона. Фоновые загрузки должны использовать http или https и должны загружаться в доступный файл.

и в URLSession

(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?)

error userInfo : Optional([:])

: Optional(Error Domain=NSURLErrorDomain Code=-3003 "(null)")

код ошибки -3003 означает невозможность записи в файл

Я прочитал много сообщений и все же не могу найти ответ

наиболее перспективным было https://forums.developer.apple.com/thread/24770

4b9b3361

Ответ 1

Итак, проблема исходит из библиотеки, я объясняю:

TCBlobDownloadSwift имеет пользовательский делегат, который вызывается в конце метода urlSessionDelegate (например, пользовательский делегат дает значение прогресса вместо totalByteWritten и totalBytesExpectedToWrite).

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    guard let download = self.downloads[downloadTask.taskIdentifier] else{
        return
    }
    let progress = totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown ? -1 : Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
    print("progress : \(progress)")
    // the delegate is in fact called download and has more parameter .
    customDelegate(download , progress : progress)
}

И он отлично работает. Но когда дело доходит до возобновления загрузки, когда приложение перезагружается, загрузка не регистрируется, а downloadTask.taskIdentifier возвращает ноль, поэтому пользовательский делегат не вызывается!!

Чтобы возобновить загрузку после принудительного закрытия, вы должны использовать этот код (метод вызывается, когда объект, следующий за протоколом NSURLSessionDelegate) был создан:

public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) {
    if let error = sessionError {
    print("error : \(error)")
    let directory = NSURL(fileURLWithPath: fileManage.Path)
    if let resumedData = error.userInfo[NSURLSessionDownloadTaskResumeData] as? NSData {
        let url = error.userInfo[NSURLErrorFailingURLStringErrorKey] as? String
        // get name from url just read a dictionnary of name and url
        let name = getNameFromURL(url!) 
        // start the download
        self.manager.downloadFileWithResumeData(resumedData, toDirectory: directory , withName: name, andDelegate: self)
        }
    }
}

Мне пришлось уничтожить библиотеку (она не позволяет возобновить загрузку, если приложение force-Quit)

TL;DR

Если вы используете библиотеку с пользовательским делегатом (один отличается от NSURLSessionDelegate), проблема может возникнуть у пользовательского делегата, который не вызывает метод URLSession (session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) method

PS: Спасибо за ответ, который я понимаю. Как вводить в заблуждение мой пост.

Я попытаюсь (если у меня есть время) работать над каркасом, который может возобновить загрузку после приложения. -Открыть (выглядит просто, на самом деле вам просто нужно добавить метод делегирования для этого конкретного случая, но если это сложнее, у меня нет времени, но, возможно, позже)