21

I've been trying for over two days to write a file to iCloud drive. I have tried writing a simple text file directly, locally then moving it, using UIDocumentMenuViewController, etc. I'm not getting any errors with my code and stepping through debugger, it looks successful, but when I check to see if the file exists or at least the iCloud directory, there is nothing there. I tried on both the simulator and my iPhone, triggering iCloud synching, and everything else I can think of.

My main goal is to simply write a text file to the iCloud drive, which later will be "numbers" file

I have set up my plist file and my entitlements:

<key>NSUbiquitousContainers</key>
<dict>
    <key>iCloud.com.paul.c.$(PRODUCT_NAME:rfc1034identifier)</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerName</key>
        <string>myCloudTest</string>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

I have also bumped up by bundle version as stated at: Save iOS 8 Documents to iCloud Drive

I have tried dozens of tutorials with no luck. My latest code is based off of this sample: https://medium.com/ios-os-x-development/icloud-drive-documents-1a46b5706fe1

Here is my code:

@IBAction func ExportFile(sender: AnyObject) {

    var error:NSError?

    let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("myCloudTest")

    //is iCloud working?
    if  iCloudDocumentsURL != nil {

        //Create the Directory if it doesn't exist
        if (!NSFileManager.defaultManager().fileExistsAtPath(iCloudDocumentsURL!.path!, isDirectory: nil)) {
                //This gets skipped after initial run saying directory exists, but still don't see it on iCloud
                NSFileManager.defaultManager().createDirectoryAtURL(iCloudDocumentsURL!, withIntermediateDirectories: true, attributes: nil, error: nil)
        }
    } else {
        println("iCloud is NOT working!")
        //  return
    }

    if ((error) != nil) {
        println("Error creating iCloud DIR")
    }


    //Set up directorys
    let localDocumentsURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last as! NSURL

    //Add txt file to my local folder
    let myTextString = NSString(string: "HELLO WORLD")
    let myLocalFile = localDocumentsURL.URLByAppendingPathComponent("myTextFile.txt")
    let written = myTextString.writeToURL(myLocalFile, atomically: true, encoding: NSUTF8StringEncoding, error: &error)

    if ((error) != nil){
        println("Error saving to local DIR")
    }


   //If file exists on iCloud remove it
    var isDir:ObjCBool = false
    if (NSFileManager.defaultManager().fileExistsAtPath(iCloudDocumentsURL!.path!, isDirectory: &isDir)) {
        NSFileManager.defaultManager().removeItemAtURL(iCloudDocumentsURL!, error: &error)
    }

    //copy from my local to iCloud
    if (error == nil && !NSFileManager.defaultManager().copyItemAtURL(localDocumentsURL, toURL: iCloudDocumentsURL!, error: &error)) {
        println(error?.localizedDescription);
    }

Thank You for taking time for this.

Cheers, Paul

I ran some code on my iphone after the code above:

var error:NSError?
    let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil) //?.URLByAppendingPathComponent("myCloudTest")

    var fileManager: NSFileManager = NSFileManager()


    var fileList: NSArray = fileManager.contentsOfDirectoryAtURL(iCloudDocumentsURL!, includingPropertiesForKeys: nil, options: nil, error: &error)!
    var filesStr: NSMutableString = NSMutableString(string: "Files in iCloud folder \n")
    for s in fileList {

        println(s)
    }

and it prints out the path to my text file: file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~paul~c~myApp/MyTextFile.txt

My file is there, I just can't see it on iCloud drive.

Community
  • 1
  • 1
Paul C
  • 261
  • 1
  • 2
  • 8
  • Did you get this to work? I have the same problem and tried all the suggestions here worth no success. Please let us know if you've solved the problem by answering your own question here – RawMean Jan 18 '17 at 12:30
  • wondering if you got a chance to migrate this code to swift 3? Thanks! – Kaiusee Jan 23 '17 at 20:25

5 Answers5

7

I had this problem. I followed the advice here and I found that my Info.plist key was not correct. Once I changed it to iCloud.MY_BUNDLE_IDENTIFIER (i.e. copy the string from the CFBundleIdentifier key higher in Info.plist) it all started working.

Removing the .com from your key may fix your issue.

Community
  • 1
  • 1
Rick Andrews
  • 111
  • 1
  • 1
  • 4
  • For me, I had an issue where the iCloud container registered on the developer portal had a different capitalization than the app bundle identifier registered in App Store connect. I had to change iCloud.$(PRODUCT_BUNDLE_IDENTIFIER) under NSUbiquitousContainers in the info.plist to match capitalization on the iCloud container (iCloud.com.company.appname -> iCloud.com.company.AppName). Also make sure the id in the entitlements under "Ubiquity Container Identifiers" matches both including capitalization. And increment build number (and version number?) to see the changes update in Files app. – Thompsonmachine Sep 19 '22 at 20:47
4

FWIW:

I also found out that the name of the project within the bundle ID is important.

My project bundle ID was something like the following: aaa-bbb-ccc-ddd

I could not get the iCloud working.

Then I renamed it to: aaa-bbb.ccc-ddd

It started working.

Mehmet
  • 333
  • 2
  • 10
1

I believe I've found a way to get everything back in sync without constantly having to "bump" my bundle number. I've tried this multiple times while making changes within the "capabilities" area of key-value storage/iCloud Documents/CloudKit and it seems to work each time.

  1. Sign out of iCloud on your Mac
  2. Sign out of iCloud on your Simulator
  3. Sign back into iCloud on your Mac
  4. Sign back into iCloud on your Simulator
  5. Do a clean build from XCode (Shift-Cmd-K)

This appears to reset the synchronization of the folder structures when you're App is writing to your iCloud Documents directory - without having to touch your bundle number. It takes a little longer to do it, but I'm a little OCD and kinda prefer my initial App launch to start with a 1!

pscarnegie
  • 109
  • 1
  • 11
1

You need to do 2 things

  1. Do what @rick Andrews said: "Once I changed it to iCloud.MY_BUNDLE_IDENTIFIER (i.e. copy the string from the CFBundleIdentifier key higher in Info.plist)"
  2. Store your filed inside the containers subfolder Documents
struct iCloudStore {
    public var containerUrl: URL! {
        return fileManager.url(forUbiquityContainerIdentifier: nil)!
    }
    
    public var documents: URL! {
        return containerUrl.appendingPathComponent("Documents", isDirectory: true)
    }
    
    private let fileManager: FileManager = FileManager.default

    func store(url: URL) {
      // move ulr into the documents folder as a file
 let fileID = "\(UUID().uuidString).<#extension#>"
        let icloudFile = documents.appendingPathComponent(fileID, isDirectory: false)
        try fileManager.copyItem(at: url, to: icloudFile)
    }
}
doozMen
  • 690
  • 1
  • 7
  • 14
0

Maybe there's a rule for container's name.
I tried the following names.

○:iSheet
×:sheetFiles
×:com.myname.sheetFiles

grape100
  • 341
  • 4
  • 11