Swift Programming

Easy Reading and Writing Strings to and from file in Swift

Learn how to read strings from file and save string contents to file

Anurag Ajwani

--

Photo by Aaron Burden on Unsplash

Are you looking to temporarily save some information about your app state? You might want to save the information to avoid fetching the same data from the internet from multiple parts of your app. Or you might just want to save the data for when the user relaunches the app its feels snappier and quicker. Thus leading to better user experience.

Many times I find myself looking a place to dump this information just for the sake of loading quickly whilst in the background I’m fetching for new refreshed data.

So how can save some simple data? One of the easiest way to do so is using the String write(to:_, atomically: _, encoding: _) function. And how to load it back again? Using the String convenience initialiser String(contentsOf: _, encoding: _).

Saving data temporarily to speed up your application is called Caching. However the scope of this post is not about caching but rather how to read and write strings to and from file.

Let’s see how to use the write(to:_, atomically: _, encoding: _) function and String(contentsOf: _, encoding: _) initialiaser through examples. In this post I will focus on saving and reading JSON API responses from file. Let’s say you are building an iOS app to show a list of your blog posts which are stored in your server. Upon requesting a list of the newest blog posts you get the following response:

[
{
"title": "Easy Reading and Writing String to and from file in Swift",
"date": "2021-05-11"
},
{
"title": "Post 2",
"date": "2021-05-04"
}
]

Writing Strings to file

Let’s see an example of writing strings into files:

let apiResponse = """
[
{
"title": "Easy Reading and Writing String to and from file in Swift",
"date": "2021-05-11"
},
{
"title": "Post 2",
"date": "2021-05-04"
}
]
"""
let filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("api_response.json")
try apiResponse.write(to: filePath, atomically: true, encoding: .utf8)

In the example above we are taking a string and writing to a file path. We start by first defining the file path.

Every iOS app get an allocated storage. The storage is not limited. This storage is accessible by both the app and the user. To find the document directory we make use of the FileManager interface to interact with files and directory, and search for the allocated space:

FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

Once we retrieve the directory we are appending the file name and extension to it:

.appendingPathComponent("api_response.json")

Finally we make use of String’s write(to:_, atomically: _, encoding: _) function to save the file to disk. This operation can throw an error and thus must be handled using the Swift Error Handling mechanisms.

The first parameter is simply the URL to which to write. The URL we provide here is the one we created with the help of FileManager in the previous line of code.

The second parameter–atomically: true–ensures that the file is not corrupted during the write by writing to a temporary file before copying the contents to the final destination path. Corruption can happen in scenarios where the app crashes mid-write.

We won’t be delving into the final parameter–encoding–in this post. Explaining encoding is a blog post on its own and requires an understanding of how computers store information and how these get converted at a low level. For now let’s set the encoding always to .utf8.

Reading Strings from file

In this section we’ll cover how to read strings from file. Let’s look at an example of how to convert files into strings:

let filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("api_response.json")
try String(contentsOf: filePath, encoding: .utf8)

Once again we start by getting the URL for the file we want to read. Then we simply need to provide the URL to String convenience initialiser. This initialiser can throw errors in scenarios such when the file does not exist. Thus we need once again do error handling when using this initialiser.

Summary

In this post we learnt:

Final Thoughts

In this post I did not cover deleting files. There is no String API function to do so. For deleting you’ll need to use FileManager API. You can do all of the operations (create, overwrite, read and delete) using FileManager. Whilst FileManager is quite simple and straight forward the String API makes it easier.

For more on iOS development follow me on Twitter or Medium!

--

--

Anurag Ajwani

Senior iOS Engineer at Travelperk. 7+ years experience with iOS and Swift. Blogging my knowledge and experience.