How to access file included in app bundle in Swift?

后端 未结 7 1885
灰色年华
灰色年华 2020-11-30 05:46

I know there are a few questions pertaining to this, but they\'re in Objective-C.

How can I access a .txt file included in my app using Swift on

7条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-30 06:19

    Swift 3, based on Karim’s answer.

    Reading

    You can read files included in an app’s bundle through the bundle’s resource:

    let fileURL = Bundle.main.url(forResource:"filename", withExtension: "txt")
    

    Writing

    However, you can’t write there. You will need to create a copy, preferably in the Documents directory:

    func makeWritableCopy(named destFileName: String, ofResourceFile originalFileName: String) throws -> URL {
        // Get Documents directory in app bundle
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
            fatalError("No document directory found in application bundle.")
        }
    
        // Get URL for dest file (in Documents directory)
        let writableFileURL = documentsDirectory.appendingPathComponent(destFileName)
    
        // If dest file doesn’t exist yet
        if (try? writableFileURL.checkResourceIsReachable()) == nil {
            // Get original (unwritable) file’s URL
            guard let originalFileURL = Bundle.main.url(forResource: originalFileName, withExtension: nil) else {
                fatalError("Cannot find original file “\(originalFileName)” in application bundle’s resources.")
            }
    
            // Get original file’s contents
            let originalContents = try Data(contentsOf: originalFileURL)
    
            // Write original file’s contents to dest file
            try originalContents.write(to: writableFileURL, options: .atomic)
            print("Made a writable copy of file “\(originalFileName)” in “\(documentsDirectory)\\\(destFileName)”.")
    
        } else { // Dest file already exists
            // Print dest file contents
            let contents = try String(contentsOf: writableFileURL, encoding: String.Encoding.utf8)
            print("File “\(destFileName)” already exists in “\(documentsDirectory)”.\nContents:\n\(contents)")
        }
    
        // Return dest file URL
        return writableFileURL
    }
    

    Example usage:

    let stuffFileURL = try makeWritableCopy(named: "Stuff.txt", ofResourceFile: "Stuff.txt")
    try "New contents".write(to: stuffFileURL, atomically: true, encoding: String.Encoding.utf8)
    

提交回复
热议问题