9

I've a problem to write text in a file. What I've done so far is the following: I have a string with the text to store and the file name also as a string.

let someText = "abcd"
let fileName = "file:///xxx"

Of course "xxx" is a .txt file under the document directory so it should be possible to write.
Then I found out that I can use the write method o the string. But for this call I need the file name as url so I have this piece of code:

let fileUrl = URL(string: fileName)
do {
    try someText.write(to: fileUrl, atomically: false, encoding: String.Encoding.utf8)
}
catch { }

If I start my app then I will get an error "The file xxx does not exist". Ok that's correct because the file is not created. I thought that the write method does it automatically but it seems not so.
And that's the point I don't know how to solve this issue!

I'm using Xcode 8 + Swift 3.

+++ EDIT +++

I try to explain what I'm exactly looking for.
Let's say I've two tasks: The first task builds file names and stores it in a database. That's why I work with strings:

var fileName = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).path
if (!fileName.hasSuffix("/")) {
    fileName += "/"
}
fileName += "file.txt"

As you can see the file is not created at this moment because I only need the name in this task.

Ok and then the second task. It has to select a specific file name from the database and append it with the file:// scheme:

let fileName = "file://" + fileNameFromDatabase

Then the text is written with the code above.
It's clear that the file not exists in this task because I only have the name. That's why I think that the error message of the write method is correct.
What I'm now looking for is a possibility to create the file/write the text in one step.

altralaser
  • 2,035
  • 5
  • 36
  • 55
  • Is an error being thrown when you call `write`? – rmaddy Oct 12 '16 at 20:10
  • Sorry my mistake. I forgot to say: An error is thrown which I casted to NSError and the localizedDescription is the message I wrote in my post - The file xxx does not exist. – altralaser Oct 12 '16 at 20:13
  • You are getting that error when trying to write the file? That's doesn't seem right. – rmaddy Oct 12 '16 at 20:14
  • @rmaddy: The error is thrown directly after try write. – altralaser Oct 12 '16 at 20:24
  • You say the file is under the Documents folder. Do you mean directly in the Documents folder or in some sub-folder of Documents? And update your question showing how you really get the value for `fileName`. – rmaddy Oct 12 '16 at 20:27
  • You have a variable named `fileNameFromDatabase`. Is this the complete path (including the full path of the Documents folder)? That's bad because that changes often. Never persist a full path. Simply get the path to the Documents folder at runtime and then append the name of the file to that. – rmaddy Oct 12 '16 at 22:14

3 Answers3

27

Swift 3 example:

func write(text: String, to fileNamed: String, folder: String = "SavedFiles") {
    guard let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { return }
    guard let writePath = NSURL(fileURLWithPath: path).appendingPathComponent(folder) else { return }
    try? FileManager.default.createDirectory(atPath: writePath.path, withIntermediateDirectories: true)
    let file = writePath.appendingPathComponent(fileNamed + ".txt")
    try? text.write(to: file, atomically: false, encoding: String.Encoding.utf8)
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Bogdan Novikov
  • 565
  • 6
  • 14
3

Swift 5.4 Example

Following is an example to create test.txt in Documents directory.

import Foundation

let filePath = NSHomeDirectory() + "/Documents/" + "test.txt"
if (FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)) {
    print("File created successfully.")
} else {
    print("File not created.")
}

Reference - Create Text File in Swift

arjun
  • 1,645
  • 1
  • 19
  • 19
0

I recently ran into some problems by trying to just do:

"my string".writeToURL...

Which is how many of the tutorial show you how to do it. Eventually I came up with this method (is swift 2.3 for which i apologize). I kept getting an error saying I did not have permission to write. Then I started to get your error. The bottom is working for me. The param file is what you want the name of your file to be.

func writeDataToFile(file: String)-> Bool{

    let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
    let logsPath = documentsPath.URLByAppendingPathComponent("yourFolderDirectory")
    do {
        try NSFileManager.defaultManager().createDirectoryAtPath(logsPath!.path!, withIntermediateDirectories: true, attributes: nil)
    } catch let error as NSError {
        NSLog("Unable to create directory \(error.debugDescription)")
    }

    let str = "hello world"

    let fileName = logsPath?.URLByAppendingPathComponent(file + ".txt")

    do{
        try str.writeToURL(fileName!, atomically: false, encoding: NSUTF8StringEncoding)
        return true
    } catch let error as NSError {
        print("Ooops! Something went wrong: \(error)")
        return false
    }
}
random
  • 8,568
  • 12
  • 50
  • 85
  • Is your example Swift 3 code? It seems a bit older. F.e. I'm not using writeToURL. – altralaser Oct 12 '16 at 20:27
  • @altralaser it's not, it's in swift 2.3 (i have that in the answer) but was thinking it could help. The translation should be straight forward. – random Oct 12 '16 at 20:34
  • First of all - thanks for your example. But my problem is not to build a correct file name or find the document directory. My problem is the writing process. And it's not so easy to port your code because there are many changes in Swift 3. If I did it anyway then I will more or less get the code which I used in my post and the question is still the same: Why I can't create/write? – altralaser Oct 13 '16 at 12:39