How to access file included in app bundle in Swift?

后端 未结 7 1810
灰色年华
灰色年华 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:03

    Simply by searching in the app bundle for the resource

    var filePath = NSBundle.mainBundle().URLForResource("file", withExtension: "txt")
    

    However you can't write to it because it is in the app resources directory and you have to create it in the document directory to write to it

    var documentsDirectory: NSURL?
    var fileURL: NSURL?
    
    documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last!
    fileURL = documentsDirectory!.URLByAppendingPathComponent("file.txt")
    
    if (fileURL!.checkResourceIsReachableAndReturnError(nil)) {
        print("file exist")
    }else{
        print("file doesnt exist")
        NSData().writeToURL(fileURL!,atomically:true)
    }
    

    now you can access it from fileURL

    EDIT - 28 August 2018

    This is how to do it in Swift 4.2

    var filePath = Bundle.main.url(forResource: "file", withExtension: "txt")
    

    To create it in the document directory

    if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
       let fileURL = documentsDirectory.appendingPathComponent("file.txt")
       do {
           if try fileURL.checkResourceIsReachable() {
               print("file exist")
           } else {
               print("file doesnt exist")
               do {
                try Data().write(to: fileURL)
               } catch {
                   print("an error happened while creating the file")
               }
           }
       } catch {
           print("an error happened while checking for the file")
       }
    }
    
    0 讨论(0)
  • 2020-11-30 06:06

    Just a quick update for using this code with Swift 4:

    Bundle.main.url(forResource:"YourFile", withExtension: "FileExtension")
    

    And the following has been updated to account for writing the file out:

    var myData: Data!
    
    func checkFile() {
        if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
            let fileURL = documentsDirectory.appendingPathComponent("YourFile.extension")
            do {
                let fileExists = try fileURL.checkResourceIsReachable()
                if fileExists {
                    print("File exists")
                } else {
                    print("File does not exist, create it")
                    writeFile(fileURL: fileURL)
                }
            } catch {
                print(error.localizedDescription)
            }
        }
    }
    
    func writeFile(fileURL: URL) {
        do {
            try myData.write(to: fileURL)
        } catch {
            print(error.localizedDescription)
        }
    }
    

    This particular example is not the most flexible, but with a little bit of work you can easily pass in your own file names, extensions and data values.

    0 讨论(0)
  • 2020-11-30 06:08

    Get File From Bundle in Swift 5.1

    //For Video File
    let stringPath = Bundle.main.path(forResource: "(Your video file name)", ofType: "mov")
    
    let urlVideo = Bundle.main.url(forResource: "Your video file name", withExtension: "mov")
    
    0 讨论(0)
  • 2020-11-30 06:12

    Bundles are read only. You can use NSBundle.mainBundle().pathForResource to access the file as read-only, but for read-write access you need to copy your document to Documents folder or tmp folder.

    0 讨论(0)
  • 2020-11-30 06:14

    0 讨论(0)
  • 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)
    
    0 讨论(0)
提交回复
热议问题