Prevent app rejection caused by iCloud storage

Prevent app rejection caused by iCloud storage

Introduction

Since iOS5 and 6, a lot of developers had some trouble with updating their applications. This is because their app stores a lot of data that is recursive or could be easily recreated. Therefore, their app gets rejected, but why?
Apple will tell you, your app has been rejected for the reason that your app does not comply to the iOS Storage guidelines, but why? It worked in your previous version?
This is, because most iOS users have an iCloud setup, meaning that if a user does something, like create a funny image, or the developer unzips some images to the documents directory, it will automatically be backed up to iCloud..

So imagine some big Filesharing application, backing up everything you open or use to your iCloud, your free 5 gigabytes will be swarmed in a second! That's why Apple started rejecting most of the updated apps these days that don't comply to their rules.

What are Apple's rules? 

Actually, it's quite "basic", anything that can be "generated" again by the developer, shouldn't be backed up to iCloud, but there are some more questions.

What if I unzip a file that's quite large, and don't want to redo that action every time the user is done with using the images/sounds?

Tada: That's what this blog is about, I'm going to explain you, how to still store data on the user's device, but NOT back it up to iCloud.
Let's say you have a 150 megabyte zipfile full of sounds/images that you want to unzip at startup, you have to unzip them to the Documents or Library folder, but when you do that, every single path get's flagged to synchronize to iCloud.
To prevent this, there were several solutions provided by Apple, by saving it to the Library folder etc, but that all changed. Now you have to setup a "Key" onto a specific Path or Directory that you do NOT want to be backed-up to iCloud. So how does one do such a thing?

That's an easy solution.. Basically, you can use this category.

This is a simple category on NSFileManager, it only has one method that should set that key on a specific file path.

How does it work?
Let's say you persist a Database with data into the Documents directory, but you don't want it to be backed up to iCloud, because that's why you are reading this.

Here's an example

Code:

+ (void) checkAndCreateDatabase {
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

// Create a FileManager object, we will use this to check the status  of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:[DatabaseController databasePath]];

// If the database already exists then return without doing anything
if(success) 
{
   return;
}

// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package

NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[DatabaseController databaseName]];

// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:[DatabaseController databasePath] error:nil];
/* This is our class from the category you downloaded above */
[fileManager addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:[DatabaseController databasePath]]];
/* Please make sure you make an NSURL fileURLWithPath and not an NSURL urlWithPath, otherwise it WON'T WORK!! */

}

+ (NSString *) databaseName {

return @"OurDatabaseName.sqlite";

}

 

So basically, it will check if your iOS supports this feature for adding it to a file, if it doesn't, it won't do nothing, and there will be no problem, if the user uses iOS 5.0.1, it will use the older method to set it, and if it supports iOS 5.1, then it will use the latest method and return a BOOL value wether it worked or not.
So basically, you can assign the category method to a BOOL and check if it succeeded or not.

Hope that helped, and if anyone has questions about preventing files to be backed up to iCloud, tweet or mail us, or use the comments!