ios - Cómo reanudar una descarga cuando la aplicación se cierra?
download resume (1)
Bien, entonces, el problema proviene de la biblioteca, les explico:
TCBlobDownloadSwift tiene un delegado personalizado, que se llama al final del método urlSessionDelegate (por ejemplo, el delegado personalizado da un valor de progreso en lugar de totalByteWritten y 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)
}
y funciona bien Pero cuando se trata de reanudar una descarga cuando la aplicación se reinicia, la descarga no se registra y el downloadTask.taskIdentifier devuelve nulo para que no se llame al delegado personalizado.
Para reanudar una descarga después de un cierre forzado, debe usar este código (se llama al método cuando se ha creado el objeto que sigue al protocolo 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)
}
}
}
Tuve que destruir la biblioteca (su estructura no permite reanudar la descarga si la aplicación se cierra forzosamente)
TLDR
Si utiliza una biblioteca con un delegado personalizado (uno diferente de NSURLSessionDelegate), el problema podría provenir del delegado personalizado que no llame al método URLSession (session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?)
PD: Gracias por la respuesta que entiendo. ¿Qué tan confuso es mi publicación?
Trataré (si tengo tiempo) de trabajar en un marco que permita reanudar una descarga después de que la aplicación abandone (parece simple, de hecho, solo tiene que agregar un método de delegado para ese caso en particular, pero si es más complicado, aún no tengo tiempo, tal vez más tarde)
Mi aplicación tiene que descargar un archivo bastante grande (390Mb), estoy usando TCBlopDownloadSwift para la descarga (lo convertí para swift 2.0 y funciona bien) e hice las configuraciones para una descarga en segundo plano. Quiero, cuando la fuerza de la aplicación deje de poder reanudar la descarga. Descubrí que cuando la aplicación se cerró todavía puedo encontrar los datos descargados en la caché (en "com.apple.nsurlsessiond / Downloads /" + bundleIdentifier) como un archivo tmp. Pero cuando trato de obtener los datos de la descarga usando:
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
}
devuelve nil, pero el archivo no es nulo. Puedo mover el archivo, así que traté de mover el archivo en los Documentos. Pero si intento reanudar la descarga con los datos, obtengo errores:
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
Datos de currículum víridos para la descarga de fondo. Las descargas en segundo plano deben usar http o https y deben descargarse a un archivo accesible.
y en la URLSesión
(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?)
error userInfo : Optional([:])
: Optional(Error Domain=NSURLErrorDomain Code=-3003 "(null)")
código de error -3003 significa imposible escribir en el archivo
He leído muchas publicaciones y todavía no puedo encontrar una respuesta
el más prometedor fue https://forums.developer.apple.com/thread/24770