Aluminum
Aluminum

Reputation: 2992

Check if a file already exists before downloading it with Alamofire + suggestedDownloadDestination

How can I check if a given file has been already downloaded before re-downloading it by using Alamofire? I'm using suggestedDownloadDestination so Alamofire will automatically choose the name of the file and save it in the choosen directory, for example the .CachesDirectory. The problem is that the value given by suggestedDownloadDestination is of type DownloadFileDestination which will return a NSURL only by calling him with the request's response, but in this way I could not ever know the file path without performing a request before.

This is the code I currently use to download a file with Alamofire:

Alamofire.download(.GET, downloadLink, destination: destination).progress {
                    bytesRead, totalBytesRead, totalBytesExpectedToRead in

                    }.response {
                        request, response, data, error in

                        guard error == nil else {
                            return
                        }

                        // This will give me the file path but we're already in a Request!
                        print("\(destination(NSURL(string: "")!, response!))")
                }

What am I missing?

Upvotes: 2

Views: 2078

Answers (2)

Mussa Charles
Mussa Charles

Reputation: 4412

Here is the solution which I used

  1. Download a file
  2. check if it exist if so just return the path otherwise
  func downloadDocumentFile(filePath: String,onDownloadProgress: @escaping(_ progress: Double) -> Void,onError: @escaping(_ errorMessage: String) -> Void,onSuccess: @escaping(_ destinationUrl: URL) -> Void){
        guard let url = URL(string: filePath) else {
            onError("Couldn't create url from passed file path")
            assertionFailure()
            return
        }
        let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory, in: .userDomainMask)
        Alamofire.download(url, to: destination)
            .downloadProgress { (progress) in
                onDownloadProgress(progress.fractionCompleted)
        }
        .responseData(queue: .main) { (response) in
            switch response.result {
            case .success:
                if let destinationUrl = response.destinationURL {
                    onSuccess(destinationUrl)
                }else {
                    onError("Couldn't get destination url")
                    assertionFailure()
                }
            case .failure(let error):
                  // check if file exists before
                if let destinationURL = response.destinationURL {
                    if FileManager.default.fileExists(atPath: destinationURL.path){
                        // File exists, so no need to override it. simply return the path.
                        onSuccess(destinationURL)
                        print()
                    }else {
                        onError(error.localizedDescription)
                        assertionFailure()
                    }
                }else {
                    onError(error.localizedDescription)
                    assertionFailure()
                }
            }

        }
    }

Upvotes: 1

Ishan Handa
Ishan Handa

Reputation: 2281

Not sure if you figured this out yet, but you can create an extension over Alamofire.DownloadRequest like:

extension Alamofire.DownloadRequest {
    open class func suggestedDownloadDestination(
        for directory: FileManager.SearchPathDirectory = .documentDirectory,
        in domain: FileManager.SearchPathDomainMask = .userDomainMask,
        with options: DownloadOptions)
        -> DownloadFileDestination
    {
        return { temporaryURL, response in
                let destination = DownloadRequest.suggestedDownloadDestination(for: directory, in: domain)(temporaryURL, response)
            return (destination.destinationURL, options)
        }
    }
}

Now you can specify in the options parameter if you want the file to be overwritten:

let destination =  DownloadRequest.suggestedDownloadDestination(for: .cachesDirectory,
                                                                in: .userDomainMask,
                                                                with: [DownloadRequest.DownloadOptions.removePreviousFile])

Upvotes: 3

Related Questions