2

My app produces specific image files that I want to copy to the user's iCloud Drive account.

As per my understanding, a simple call to setUbiquitous() should trigger iCloud to synch files between devices so that the user can get the files exposed on its Mac finder.

My code is as follows:

  class func write(image data: Data, to path: String) -> URL? {
        var path = "\(path).\(ext)"

        let fullPath = getDocumentsDirectory().appendingPathComponent(path)

        do {
            try data.write(to: fullPath, options: [.atomic])

            // Make it ubiquitous

                if var ubiquityUrl = FileManager.default.url(forUbiquityContainerIdentifier: nil) {
                    ubiquityUrl = ubiquityUrl.appendingPathComponent("Documents/\(path)")
                    setUbiquitous(localUrl: fullPath, ubiquityUrl: ubiquityUrl)
                    print("Setting ubiquitous at \(ubiquityUrl)")

                }
                else {
                    print("Unable to access iCloud Account")
                    print("Open the Settings app and enter your Apple ID into iCloud settings")
                }

            return fullPath
        }
        catch let error {
            print("write(image:to:): failed with error \(error) – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding")
            return nil
        }
    }

    class func setUbiquitous(localUrl: URL, ubiquityUrl: URL) {

        do {
            try FileManager.default.setUbiquitous(true, itemAt: localUrl, destinationURL: ubiquityUrl)
        } catch let error {
            print("*** error: setUbiquitous failed \(error.localizedDescription)")
        }
    }

Unfortunately, I did not yet succeed in making this happened so far. I've got this error:

Setting ubiquitous at file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~***~Tree/Documents/3481-4.jpg
*** error: setUbiquitous failed The file “3481-4.jpg” couldn’t be saved in the folder “***Tree” because a file with the same name already exists.

How should I update existing files?

Also, I see no files in the iCloud management Settings app as my app isn't listed (though it is listed in the pen before as using iCloud).

Side note:

According to this, I added the following in plist file under the key NSUbiquitousContainers, but I'm not sure what role it plays or if its really related to my usage of iCloud.

<dict>
    <key>com.***.Tree</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
        <key>NSUbiquitousContainerName</key>
        <string>AppleTree</string>
    </dict>
</dict>
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95
  • I am having similar issues. Did you resolve your issues? I am using a entitlements file for my app, and I question whether I also need to set the Info.plist data as you describe above. – James Cramer Feb 21 '18 at 20:23
  • Nope. I didn’t come up with a solution yet. I asked a friend to have a look. Waiting for that. – Stéphane de Luca Feb 21 '18 at 20:27
  • I ended up getting it to work yesterday. I have both the .entitlements file generated by Xcode 9, and I have the Info.plist key you referenced above. It started working after I changed the bundle ID of my project and Xcode automatically provisioned another certificate. After adding a file to the ubiquitous container Documents folder and using setubiquitous it worked. – James Cramer Feb 22 '18 at 14:40
  • maybe [this answer](https://stackoverflow.com/a/32415833) will help you – Sergei Volkov Jan 10 '19 at 23:55
  • 1
    Delete the existing file before calling setUbiquitous(): ```try? fileManager.removeItem(at: ubiquityUrl)``` – pipacs Jun 09 '21 at 21:08

0 Answers0