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.
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.
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.
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.
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!
You need to do 2 things
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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With