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 an actual iPhone? I want to be able to read and write from it. Here are my project files if you want to take a look. I'm happy to add details if necessary.
The bundle object provides a single interface for locating items, taking into account the bundle structure, user preferences, available localizations, and other relevant factors. Any executable can use a bundle object to locate resources, either inside an app's bundle or in a known bundle located elsewhere.
The main bundle lets you access the resources in the same directory as the currently running executable.
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") } }
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With