Reading and Writing files in iOS app iOS 23.11.2019

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.

The application sandbox contains a number of directories:

  • Documents/. This directory is where you write data that the application generates during runtime and that you want to persist between runs of the application. It is backed up when the device is synchronized with iCloud or Finder. If something goes wrong with the device, files in this directory can be restored from iCloud or Finder.
  • Library/Caches/. This directory is where you write data that the application generates during runtime and that you want to persist between runs of the application. However, unlike the Documents directory, it does not get backed up when the device is synchronized with iCloud or Finder. A major reason for not backing up cached data is that the data can be very large and extend the time it takes to synchronize your device. Data stored somewhere else – like a web server – can be placed in this directory. If the user needs to restore the device, this data can be downloaded from the web server again. If the device is very low on disk space, the system may delete the contents of this directory.
  • Library/Preferences/. This directory is where any preferences are stored and where the Settings application looks for application preferences. Library/Preferences is handled automatically by the class UserDefaults and is backed up when the device is synchronized with iCloud or Finder.
  • tmp/. This directory is where you write data that you will use temporarily during an application’s runtime. The OS may purge files in this directory when your application is not running. However, to be tidy you should explicitly remove files from this directory when you no longer need them. This directory does not get backed up when the device is synchronized with iCloud or Finder.

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")
    }
}