Search code examples
iosswiftbundlensdocumentdirectory

Failing to copy file from Bundle to Documents Directory Subfolder


I have created a Documents Directory subfolder with the following code:

fileprivate func createFolderOnDocumentsDirectoryIfNotExists() {
    let folderName = "HTML"
    let fileManager = FileManager.default
    if let tDocumentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
        let filePath =  tDocumentDirectory.appendingPathComponent("\(folderName)")
        if !fileManager.fileExists(atPath: filePath.path) {
            do {
                try fileManager.createDirectory(atPath: filePath.path, withIntermediateDirectories: true, attributes: nil)
            } catch {
                print("Couldn't create document directory")
            }
        }
        print("Document directory is \(filePath)")
    }
}

Doing this the subfolder is created as expected. I prove that by printing the documents directory content and it shows the HTML folder/file

Then I am trying to copy another file that exists in the app Bundle to this created subfolder but somehow I get an error saying that the specific file couldn't be copied to Documents because an item with the same name already exists.

This is confusing because even on a newly installation, without any copied file it says the file exists there but if I print the subfolder contents nothing is shown.

I'm trying to copy the file from the bundle sandbox with the following code:

fileprivate func copyCSSFileToHTMLFolder() {
    guard let cssPath = Bundle.main.path(forResource: "swiss", ofType: ".css") else {
        print("css not found -- returning")
        return
    }
    let fileManager = FileManager.default

    if let tDocumentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
        let filePath =  tDocumentDirectory.appendingPathComponent("HTML")
        if fileManager.fileExists(atPath: filePath.path) {
            do {
                try fileManager.copyItem(atPath: cssPath, toPath: filePath.path)
            } catch {
                print("\nFailed to copy css to HTML folder with error:", error)
            }
        }
    }
}

What am I doing wrong here?

Regards.


Solution

  • You need to create a full path, including the filename.

    Change:

    let filePath =  tDocumentDirectory.appendingPathComponent("HTML")
    

    to:

    let filePath =  tDocumentDirectory.appendingPathComponent("HTML").appendingPathComponent(cssURL.lastPathComponent)
    

    And the above use of lastPathComponent can be made possible by changing:

    guard let cssPath = Bundle.main.path(forResource: "swiss", ofType: ".css") else {
    

    to:

    guard let cssURL = Bundle.main.url(forResource: "swiss", withExtension: "css") else {
    

    And of course use cssURL.path in the call to copyItem.