Skip to content

MASTG-KNOW-0091: File System APIs

iOS apps can write data to the file system using various APIs, depending on the use case.

Other ways to store data that do not involve direct file system access include: Binary Data Storage, UserDefaults, CoreData, Realm Databases, Other Third-Party Databases, Object Serialization

For internal app files, caches, exports, or simple background writes where the app fully controls the path and conflicts are unlikely, apps typically use FileManager.

A file can be created and written using FileManager and createFile(atPath:contents:attributes:).

  • First, obtain the path using FileManager.default.urls(for:in:). Use the for parameter to specify the directory, such as .documentDirectory or .libraryDirectory.
    • Apps can also write to the temporary directory using the URL property temporaryDirectory and the file manager property temporaryDirectory. The system may purge this directory when the app isn't running.
    • For files that persist longer than temporary files, but are still purgeable, apps can use the caches directory .cachesDirectory.
    • For files that are needed for app operation but don't need to be exposed to the user, apps can use the application support directory .applicationSupportDirectory (typically configuration files, templates, and modified versions of default files from the app bundle).
  • Next, call createFile(atPath:contents:attributes:), providing the path, the data to write, and optional attributes such as the file protection level.

Example:

let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    .appendingPathComponent("filename.txt")
FileManager.default.createFile(
    atPath: url.path,
    contents: "secret text".data(using: .utf8),
    attributes: [FileAttributeKey.protectionKey: FileProtectionType.complete]
)

Other APIs can write to files as well, including:

In document based apps, where the system should coordinate access, integrate with iCloud or the Files app, or support autosave and versioning, developers can use UIDocument or NSDocument. These APIs still read and write regular files under the app sandbox or iCloud containers, so file protection attributes and default protection classes apply in the same way.

Data Protection

File protection attributes such as FileProtectionType.complete ensure that data remains encrypted while the device is locked, as described in Apple's Encrypting Your App's Files.

The default protection level is NSFileProtectionCompleteUntilFirstUserAuthentication and can be changed by supplying attributes when creating a file with createFile(atPath:contents:attributes:) or later using setAttributes(_:ofItemAtPath:).

Files created using other APIs inherit the default protection level unless explicitly updated with setAttributes. For example:

FileManager.default.setAttributes(
    [FileAttributeKey.protectionKey: FileProtectionType.complete],
    ofItemAtPath: path
)

A default protection level can also be set for the entire app by configuring the NSFileProtectionKey in the app's Info.plist file.

User Exposure

By default, files in the app's private sandbox are not exposed to the user. However, apps can expose files to the user by saving them in specific directories such as the Documents directory and enabling file sharing in the app's Info.plist using the UIFileSharingEnabled ("Application supports iTunes file sharing") and LSSupportsOpeningDocumentsInPlace ("Supports opening documents in place") keys set to YES.

They can also use APIs like UIDocumentPickerViewController to allow users to export files.