web-dev-qa-db-fra.com

Méthode Alamofire.download (): où se trouve le fichier et a-t-il été enregistré avec succès?

L'exemple d'utilisation de Alamofire.download () fonctionne très bien, mais il n'y a aucun détail sur la façon d'accéder au fichier téléchargé résultant. Je peux comprendre où se trouve le fichier et son nom en fonction de la destination que j'ai définie et de la demande de fichier d'origine que j'ai faite, mais je suppose qu'il y a une valeur à laquelle je devrais pouvoir accéder pour obtenir le chemin de téléchargement final complet et nom de fichier dans la réponse.

Comment accéder au nom du fichier et comment savoir s'il a bien été enregistré? Je peux voir les méthodes déléguées dans le code Alamofire réel qui semblent gérer les appels d'achèvement des délégués pour le processus de téléchargement, mais comment puis-je/puis-je accéder aux détails du fichier dans le bloc .response?

22
Paul Bonneville

L'exemple du fichier Lisez-moi d'Alamofire contient en fait le chemin du fichier, donc je le saisis avec une variable distincte à utiliser ailleurs dans mon code. Ce n'est pas très élégant et j'espère qu'il y a un moyen d'obtenir ces informations dans la réponse, mais pour l'instant, cela fait le travail:

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!)
        }
 }
13
Paul Bonneville

Swift 2.1 et un peu plus simple:

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

Difficile de comprendre pourquoi ils utilisent des fermetures pour définir le chemin de destination ...

25
Sam

J'ai passé environ 8 heures à chercher une réponse à celle-ci. La solution ci-dessous fonctionne pour moi et, fondamentalement, je me connecte à la méthode de téléchargement pour afficher l'image. Dans l'exemple ci-dessous, je télécharge l'image de profil d'un utilisateur connaissant son identifiant 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!)
                }
            }
    }
3
esfoobar

Cette réponse d'un membre d'Alamofire semble être la meilleure réponse:

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

Voici la méthode complète pour télécharger le fichier dans une destination différente avec le progrès

// MARK: Méthodes de téléchargement

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
alok srivastava