Prevent your app's files from being included in iCloud Backup
In this blog post, you will learn which files of your app are automatically included in a Backup (iTunes or iCloud) and how to exclude specific files.
Motivation
This is important to know if you want to prevent sensitive data from being backed up by Apple's iCloud service. Also, you want to reduce the space and time that backups take to create.
Golden rule: any file that can be re-created or downloaded should be excluded from the backup. This is particularly important for large media files.
Which directories are included in a Backup?
An iOS app can create and save files in various directories of its app data container.
There are four major directories.
Directory | Type of Files to be stored | Part of iCloud Backup Data |
Documents | User-visible files | Yes |
/Library | Top-level directory for any files that are not user data files | Yes with the exception of the Caches subdirectory |
/Library/Application Support | App-created support files | Yes |
/Library/Caches | Purgeable or transient content needed longer than temporary data, but not as long as a support file | No |
/tmp | Temporary data | No |
The iOS system will create all those directories except for Library/Application Support
and therefore you would need to create the directory if you need it.
let appSupportDir = URL.applicationSupportDirectory
if !FileManager.default.fileExists(atPath: appSupportDir.path()) {
try? FileManager.default.createDirectory(at: appSupportDir, withIntermediateDirectories: true)
}
iOS 16 provides convenient APIs to get URL
s' for such directories but if you have to support lower iOS versions then check out this dependency-free Swift package that provides a backport of those APIs.
Back to the topic.
API to exclude resources from Backup
You can exclude directories & files from the backup by setting isExcludedFromBackup
resource value.
var newFile = URL.documentsDirectory.appending(path: "News.txt")
try "Hello, World!".write(to: newFile, atomically: true, encoding: .utf8)
var resource = URLResourceValues()
resource.isExcludedFromBackup = true
try newFile.setResourceValues(resource)
Important facts to know about this API
- Limited applicability
This property is only useful for excluding cache and other application support files which are not needed in a backup. Some operations commonly made to user documents will cause this property to be reset to false and so this property should not be used on user documents.
- Not a guaranteed behavior
The
isExcludedFromBackup
resource value exists only to provide guidance to the system about which files and directories it can exclude; it’s not a mechanism to guarantee those items never appear in a backup or on a restored device.
- You have to call it on every save
Because certain file operations can reset resource values, make sure you set an excluded file’s resource values each time you save it.
- API works only on existing files
Note that I called setResourceValues
after the file got created. You cannot call setResourceValues
before the actual file exists on the file system. Otherwise, an error gets thrown.
Further Tips
You can create an extension on URL
for convenience.
extension URL {
mutating func excludeFromBackup() throws {
var resource = URLResourceValues()
resource.isExcludedFromBackup = true
try self.setResourceValues(resource)
}
}
The code usage becomes much simpler:
var newFile = URL.documentsDirectory.appending(path: "News.txt")
try? "Hello, World!".write(to: newFile, atomically: true, encoding: .utf8)
newFile.excludeFromBackup()
Furthermore:
To indicate the system can exclude a group of related files from iCloud Backup, move those files into a directory and update the directory’s
isExcludedFromBackup
resource value.If you create an excludable directory inside the app container’s
Library
then consider naming the directory with the app’s bundle identifier to avoid potential conflicts with directories the system may create in the future.
If you want to deepen your knowledge about iOS Storage and best practices then I recommend the following Apple Tech Talk:
Additionally, I recommend reading Apple's article Optimizing Your App’s Data for iCloud Backup.