The Mental Blog

Software with Intellect

0 notes

The Mysterious Case of iCloud Drive and the Splitting Folders

Update 25th Feb 2015: Looks like Apple have addressed this. My tests now lead to two copies of conflicting files (eg. File and File 2) rather than two directories. This is similar to how Dropbox does it, and preferable in my view.

Apple introduced iCloud Drive with iOS 8, supplanting the original iCloud file sync. Since the introduction, I have started observing some odd behavior in my tests with Ensembles. Occasionally, when diving into the ~/Library/Mobile Documents folder on Yosemite, I would observe multiple folders where I had expected just one. For example, if Ensembles was working in an iCloud folder called ‘Main’, a peek in Mobile Documents regularly revealed 'Main’, but also 'Main 2’ and 'Main 3’.

Initially, I chalked this down to some strange side-effect related to migrating between the original iCloud, and iCloud Drive. But the problem kept arising, well after the migration was complete. It had to be occurring for other reasons.

Yesterday, I decided to get to the bottom of it. I ran some command line experiments. With two Macs set up, and fully synced, I made simultaneous changes in Mobile Documents, and observed the results after the two machines synced up again.

The good news is that both devices always ended up having the same folders and files. The bad news is that it wasn’t that difficult to trigger a directory to split into two, like the broomsticks in Fantasia.

To do it, you have to make concurrent changes on two machines in iCloud Drive. I did this by issuing commands like this

mkdir Dir ; echo 11 > Dir/File ; rm -r Dir ; mkdir Dir ; echo 12 > Dir/File

on one machine, while simultaneously running this on the second machine

mkdir Dir ; echo 21 > Dir/File ; rm -r Dir  ; mkdir Dir ; echo 22 > Dir/File

By pressing the enter key at the same time on each machine, I could be pretty sure the events would be considered concurrent by iCloud Drive.1 After waiting a minute or so for iCloud Drive to sync, I would observe the resulting directories and files.

Here’s what I learned:

  1. If you never remove or move folders, you never get the 'split’ folders.
  2. Files never split into two. You always end up with one file, even if you make concurrent changes to it.
  3. You can end up with split folders if you remove or move a folder on one machine, and then re-add it, while at the same time manipulating files in the directory on a second device.
  4. New or changed files tend to end up in the folder with the highest number (eg 'Main 2’ not the original 'Main’).
  5. Messing with directories alone never seems to result in splits. It seems you have to manipulate files contained in the directories to trigger the issue.

It’s difficult to know exactly what is happening, but it seems iCloud Drive is generating extraneous folders during conflict resolution. It probably goes something like this…

  1. iCloud Drive applies the directory removal from the first device.
  2. It then goes to apply the file manipulation from the second device, but the folder is gone, so it resurrects a new folder for the file.
  3. The directory re-creation from the first devices is now applied, generating a second folder at that path.

For many apps, this is no big deal, and may never arise. But if your app stores data at specific paths in iCloud Drive, it could very easily become a problem. This is the case for Ensembles, for example.

If you are removing and re-adding folders in your app at a specific path in iCloud Drive, don’t be surprised if one day you discover the data is gone, and moved into a second version of the folder at a different path.

I consider this pretty undesirable behavior. No other sync solution I know does this. Dropbox doesn’t — although Dropbox does do something similar to this with files rather than directories — and the original iCloud file sync also didn’t do it.

Maybe Apple thought it was better to resurrect data than lose it entirely, but if the path of the most recent data is not the path that your app expects, it is a major hurdle. I would much prefer the directory trees just be merged, with all paths intact.

I’ve submitted this as a bug via Radar; if you agree with me, you could dupe it (#18967410).


  1. Note that in order to be considered 'concurrent’, two sets of changes do not necessarily have to happen at the same time — they could even happen months apart. To be concurrent, one set of changes has to be applied before the effects of the other set have been incorporated. In a Git analogy, the changes would be taking place in separate branches.