objective - alamofireobjectmapper
Método Alamofire.download(): ¿Dónde está el archivo y se guardó correctamente? (5)
Aquí está el método completo para descargar el archivo en diferentes destinos con el progreso
// MARK: Métodos de descarga
func downloadFile(reqType : RequestType, urlParam: String,completionHandler: (Double?, NSError?) -> Void) {
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
var downloadPath = documentsPath.URLByAppendingPathComponent("downloads")
var isDirectory: ObjCBool = false
if NSFileManager.defaultManager().fileExistsAtPath(downloadPath.path!, isDirectory: &isDirectory) {
if(!isDirectory){
do {
try NSFileManager.defaultManager().createDirectoryAtPath(downloadPath.path!, withIntermediateDirectories: true, attributes: nil)
}catch {
NSLog("Unable to create directory ")
}
}
}else{
do {
try NSFileManager.defaultManager().createDirectoryAtPath(downloadPath.path!, withIntermediateDirectories: true, attributes: nil)
}catch {
NSLog("Unable to create directory ")
}
}
//get the url from GTM
let urlString = self.getRequestedUrlFromIdentifier(reqType, param: urlParam)
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)
Alamofire.download(.GET, urlString, destination: { (temporaryURL, response) in
let pathComponent = response.suggestedFilename
downloadPath = downloadPath.URLByAppendingPathComponent(pathComponent!)
if NSFileManager.defaultManager().fileExistsAtPath(downloadPath.path!) {
do{
try NSFileManager.defaultManager().removeItemAtPath(downloadPath.path!)
}catch {
}
}
return downloadPath
}) .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print(totalBytesRead)
// This closure is NOT called on the main queue for performance
// reasons. To update your ui, dispatch to the main queue.
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes read on main queue: /(totalBytesRead)")
}
}
.response { request, response, _, error in
print(response)
let originalPath = destination(NSURL(string: "")!, response!)
if let error = error {
completionHandler(500000.1 , nil)
print("Failed with error: /(error)")
} else {
completionHandler(500000.0 , nil)
print("Downloaded file successfully /(downloadPath)")
}
}
}
El ejemplo para usar Alamofire.download () funciona bien, pero no hay ningún detalle sobre cómo acceder al archivo descargado resultante. Puedo averiguar dónde está el archivo y su nombre según el destino que configuré y la solicitud de archivo original que hice, pero supongo que hay un valor al que debería poder acceder para obtener la ruta de descarga final completa y Nombre del archivo en la respuesta.
¿Cómo accedo al nombre del archivo y cómo sé si se guardó correctamente? Puedo ver los métodos de delegado en el código real de Alamofire que parecen manejar las llamadas de finalización de delegado para el proceso de descarga, pero ¿cómo puedo / puedo acceder a los detalles del archivo en el bloque de respuestas?
El ejemplo en el archivo readme de Alamofire en realidad tiene la ruta del archivo, así que lo tomo con una variable separada para usar en otro lugar en mi código. No es muy elegante y espero que haya una manera de obtener esa información en la respuesta, pero por ahora, esto es hacer el trabajo:
var fileName: String?
var finalPath: NSURL?
Alamofire.download(.GET, urlToCall, { (temporaryURL, response) in
if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
fileName = response.suggestedFilename!
finalPath = directoryURL.URLByAppendingPathComponent(fileName!)
return finalPath!
}
return temporaryURL
})
.response { (request, response, data, error) in
if error != nil {
println("REQUEST: /(request)")
println("RESPONSE: /(response)")
}
if finalPath != nil {
doSomethingWithTheFile(finalPath!, fileName: fileName!)
}
}
Pasé unas 8 horas buscando una respuesta a esta. La solución a continuación funciona para mí, y básicamente lo encadeno al método de descarga para mostrar la imagen. En el siguiente ejemplo, estoy descargando la imagen de perfil de un usuario que conoce su ID de Facebook:
let imageURL = "http://graph.facebook.com//(FBId!)/picture?type=large"
let destination: (NSURL, NSHTTPURLResponse) -> (NSURL) = {
(temporaryURL, response) in
if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
var localImageURL = directoryURL.URLByAppendingPathComponent("/(self.FBId!)./(response.suggestedFilename!)")
return localImageURL
}
return temporaryURL
}
Alamofire.download(.GET, imageURL, destination).response(){
(_, _, data, _) in
if let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as? NSURL {
var error: NSError?
let urls = NSFileManager.defaultManager().contentsOfDirectoryAtURL(directoryURL, includingPropertiesForKeys: nil, options: nil, error: &error)
if error == nil {
let downloadedPhotoURLs = urls as! [NSURL]
let imagePath = downloadedPhotoURLs[0] // assuming it''s the first file
let data = NSData(contentsOfURL: imagePath)
self.viewProfileImage?.image = UIImage(data: data!)
}
}
}
Swift 2.1 y un poco más sencillo:
var localPath: NSURL?
Alamofire.download(.GET,
"http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v",
destination: { (temporaryURL, response) in
let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let pathComponent = response.suggestedFilename
localPath = directoryURL.URLByAppendingPathComponent(pathComponent!)
return localPath!
})
.response { (request, response, _, error) in
print(response)
print("Downloaded file to /(localPath!)")
}
Aún es difícil entender por qué están usando cierres para establecer la ruta de destino ...
Esta respuesta de un miembro de Alamofire parece ser la mejor respuesta:
let destination = Alamofire.Request.suggestedDownloadDestination(
directory: .CachesDirectory,
domain: .UserDomainMask
)
Alamofire.download(.GET, "http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf", destination: destination)
.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print(totalBytesRead)
}
.response { request, response, _, error in
print(response)
print("fileURL: /(destination(NSURL(string: "")!, response))")
}