Contents

Reducing your app’s disk usage

Measure and minimize the space your app uses to store its files.

Overview

People use multiple apps on a device, to create and access important content. Minimize your app’s disk usage to make more space for a person’s content, and to allow someone to install more apps on their device. Store recoverable data in purgeable locations, so that the system can free up space when it needs to.

Review your app’s disk usage

To see the storage used by each app on your device, open Settings and choose General > Storage.

[Image]

Tap on your app to see a breakdown of how the app’s bundle, documents, and data contribute to the overall disk usage.

Gather metrics on disk usage

Use MXDiskSpaceUsageMetric to gather metrics on the number of files in your app’s container, and the disk space they occupy including space in the cachesDirectory:

import MetricKit

class MetricService: NSObject, MXMetricManagerSubscriber {
    let metricManager: MXMetricManager = MXMetricManager.shared
    
    override init() {
        super.init()
        metricManager.add(self)
    }
    
    func didReceive(_ payloads: [MXMetricPayload]) {
        payloads.forEach({ payload in
            if let diskUsage = payload.diskSpaceUsageMetrics {
                // Analyze your app's disk usage.
            }
        })
    }
}

Use purgeable folders for recoverable content

When you download or otherwise generate content that your app can recover if it needs to, store that content in the cachesDirectory or the temporaryDirectory. The system automatically deletes content in the cachesDirectory and temporaryDirectory — an operation known as purging — when it detects that disk space is low.

let cacheDownloadTask = URLSession.shared.downloadTask(with: cacheURL) {
    fileURL, response, error

    // Check for download errors and handle them.

    guard let temporaryURL = fileURL else { return }
    do {
        let destinationURL = URL.cachesDirectory.appendingPathComponent(temporaryURL.lastPathComponent)
        try FileManager.default.moveItem(at: temporaryURL, to: destinationURL)
    }
    catch {
        // Handle the error.
    }
}

Manage local copies of iCloud files

When a person isn’t using the local copy of a file that’s stored in iCloud, call evictUbiquitousItem(at:) to remove the local copy while keeping the original on iCloud:

func removeLocalDocument(at localURL: URL) throws {
    let resources = try localURL.resourceValues(forKeys: [.ubiquitousItemIsUploadedKey])
    guard resources.ubiquitousItemIsUploaded == true else { return }
    FileManager.default.evictUbiquitousItem(at: localURL)
}

You can subsequently retrieve the file from iCloud by calling startDownloadingUbiquitousItem(at:):

func fetchRemoteDocument(for localURL: URL) throws {
    let resources = try localURL.resourceValues(forKeys: [.ubiquitousItemIsUploadedKey])
    guard resources.ubiquitousItemIsUploaded != true else { return }
    FileManager.default.startDownloadingUbiquitousItem(at: localURL)
}

Copy files by creating clones

When you use copyItem(at:to:) to copy a file on an APFS volume, the system creates a clone of the file. The clone refers to the original file’s content, so it uses less space on disk than if you duplicate the file through other methods. MXDiskSpaceUsageMetric accounts for clones in its calculations of the disk space used by your app.

For more information, see About Apple File System.

See Also

Disk usage