2015-12-07 6 views
10

Мое приложение должно загрузить довольно большой файл (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 
} 

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

-[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

+1

Почему вы просто не используете NSURLSession и не загружаете файл в фоновое задание? – Lefteris

+0

Я загружаю файл в качестве фоновой задачи, я хочу, чтобы приложение принудительно завершило загрузку: если пользователь перезагрузит приложение, возобновите загрузку там, где он остановился, с данными, сохраненными в кеше – kholl

+3

Если вы настроили фоновая задача NSURLSession, загрузка осуществляется операционной системой, а не вашим приложением. Ваше приложение может прекратить/сбой, но загрузка не прекратится. – Lefteris

ответ

3

Хорошо, проблема возникла из библиотеки, я объясняю:

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) 
     } 
    } 
} 

Я должен был уничтожить библиотека (это структура не позволяет возобновить загрузку, если приложение принудительно Quit)

TLDR

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

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

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