Reading and Writing files in iOS app

Every iOS app has its own little space on the device for storing files. This space is called its sandbox, as access by other apps is generally prohibited. Similarly, your app generally doesn’t have access to the sandboxed file system of other apps.

Useful iOS directories

  • App bundle. This read-only directory contains the app itself and all resources bundled with it.
  • Documents. Files generated by the user that may be accessible to the user directly through file sharing.
  • Application support. Files your app can generate to support itself that will be invisible to the user.
  • Temporary files. Store files here temporarily while you work with them.
  • Caches. Store files here temporarily for possibly improving download speed.

You can use the FileManager class to handle regular file system activities such as creating, copying, and moving files and directories. You can also use the FileManager class to return a path for one of the iOS directories.

Use the FileManager’s urls method to get an array of URL objects for the application support directory. Because you only want the first item in the array, use its first property.

Unlike the documents folder, the application support folder isn’t generated for your app automatically, so before returning the URL, check if the folder exists, and if not, create it.

Define the appSupportDirectory private global variable in your swift file (outside the class).

private let appSupportDirectory: URL = {
    let url = FileManager().urls(for: .applicationSupportDirectory,
                in: .userDomainMask).first!
    if !FileManager().fileExists(atPath: url.path) {
        do {
            try FileManager().createDirectory(at: url, withIntermediateDirectories: false)
        } catch {
            print("\(error.localizedDescription)")
        }
    }
    return url
}()

Because the createDirectory method can throw an error, you’ll need to surround it in a do-catch statement.

Once you have a path to the application support directory, generate a path to a directory to store your data, using the URL object’s appendingPathComponent method.

private let moviesFile =
    appSupportDirectory.appendingPathComponent("Movies")

Reading and Writing to Files

To write a file, we first need to use the FileManager object like this:

let fm = FileManager.default

Next, we need to define a location for the file, which is the document directory in the home folder:

let urls = fm.urls(for: .documentDirectory, in: .userDomainMask) 

Finally, we need to create a file name (such as "file.txt") to store data like this:

let url = urls.last?.appendingPathComponent("file.txt")

Once we’ve stored text in a file, we can retrieve it by using the FileManager again and look for the file in the document directory in the home folder.

func readFile(_ sender: UIButton) {
    let fm = FileManager.default
    let urls = fm.urls(for: .documentDirectory, in: .userDomainMask)
    let url = urls.last?.appendingPathComponent("file.txt") 
    do {
        let fileContent = try String(contentsOf: url!, encoding: String.Encoding.utf8)
        displayText.text = fileContent
    } catch {
        print("File reading error")
    } 
}

func writeFile(_ sender: UIButton) {
    let fm = FileManager.default
    let urls = fm.urls(for: .documentDirectory, in: .userDomainMask)
    let url = urls.last?.appendingPathComponent("file.txt") 
    do {
        try createText.text.write(to: url!, atomically: true,
            encoding: String.Encoding.utf8) 
    } catch {
        print("File writing error")
    }
}