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