iosswifticloud-drive

Saving a file to icloud drive


I'm trying to save a file to icloud drive. I'm going for the simple version where I don't let the user pick where to save the file, I just save it in the root directory of icloud drive. Here's the code I'm using:

func exportToFiles() {
    for page in pages {
            let filename = getDocumentsDirectory().appendingPathComponent((page.title ?? "Untitled") + ".png")
        if let image = exportImage(page: page, dpi: 300) {
            if let data = image.pngData() {
                try? data.write(to: filename)
            }
        }
    }
}

func getDocumentsDirectory() -> URL {
    let driveURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
    return driveURL!
}

And I have this in my Info.plist file:

<key>NSUbiquitousContainers</key>
<dict>
        <key>iCloud.com.mysite.myapp</key>
        <dict>
                <key>NSUbiquitousContainerIsDocumentScopePublic</key>
                <true/>
                <key>NSUbiquitousContainerName</key>
                <string>myapp</string>
                <key>NSUbiquitousContainerSupportedFolderLevels</key>
                <string>Any</string>
        </dict>
</dict>

In the UI it looks like this works, because there's a slight pause after I tap my button. But when I look in my files, there's nothing there. What am I doing wrong?


Solution

  • You have to check and create "Documents" folder and also it's good practice to handle errors:

    if let containerUrl = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") {
        if !FileManager.default.fileExists(atPath: containerUrl.path, isDirectory: nil) {
            do {
                try FileManager.default.createDirectory(at: containerUrl, withIntermediateDirectories: true, attributes: nil)
            }
            catch {
                print(error.localizedDescription)
            }
        }
        
        let fileUrl = containerUrl.appendingPathComponent("hello.txt")
        do {
            try "Hello iCloud!".write(to: fileUrl, atomically: true, encoding: .utf8)
        }
        catch {
            print(error.localizedDescription)
        }
    }