Jamie Le Souëf
Jamie Le Souëf

Reputation: 59

Access iCloud documents in iOS

I'm trying to access documents that I've put into my iCloud Documents folder on my Mac in an iOS app but I can't work out how to.

let manager = FileManager.default  
let dir = manager.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
let files = try? FileManager.default.contentsOfDirectory(at: dir!, includingPropertiesForKeys: nil, options: [])
print(files) //(Optional([])

I have enabled iCloud Documents in my apps capabilities, and I know there are files in my Documents folder on my desktop..

I'm clearly missing something here..

Thanks in advance

Upvotes: 1

Views: 4723

Answers (2)

jonkimsr
jonkimsr

Reputation: 39

  1. Create iCloud Container for the iCloud

    a. login to developer.apple.com

    b. go to Identifiers and add iCloud Containers.

    c. You can't delete iCloud Containers once created.

  2. Create App ID that includes iCloud capabilities

    a. Create App ID

    b. Add iCloud support with explicit Bundle ID.

    c. Create Provisioning Profile and download it to Xcode.

  3. Configure the Capabilities in Xcode

    a. Click and add iCloud support from "+ Capability"

    b. For iCloud document storage, select iCloud Documents and select the Container you created.

    c. Add NSUbiquitousContainers key in Info.plist

    d. "MyApp" inside is what will display as foldername.

<key>NSUbiquitousContainers</key>
    <dict>
        <key>iCloud.com.example.MyApp</key>
        <dict>
            <key>NSUbiquitousContainerIsDocumentScopePublic</key>
            <true/>
            <key>NSUbiquitousContainerSupportedFolderLevels</key>
            <string>Any</string>
            <key>NSUbiquitousContainerName</key>
            <string>MyApp</string>
        </dict>
    </dict>
  1. Test Code Snippet

    a. Try below quick and dirty test.

    let driveURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
    if let unwrappedFU = driveURL {
        print("iCloud available")
        let fileURL = driveURL!.appendingPathComponent("test.txt")
        try? "Hello word".data(using: .utf8)?.write(to: fileURL)
    } else {
        print("iCloud not available")
    }
  1. Writing to your App Document Folder is different from iCloud document storage. You can make your App Document folder visible. By adding to Info.plist 2 additional property.

    a. Add Support opening documents in place : YES

    b. Supports opening documents in place : YES

    c. Test using Tim's code snippet. https://www.youtube.com/watch?v=p1UNnsodJxc


    let file = "\(UUID().uuidString).txt"
    let contents = "Some text..."
    
    let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let fileURL = dir.appendingPathComponent(file)
    
    do {
        try contents.write(to: fileURL, atomically: false, encoding: .utf8)
    }
    catch {
        print("Error: \(error)")
    }

NOTE: You will notice App Folder in the Files App in "On My iPhone" folder. That is App's Document folder you exposed to user. You will also notice your app folder in iCloud Drive folder. Those 2 folders are different. You should use your App Folder and use iCloud Drive folder as your export destination that way you don't have to deal with access control much.

CAVEAT: Oddly none of this worked including resigning into iCloud on the iPhone. Even though it was working on the simulator. It only started working when iPhone was rebooted in my case.

Upvotes: 1

user13084305
user13084305

Reputation:

 func clickFunction(){

            let DOCUMENTS_DIRECTORY = "Documents"
            if let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent(DOCUMENTS_DIRECTORY){
                if let pathComponent = iCloudDocumentsURL.path as? String {
                    if (FileManager.default.fileExists(atPath: pathComponent, isDirectory: nil)) {

                        //Write it out the code of getting files
                        let fileManager = FileManager.default
                        let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.iCloudDocumentsURL!.path!)
                        while let file = enumerator?.nextObject() as? String {
                            //this this the file or document path.
                        }
                    }
                }
            }
        }

Upvotes: 0

Related Questions