2014-10-10 6 views
21

L'esempio per l'utilizzo di Alamofire.download() funziona perfettamente, ma non vi sono dettagli su come accedere al file scaricato risultante. Posso capire dove si trova il file e come è stato chiamato in base alla destinazione che ho impostato e alla richiesta di file originale che ho creato, ma suppongo che ci sia un valore a cui dovrei essere in grado di accedere per ottenere il percorso di download finale completo e nome del file nella risposta.Metodo Alamofire.download(): dove si trova il file e salvato con successo?

Come accedere al nome del file e come faccio a sapere se è stato salvato correttamente? Riesco a vedere i metodi delegati nell'attuale codice Alamofire che sembra gestire le chiamate di completamento delegate per il processo di download, ma come posso/posso accedere ai dettagli del file nel blocco .response?

+0

Stavo per fare la stessa domanda come ho lo stesso problema in questo momento! – dburgmann

risposta

13

L'esempio sul file Leggimi di Alamofire contiene effettivamente il percorso del file, quindi lo prendo con una variabile separata da utilizzare altrove nel mio codice. Non è molto elegante e spero ci sia un modo per ottenere queste informazioni nella risposta, ma per ora, questo è sempre il lavoro fatto:

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!) 
     } 
} 
+1

non è possibile accedere alla variabile finalPath o fileName da lì – Gabox

+1

Se si desidera accedere a finalPath o fileName nella chiusura, è necessario modificare la chiamata di download in "Alamofire.download (.GET, urlToCall, {[self debole] (temporaryURL, risposta) in " Quindi è possibile fare riferimento a self.fileName e self.finalPath senza causare un ciclo di conservazione. Inoltre, è necessario inserire questo codice in una classe istanziata in un punto in cui non verrà interrotta. Un approccio più semplice consiste nell'aggiungere una chiusura di gestione del completamento alla funzione in cui si trova questo codice e passare finalPath a tale gestore di completamento. –

3

ho speso circa 8 ore alla ricerca di una risposta a questa uno. La soluzione qui sotto funziona per me, e fondamentalmente collego al metodo di download per visualizzare l'immagine. Nell'esempio che segue, sto scaricando l'immagine del profilo di un utente conoscere il suo ID di 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!) 
       } 
      } 
    } 
25

Swift 2.1 e un po 'più semplice:

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

ancora difficile da capire perché stanno usando le chiusure per impostare il percorso di destinazione ...

+2

Se il file di destinazione esiste già, la ridenominazione/spostamento fallirà, quindi la gestione questo caso nella chiusura è utile se si desidera utilizzare il nome file suggerito – penfold

+0

@penfold true questo mi consente di risparmiare un sacco di tempo scrivendo la logica per sostituire il file esistente con il nuovo file e il ripristino dal file temporaneo se il download non riesce. Sono davvero felice che sia una chiusura. – spaceMonkey

2

Ecco metodo completo per scaricare file in destinazione con il progresso

// MARK: metodi di download

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

} 
2

This answer da un membro Alamofire sembra essere la risposta migliore:

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))") 
} 
Problemi correlati