Search code examples
swifticloud

Force iOS to upload a file to iCloud


I am writing an app that synchronizes data between different devices using iCloud documents. The problem I'm having is that after saving the file to iCloud from one device (Both devices are simulators in this case, registered to the same iCloud account), the file seems to not exist from the other device (or it takes more than 30-40 minutes to it to "arrive", while both simulators are on).

I thought maybe there is an API to force file synchronization, but appears there's no such API (on NSFileManager).

The code I used to write the file is (I uploaded only the relevant code):

currVersionDir = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent(DBVersionURL, isDirectory: false);
if (!NSFileManager.defaultManager().fileExistsAtPath((currVersionDir?.path)!))
{
 NSFileManager.defaultManager().createFileAtPath((currVersionDir?.path!)!, contents: nil, attributes: nil);
}
let coord = NSFileCoordinator();
let err : NSErrorPointer = NSErrorPointer();
coord.coordinateWritingItemAtURL(currVersionDir!, options: .ForMerging, error: err, byAccessor: {(url : NSURL) in
do {
 try dbVersion.writeToFile(currVersionDir!.path!, atomically: true, encoding: NSUTF8StringEncoding);
 } catch { retVal = false; }
});

The code used to read the file:

let coord = NSFileCoordinator();
let err : NSErrorPointer = NSErrorPointer();
do{
 if (currDir != nil && isOnIcloud){
  try NSFileManager.defaultManager().startDownloadingUbiquitousItemAtURL(currDir!);
 }
} catch { }
coord.coordinateReadingItemAtURL(currVersionDir!, options: .WithoutChanges, error: err, byAccessor: {(url : NSURL) in
do {
 currDbVersion = try NSString(contentsOfFile: currVersionDir!.path!, encoding: NSUTF8StringEncoding) as String;
} catch { }
});

The use of the coordinator is because of Apple's instructions, even without it doesn't work.

When this code runs on a specific device, it works -- the file is written, and can be read. When this code runs on one device, the device is turned off after a while, and another device starts the app later -- nearly always the file is not accessible from the other devices.

Is there any command I can issue that will force the file to be uploaded? Do you have any idea what prevents it from being uploaded immediately?

I'm new to iCloud and it seems to misbehave, while I'm sure it's something I'm doing wrong.. Thanks!


Solution

  • It seems like the issue is happening only when using the iOS simulator. When using two actual devices the synchronization works in reasonable time, so I assume this is a bug in the simulator.

    In addition, Apple recommends creating the file locally, in a temporary library, and calling NSFileManager.defaultManager().setUbiquitous(... for moving the file to iCloud (in the code above I create the file initially on the iCloud library.

    Hope other people will find it useful, I burnt a few days on this issue...