Reputation: 339
I'm trying to output some strings I've gathered in my app to a text file.
The text files will always exist in my project, like so:
I'm trying to overwrite whatever is in the file with a new (multi-lined) string:
func writeFile(){
let theFile: FileHandle? = FileHandle(forWritingAtPath: "./MyFiles/file.txt")
if theFile != nil { // This is always nil!!!
let data = ("Some text\nline 2\nline3\n" as String).data(using: String.Encoding.utf8)
// Write it to the file
theFile?.write(data!)
// Close the file
theFile?.closeFile()
} else {
print("Writing failed.")
}
} // End file writing
However, the FileHandler always returns nil. I suspect that this is because I'm supplying the path and/or filename incorrectly?
I've been googling and stack overflowing for a couple of hours now and I still have no idea of how to fix the problem. How do I specify the correct location and file?
Upvotes: 2
Views: 3965
Reputation: 8143
Generally apps should write only to certain directories. Where an app can write depends on the OS and the security settings. In general, the app's documents directory can be used for generic disk storage.
Since iOS 16 and macOS 13 URL.documentsDirectory
is available. Using the Data.write(to:)
shortcut for brevity:
let path = URL.documentsDirectory.appending(path: "binary.data")
let data = Data([0xca, 0xfe, 0xba, 0xbe])
try data.write(to: path)
Which will write the binary data to Data/Application/<app-uuid>/Documents/binary.data
Use a FileHandle for more control. The following example shows how to append-only on a file in the documents directory:
let logData = Data(...)
let path = URL.documentsDirectory.appending(path: "persistent.log")
if FileManager().fileExists(atPath: path.path) {
let fileHandle = try FileHandle(forWritingTo: path)
fileHandle.seekToEndOfFile()
try fileHandle.write(contentsOf: logData)
} else {
// create if not exists
try logData.write(to: path)
}
To see the file generated by an iOS app:
The written file should be in the AppData/Document directory of the container.
Upvotes: 1
Reputation: 2181
You cannot write file outside of the application sandbox. Each iOS app have individual directories Document, Library, tmp to store data.
func writeFile(){
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentsDirectory,.userDomainMask,true)
let theFile: FileHandle? = FileHandle(forWritingAtPath: "\(documentsPath)/MyFiles/file.txt")
if theFile != nil { // This is always nil!!!
let data = ("Some text\nline 2\nline3\n" as String).data(using: String.Encoding.utf8)
// Write it to the file
theFile?.write(data!)
// Close the file
theFile?.closeFile()
}
else {
print("Writing failed.")
}
} // End file writing
Upvotes: 4
Reputation: 535306
I'm trying to overwrite whatever is in the file
You can't. Writing into the app bundle is forbidden.
The proper approach in this kind of situation is, on first launch, to copy the files into, say, the Documents folder, which is writable. Now you can access them from there, and they are both readable and writable.
Upvotes: 1