Make App Pie

Training for Developers and Artists

iOS Tips: Read and Write Text Files

iOS Development tips weekly is a series you can find at the Lynda.com and LinkedIn Learning libraries. The first week of a week’s tip will be available to the public. After that, you will need a subscription to get access to it. Click the image below to view.

You can find the finished project here on GitHub

In iOS, one of the simplest forms of persistent data, and the basis for many universal file formats, is the text file. I’m going to show you one simple way to set up text files.

I’ll be making our demo in Swift playgrounds based on a starter file I created called ReadWriteText. If it starts to run, Hold down the play button and set to run manually.

There’s two parts to reading and writing a text file. Getting a file’s name and then reading or writing the file.

For filenames, you can use  either a string of the complete file path, or a URL. You’ll find the URL is a lot more flexible in use.  I’ll get the URL for the  document directory of the app using a computed property I  started here

We’ll make this url using the FileManager class, which controls the file system. It has a singleton, default, to point to the  default file system.  Type this:

let URL FileManager.default.

Select the method url:for:in:appropriateFor:Create: which returns the URL of a directory. The for parameter is an enumeration with several options. For saving user files, take the document directory option to store the text file in the document directory.

The in parameter is the domain of the file system. For most applications you’ll want a userdomainmaskAppropriate for is for replacing directories, so leave that nil. If the directory does not exist create it by making create: true.

This method throws errors, though we are sure that this directory will either be there or will be created in the app. Add a try! In front of the FileManager to quiet any error checking.

var DocumentDirURL:URL{
let url = try!FileManager.default.url(
    for: .documentDirectory,
    in: .userDomainMask,
    appropriateFor: nil,
    create: true)
}

I’ll add a function to append a filename and extension to the URL directory

func fileURL(fileName:String, fileExtension:String) -> URL {
    return DocumentDirURL.appendingPathComponent(fileName).appendingPathExtension(fileExtension)
}

I get the file name and extension as parameters, and I append them to the document URL using the appendingPathComponent and the Appending Path extension.

With my URL, I can write  to a file. I’ll fill in  another function writeFile:

func writeFile(writeString:String,to fileName:String, fileExtension:String = "txt"){

}

Most of the files will be of the extension “txt”, so I set a default value of txt for convenience. I’ll get the URL from those parameters.

let url = fileURL(fileName: fileName, fileExtension: fileExtension)

There’s a method on strings that writes directly to the file system if we give it a url. It does throw errors so I’ll need a try here

// Write to the file
try writeString.write(to: url, atomically: true, encoding: String.Encoding.utf8)

The first parameter is the URL, Atomically makes a temporary file while the operation is completing. Encoding is an enumeration of String.Encoding that gives that character encoding for the string. I’ll keep it simple with UTF8

As far as the error handling, I use a do-catch to handle the error:

do {

} catch let error as NSError {
    print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
}

We’ve now set code to write a file, it would be a good idea to read it. Much of the code is the same. Copy and paste the code from writeFile into the read file method. In the error, change writing to reading.

Add a Variable readString with a blank string.

var readString = ""

String also has an initializer that reads directly from a URL. It can throw an error so it’s in the do-catch.

readString = try String(contentsOf: url)

We are ready to use this.  Under the class, I already instantiated it for you. Add  this:

rwt.writeFile(writeString: "Hello Pizza", to: "Pizza")

print(rwt.readFile(fileName: "Pizza"))

Run the code.  The field writes and reads.  This sends the files to the documents. You can change the URL to send it to other places, such as the bundle. The power of text files does not remain with text alone. XML, CSV and HTML files all are text files which could be read  or written this same way.

You can find the finished project here on GitHub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: