Search code examples
iosswiftalamofirensfilemanager

Alamofire download to file system doesn't work


I'm creating a test project before we implement the Alamofire downloading into our app. Right now, I'm facing a strange issue and maybe I don't understand how Alamofire Download or the FileManager works.

I simply download 3 files from a URL and want to store them in the file system. After that, I want to use them as local data in a WKWebView (not implemented yet).

This is my ViewController:

import UIKit

class ViewController: UIViewController {

    @IBAction func loadWebsite(_ sender: Any) {     
        NetworkService.shared.getFile(path: "webview.html", completion: {
            NetworkService.shared.getFile(path: "css/style.css", completion: {
                NetworkService.shared.getFile(path: "images/square.jpg", completion: {
                    self.fillInContent()
                })
            })
        })
    }

    private func fillInContent() {
        let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let fileUrl = documentURL.appendingPathComponent("webview.html")

        if FileManager.default.fileExists(atPath: fileUrl.absoluteString) {
            print("True")
        } else {
            print("no webview")
        }
    }
}

I know the code for loading the resources isn't written very well with starting a new request in the completion block, but again it's just a test project.

This is my NetworkService singleton:

import UIKit
import Alamofire

class NetworkService {
    static let shared = NetworkService()

    // Thread-safe
    private init() {}

    func getFile(path: String, completion: @escaping() -> Void) {
        let destination: DownloadRequest.DownloadFileDestination = {_, _ in
            let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            let fileURL = documentURL.appendingPathComponent(path)

            return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
        }

        Alamofire.download("https://myurl.com/" + path, to: destination)
            .responseData { response in
                if let error = response.result.error {
                    print("Error: \(error.localizedDescription)")
                }

               completion()
        }
    }
}

When I print out the file URLs in the NetworkService or the fillInContent() in the VC they are correct. However, the fillInContent() method always prints out "no webview". So the file doesn't exist. I expected it to be overwritten by the other completion blocks, but even if I start the function right in the completion block the fileExist() also returns false. Even if I remove the other 2 calls to getFile() I won't get true for fileExists here.

Current behavior: I get "no webview" all the time.

Expected behavior: The fillInContent() method prints out "True".

Any help or guidance is highly appreciated!

EDIT: After running the project twice, I also receive this error message: 'Error: The file “Documents” couldn’t be saved in the folder “1E07C511-B5B3-4B5A-84E1-8EF61F6B7340” because a file with the same name already exists.'


Solution

  • Try to use this method to get documents directory:

    try? FileManager.default.url(for: .documentDirectory,
                                 in: .userDomainMask,
                                 appropriateFor: nil,
                                 create: true)
    

    And use fileUrl.path instead of fileUrl.absoluteString