Search code examples
iosswiftfileicloud

File written on one device can't be opened on another


This question was asked five years ago with no resolution, so I'm assuming it isn't the same issue.

I have an app that writes several files to iCloud. I can see the current file updated on iCloud.com as well as on my Mac iCloud folder, but I only see the stub file(s) (the ones with the iCloud badge) in the Files folder on the second device. My app that tries to read the file fails with "file not found". If I open the file from the Files app which forces it to download, then run my app, it opens and reads the file just fine. So, my question is, how do I programmatically force the file to download. I tried appending ".icloud" to the file name and still shows as not found.

Any suggestions?


Solution

  • The basic idea is to check if the file is available. If it is not, just use startDownloadingUbiquitousItem(at url: URL) to ask for the file to start downloading.

    The whole iCloud documentation is available here: https://developer.apple.com/library/content/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForDocumentsIniCloud.html

    UPDATE: Please note this is a sample code solution intended to describe the basic idea.

    let fileManager = FileManager.default
    let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents", isDirectory: true)
    let iCloudDocumentToCheckURL = iCloudDocumentsURL?.appendingPathComponent("whateverFileName", isDirectory: false)
    
    guard let iCloudDocumentPath = iCloudDocumentsURL?.path else {
        return
    }
    
    if fileManager.fileExists(atPath: iCloudDocumentPath) {
        // Do something with the document
    } else {
        do {
            try fileManager.startDownloadingUbiquitousItem(at: iCloudDocumentToCheckURL!)
            // Will start downloading the file
        } catch let error as NSError {
            print("Unresolved error \(error), \(error.userInfo)")
        }
    }