iOS Fragmentation – iCloud style

To be clear from the start, I’m talking from development’s point of view, not percentage of devices getting new OS versions. Just good old code :)

Since iOS version 5.x there is a fragmentation in iOS that I really don’t like. Since my app was rejected from the appstore I started reading more about iCloud and how it has been implemented in different iOS versions.

Official reason why my app was rejected is:

We found that your app does not follow the iOS Data Storage Guidelines, which is required per the App Store Review Guidelines.

That sounded OK, I’m not complaining, I was unaware of iCloud integration to be honest (or how deep the integration is). In the same message from apple, I’ve got a hint to take a look at this Q&A.

To make a long story short:

  1. iOS 4.x: There is no iCloud sync, so you can store your files in /Documents folder without any problems.
  2. iOS 5.0: Everything in /Documents folder is synced with iCloud, so you have to put your files in /Cache. The only problem is that when your iDevice runs out of space, your cache folder will be deleted most likely.
  3. iOS 5.0.1: You can set a “don’t sync” this file/folder inside your /Documents folder. That is pretty good, but this code is only for this version
    #import <sys/xattr.h>
    - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {
    
      assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
    
      const char* filePath = [[URL path] fileSystemRepresentation];
      const char* attrName = "com.apple.MobileBackup";
    
      u_int8_t attrValue = 1;
    
      int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    
      return result == 0;
    
    }

    Apple marked this code as deprecated for later version of iOS

  4. iOS 5.1+ (currently 5.1 and 5.1.1): You can also flag files or folders, so that they are not synced to iCloud. Here is the snippet:
    - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {
      assert([[NSFileManager defaultManager] fileExistsAtPath: [URL path]]);
    
      NSError *error = nil;
      BOOL success = [URL setResourceValue: [NSNumber numberWithBool: YES]
                                    forKey: NSURLIsExcludedFromBackupKey error: &error];
    
      if(!success){
        NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
      }
    
      return success;
    
    }

Also in my app I’ve added a small piece of code that handles iOS updates. For example if user had my app with 5.0 and then updates to 5.0.1 or similar.
After applying these snippets to my app it was approved without problems.

So the only thing I’m wondering is why isn’t iCloud handling as elegant as most of iOS features? :)
It’s not that bad, but I don’t like it.