I'm trying to use Alamofire4
for Swift3
. I need to download .mp3
files and save them to the Documents
directory. Current code is like so:
func downloadAudioFromURL(url: String, completion: ((_ status: ResponseStatus, _ audioLocalURL: URL?) -> Void)?) {
let fileManager = FileManager.default
let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioFullURL = String.ensureFullURLPath(url)
alamoManager.download(audioFullURL)
.validate { request, response, temporaryURL, destinationURL in
var pathComponent = response.suggestedFilename!
if pathComponent == "m4a.mp4" {
// Due to the old Android audio files without a filename
// Assign a unique name so audio files don't overwrite each other
pathComponent = "\(NSUUID().uuidString).mp4"
}
let localURL = directoryURL.appendingPathComponent(pathComponent)
if response.statusCode == 200 {
completion?(.success, localURL)
} else {
completion?(.failure, nil)
}
return .success
}
.responseJSON { response in
debugPrint(response)
print(response.temporaryURL)
print(response.destinationURL)
}
}
However I can't actually access the files from the localURL
after saving. I have also noticed that the localURL
will be exactly the same for different files I try to download (maybe they are overwriting?). E.g: file:///Users/testuser/Library/Developer/CoreSimulator/Devices/D4254AEA-76DD-4F01-80AF-F1AF3BE8A204/data/Containers/Data/Application/29755154-DD21-4D4C-B340-6628607DC053/Documents/file1.mp3
Any ideas what I am doing wrong here?
Edited my code to look like this:
func downloadAudioFromURL(url: String, completion: ((_ status: ResponseStatus, _ audioLocalURL: URL?) -> Void)?) {
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
documentsURL.appendPathComponent("Audiofile.mp3")
return (documentsURL, [.removePreviousFile])
}
Alamofire.download(url, to: destination).response { response in
if let localURL = response.destinationURL {
completion?(.success, localURL)
} else {
completion?(.failure, nil)
}
}
}
How would I check for m4a.mp4 though?
Why are you performing .validate
? You are not storing any data after download in your current code.
Alamofire allows you to store a file directly after download:
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendPathComponent("pig.png")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(urlString, to: destination).response { response in
print(response)
if response.result.isSuccess, let imagePath = response.destinationURL?.path {
let image = UIImage(contentsOfFile: imagePath)
}
}
And by the way, the download path you are providing in the download
method, is the local URL to the Documents directory and not a URL of a server.