12

There are all sorts of sample code & questions on SO dealing with how to programmatically copy files in Obj-C from the app bundle to the application's sandboxed Documents folder (e.g. here, here, and here) when the application runs for the first time.

How do you do this in Swift?

MMac
  • 483
  • 1
  • 4
  • 13
  • 6
    There is no way to copy files to the Documents folder at build time in any language. It needs to be done at runtime, not build time. And if you have code in Objective-C, then why can't you translate the code to Swift? It's the same APIs. – rmaddy Jan 02 '19 at 21:50
  • sorry, I'm not using the correct terminology. I was thinking of "build time" as the first time the app is installed -- but you're right; that's still run time. I have rephrased the question. – MMac Jan 02 '19 at 22:32

2 Answers2

21

You could use FileManager API:

Here's example with a function that copies all files with specified extension:

func copyFilesFromBundleToDocumentsFolderWith(fileExtension: String) {
    if let resPath = Bundle.main.resourcePath {
        do {
            let dirContents = try FileManager.default.contentsOfDirectory(atPath: resPath)
            let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
            let filteredFiles = dirContents.filter{ $0.contains(fileExtension)}
            for fileName in filteredFiles {
                if let documentsURL = documentsURL {
                    let sourceURL = Bundle.main.bundleURL.appendingPathComponent(fileName)
                    let destURL = documentsURL.appendingPathComponent(fileName)
                    do { try FileManager.default.copyItem(at: sourceURL, to: destURL) } catch { }
                }
            }
        } catch { }
    }
}

Usage:

copyFilesFromBundleToDocumentsFolderWith(fileExtension: ".txt")
Brooketa
  • 352
  • 2
  • 9
  • 5
    I didn't ask for the extra detail about only copying files of a particular extension, but that is super helpful and most definitely was the next issue I was going to have to solve. Despite the community not finding the question helpful, your answer IS helpful to me and I appreciate the time you put in. Thank you! – MMac Jan 03 '19 at 13:16
7

For Swift 4.2:

Assuming the file in your App Bundle is called Some File.txt

In ViewDidLoad, add:

let docName = "Some File"
let docExt = "txt"
copyFileToDocumentsFolder(nameForFile: docName, extForFile: docExt)

and then create a function as follows:

func copyFileToDocumentsFolder(nameForFile: String, extForFile: String) {

    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    let destURL = documentsURL!.appendingPathComponent(nameForFile).appendingPathExtension(extForFile)
    guard let sourceURL = Bundle.main.url(forResource: nameForFile, withExtension: extForFile)
        else {
            print("Source File not found.")
            return
    }
        let fileManager = FileManager.default
        do {
            try fileManager.copyItem(at: sourceURL, to: destURL)
        } catch {
            print("Unable to copy file")
        }
}
MMac
  • 483
  • 1
  • 4
  • 13