2

When the user enables iCloud in my app, I need to move all local files to iCloud. Here, I use setUbiquitous:itemAtURL:destinationURL:error: to move each file. The problem is, if (for any local file) the same file URL already exists on iCloud, this method fails.

My question is, how can I determine which file is newer (local vs iCloud) so that I can either overwrite the iCloud version or discard the local version for each file? Or, could I somehow force iOS to perform the upload and set the file state into conflict on iCloud so that my conflict resolution methods would take over and handle this?

Anton
  • 3,998
  • 25
  • 40

1 Answers1

2

FWIW, from Apple's dox they suggest an all-or-nothing iCloud approach - i.e., ask the user at one point whether or not iCloud should be enabled or not and then don't change.

That said, for your situation I'd suggest the following steps after the user enables iCloud:

1) Run an NSMetaDataQuery with ubiquitous scope to get the list of files already in the cloud for this app. (Note that the query must be run on the main thread or you get nothing back).

2) If you have a file of the same name, you can use the last modified date key (NSMetadataItemFSContentChangeDateKey) in the NSMetaData to figure out which one you should use (or whatever approach you want to use for resolving the conflict)

3) If the file is not already in the cloud, then use the setUbiquitous method to put it there.

Mike M
  • 4,358
  • 1
  • 28
  • 48
  • I've tried using this approach with last modified dates, but it's using the date and time of each device--instead of any absolute time suitable for such a comparison. Even using UTC/GMT times only, changing the date or time on any device using my app can throw this off. Do you have any suggestions for dealing with this? – Anton Feb 19 '13 at 17:39
  • @Anton, in my testing, whenever there is a iCloud-detected UIDocument conflict the document with the last edit is considered the "current" version and the conflicting versions are the older ones. However note that if you save/close before resolving the conflicts that will always make the local version "current". – Mike M Feb 19 '13 at 19:23
  • This is good information about document conflicts, but in my case I'm afraid I won't run into this comparing a local and remote file in this way. This is because `setUbiquitous:` won't upload a file to a location where one already exists. However, I wonder if there is a way to upload a file to an existing file and force iCloud to treat it as a conflict? – Anton Feb 19 '13 at 19:37
  • If the file already exists, have you tried just opening and writing to it? I'm wondering if that would be enough to have iCloud consider it a conflict. – Mike M Feb 19 '13 at 20:33
  • Great idea! Sadly, the results are a no-go: it treats it as a valid edit and not as a conflict. – Anton Feb 20 '13 at 02:35
  • @MikeM For step 2 that you gave above, how would you compare the NSMetadataItemFSContentChangeDateKey values? The local file does not have an NSMetadataItem associated with it. Would you have to compare the NSMetadataItemFSContentChangeDateKey of the iCloud file with the URLResourceKey.contentModificationDateKey value of the local file? – daniel Sep 18 '18 at 01:49
  • @ShinehahGnolaum whatever works - I'd probably get the file attributes via the NSFileManager and use FileAttributeKey.modificationDate for the date. – Mike M Sep 18 '18 at 17:34