Unable to download file from iCloud Documents.

I am unable to download file from iCloud Documents from my swift project. I was able to successfully upload the file to iCloud Documents but now when I try to download same file at the uploaded path. It is giving me error that I don't have permission to view the file.

Please find exact error below.

[ERROR] couldn't fetch remote operation IDs: NSError: Cocoa 257 "The file couldn’t be opened because you don’t have permission to view it." "Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""

Answered by DTS Engineer in 821003022

I did reproduce the following error when playing your project:

[ERROR] couldn't fetch remote operation IDs: NSError: Cocoa 257 "The file couldn’t be opened because you don’t have permission to view it." "Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""

I believe this is a log noice that you can safely ignore, as mentioned in On Log Noise.

Other than that, I see several issues in your project.

First, your following code uses a wrong search scope:

query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]

Since your data isn't in the Documents folder, the search scopes should be NSMetadataQueryUbiquitousDataScope:

query.searchScopes = [NSMetadataQueryUbiquitousDataScope]

Secondly, your following code doesn't retain the metadata query (NSMetadataQuery):

@IBAction func didTapOnButtonRestore(_ sender: Any) {
    ...
    iCloudFileMonitor().startMonitoring(for: "Sample.txt")
}

iCloudFileMonitor() will be released after your app exits didTapOnButtonRestore, and so its member variable metadataQuery will be released as well. To fix that, consider creating a member variable to hold the monitor:

class ViewController: UIViewController {
    private let monitor = iCloudFileMonitor()
    ...
    
    @IBAction func didTapOnButtonRestore(_ sender: Any) {
        ...
        //iCloudFileMonitor().startMonitoring(for: "Sample.txt")
        monitor.startMonitoring(for: "Sample.txt")
    }
}

With that, the metadata query should monitor the data scope of your ubiquity container, and you can do your data backup or restoration based on the query result.

Fore more details about how to use NSMetadataQuery, see the following sample code:

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

The message indicates that you are trying to access a file that you don't have access, probably because the file is outside of your app's sandbox.

It is hard to comment meaningfully without looking into your implementation details though. If you can provide a minimal project that contains only the code relevant to the issue, with detailed steps to reproduce the issue, folks here may be able to help more effectively.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Please find code snippet I am using to download file from iCloud Documents.

    private var metadataQuery: NSMetadataQuery?

    func startMonitoring(for fileName: String) {
        metadataQuery = NSMetadataQuery()
        guard let query = metadataQuery else { return }

        query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]
        query.predicate = NSPredicate(format: "%K == %@", NSMetadataItemFSNameKey, fileName)

        NotificationCenter.default.addObserver(self, selector: #selector(queryDidUpdate(_:)), name: .NSMetadataQueryDidUpdate, object: query)
        NotificationCenter.default.addObserver(self, selector: #selector(queryDidFinish(_:)), name: .NSMetadataQueryDidFinishGathering, object: query)

        query.start()
    }

    func stopMonitoring() {
        metadataQuery?.stop()
        NotificationCenter.default.removeObserver(self)
        metadataQuery = nil
    }

    @objc private func queryDidUpdate(_ notification: Notification) {
        processQueryResults()
    }

    @objc private func queryDidFinish(_ notification: Notification) {
        processQueryResults()
    }

    private func processQueryResults() {
        guard let query = metadataQuery else { return }
        query.disableUpdates()

        for item in query.results {
            if let metadataItem = item as? NSMetadataItem,
               let fileURL = metadataItem.value(forAttribute: NSMetadataItemURLKey) as? URL {
                handleFileMetadata(metadataItem, fileURL: fileURL)
            }
        }

        query.enableUpdates()
    }

    private func handleFileMetadata(_ metadataItem: NSMetadataItem, fileURL: URL) {
        // Access security-scoped resource if needed
        let accessGranted = fileURL.startAccessingSecurityScopedResource()
        defer { fileURL.stopAccessingSecurityScopedResource() }
        
        guard accessGranted else {
            print("Failed to access the security-scoped resource for file: \(fileURL.lastPathComponent)")
            return
        }

        // Check file availability
        checkFileAvailability(for: metadataItem)

        // Monitor download progress
        if let downloadProgress = metadataItem.value(forAttribute: NSMetadataUbiquitousItemPercentDownloadedKey) as? Double {
            print("Download progress for \(fileURL.lastPathComponent): \(downloadProgress)%")
        }
    }

    private func checkFileAvailability(for metadataItem: NSMetadataItem) {
        if let isDownloaded = metadataItem.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? Bool, !isDownloaded {
            print("File is not downloaded. Attempting to download...")
            if let fileURL = metadataItem.value(forAttribute: NSMetadataItemURLKey) as? URL {
                downloadFileIfNeeded(at: fileURL)
            }
        }
    }

    private func downloadFileIfNeeded(at url: URL) {
        do {
            try FileManager.default.startDownloadingUbiquitousItem(at: url)
            print("Download started for file at: \(url)")
        } catch {
            print("Error starting download: \(error.localizedDescription)")
        }
    }
}

I did reproduce the following error when playing your project:

[ERROR] couldn't fetch remote operation IDs: NSError: Cocoa 257 "The file couldn’t be opened because you don’t have permission to view it." "Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""

I believe this is a log noice that you can safely ignore, as mentioned in On Log Noise.

Other than that, I see several issues in your project.

First, your following code uses a wrong search scope:

query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]

Since your data isn't in the Documents folder, the search scopes should be NSMetadataQueryUbiquitousDataScope:

query.searchScopes = [NSMetadataQueryUbiquitousDataScope]

Secondly, your following code doesn't retain the metadata query (NSMetadataQuery):

@IBAction func didTapOnButtonRestore(_ sender: Any) {
    ...
    iCloudFileMonitor().startMonitoring(for: "Sample.txt")
}

iCloudFileMonitor() will be released after your app exits didTapOnButtonRestore, and so its member variable metadataQuery will be released as well. To fix that, consider creating a member variable to hold the monitor:

class ViewController: UIViewController {
    private let monitor = iCloudFileMonitor()
    ...
    
    @IBAction func didTapOnButtonRestore(_ sender: Any) {
        ...
        //iCloudFileMonitor().startMonitoring(for: "Sample.txt")
        monitor.startMonitoring(for: "Sample.txt")
    }
}

With that, the metadata query should monitor the data scope of your ubiquity container, and you can do your data backup or restoration based on the query result.

Fore more details about how to use NSMetadataQuery, see the following sample code:

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Unable to download file from iCloud Documents.
 
 
Q