Метод Alamofire.download(): Где находится файл и успешно ли он был сохранен?
Пример использования Alamofire.download() работает очень хорошо, но нет никаких подробностей о том, как получить доступ к полученному загруженному файлу. Я могу выяснить, где находится файл и что он был назван, на основе установленного адресата и исходного запроса на файл, который я сделал, но я бы предположил, что есть значение, которое я должен иметь доступ, чтобы получить полный конечный путь загрузки и имя файла в ответе.
Как мне получить доступ к имени файла и как узнать, успешно ли он был сохранен? Я вижу методы делегата в фактическом коде Alamofire, который, как представляется, обрабатывает вызовы завершения делегирования для процесса загрузки, но как я могу/я могу получить доступ к данным файла в блоке .response?
Ответы
Ответ 1
В примере в файле readme Alamofire на самом деле есть путь к файлу, поэтому я беру его с помощью отдельной переменной, используемой в другом месте в моем коде. Это не очень элегантно, и я надеюсь, что есть способ получить эту информацию в ответе, но на данный момент это выполняется:
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!)
}
}
Ответ 2
Swift 2.1 и немного проще:
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!)")
}
По-прежнему сложно понять, почему они используют замыкания для установки пути назначения...
Ответ 3
Я потратил около 8 часов на поиск ответа на этот вопрос. Решение ниже работает для меня, и в основном я подключаюсь к методу загрузки для отображения изображения. В приведенном ниже примере я загружаю изображение профиля пользователя, зная его идентификатор 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 the first file
let data = NSData(contentsOfURL: imagePath)
self.viewProfileImage?.image = UIImage(data: data!)
}
}
}
Ответ 4
Вот полный способ загрузки файла в другом месте с ходом
//MARK: методы загрузки
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)")
}
}
}
Ответ 5
Этот ответ от члена Alamofire кажется лучшим ответом:
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))")
}