Miralem Cebic
Miralem Cebic

Reputation: 1301

Prevent app of iCloud Backup

My App getting reverted from App Store Review because I not preventing my Data from iCloud Backup :/

I have the following code in app delegate:

-(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)fileURL {
if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
    NSLog(@"File %@ doesn't exist!",[fileURL path]);
    return NO;
}

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer isEqualToString:@"5.0.1"]) {
    const char* filePath = [[fileURL path] fileSystemRepresentation];
    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;
    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    NSLog(@"Excluded '%@' from backup",fileURL);
    return result == 0;
}
else if (&NSURLIsExcludedFromBackupKey) { //iOS 5.1 and later
    NSError *error = nil;
    BOOL result = [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
    if (result == NO) {
        NSLog(@"Error excluding '%@' from backup. Error: %@",fileURL, error);
        return NO;
    }
    else { // Succeeded
        NSLog(@"Excluded '%@' from backup",fileURL);
        return YES;
    }
} else {
    // iOS version is below 5.0, no need to do anything because there will be no iCloud present
    return YES;
}
}

// now call  above method from where you are storing your files/folders in NSDocumnetsDirectory
-(BOOL) doNotBackUpMyFolderOrFile {

NSString *applicationCacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
                                                                     NSUserDomainMask,
                                                                     YES) lastObject];

NSURL *pathURL= [NSURL fileURLWithPath: applicationCacheDir isDirectory:YES];


NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsURL = [paths lastObject];


NSURL *tmpURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];

if ([self addSkipBackupAttributeToItemAtURL:documentsURL] &&
    [self addSkipBackupAttributeToItemAtURL:pathURL]      &&
    [self addSkipBackupAttributeToItemAtURL:tmpURL] ) {
    return YES;
}
return NO;
}

I call [self doNotBackUpMyFolderOrFile] in -application:didFinishLaunchingWithOptions:

When I opening the Terminal and navigate to

/Library/Application Support/iPhone Simulator/7.1/Applications/9224585D-9B05-44E5-8A84-1AEFB56E4579

and type ls -al -@

Terminal prints

total 176
drwxr-xr-x@  8 user  staff    272 Jul  8 16:18 .
com.apple.installd.container_bundle_id     35
com.apple.installd.container_creation_os_build      7
drwxr-xr-x  13 user  staff    442 Jul  8 17:42 ..
-rw-r--r--@  1 user  staff   6148 Jul  8 16:53 .DS_Store
com.apple.FinderInfo       32
drwxr-xr-x@  7 user  staff    238 Jun 17 13:03 Documents
com.apple.metadata:com_apple_backup_excludeItem    22
drwxr-xr-x   6 user  staff    204 Jul  8 16:53 Library
drwxr-xr-x  59 user  staff   2006 Jul  8 16:24 APPNAME.app
-rw-r--r--   1 user  staff  80109 Jun 17 11:24 iTunesArtwork
drwxr-xr-x   2 user  staff     68 Jul  8 16:22 tmp

So there is Documents com.apple.metadata:com_apple_backup_excludeItem

Now! I'm cleaning Build Folder in Xcode, Deleting my App on my iPad Air 7.1.2

(iCloud Backup is enabled)

After Building the App I navigate to Settings > iCloud > Storage & Backup > Manage Storage > My iPad > Show All Apps and there is it!! My App is in the list with 4.2 MB.

When I navigate to Settings > General > Usage > Show all Apps My App is about 11 MB big.

I'm asking myself if my solution will be now passing Apple Review Process? (except no other things are bad )

Upvotes: 0

Views: 1749

Answers (2)

Miralem Cebic
Miralem Cebic

Reputation: 1301

This is my solution. Very hard coded, but it works.

-(BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)fileURL {
if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
    NSLog(@"File %@ doesn't exist!",[fileURL path]);
    return NO;
}

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer isEqualToString:@"5.0.1"]) {
    const char* filePath = [[fileURL path] fileSystemRepresentation];
    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;
    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
    NSLog(@"Excluded '%@' from backup",fileURL);
    return result == 0;
}
else if (&NSURLIsExcludedFromBackupKey) { //iOS 5.1 and later
    NSError *error = nil;
    BOOL result = [fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
    if (result == NO) {
        NSLog(@"Error excluding '%@' from backup. Error: %@",fileURL, error);
        return NO;
    }
    else { // Succeeded
        NSLog(@"Excluded '%@' from backup",fileURL);
        return YES;
    }
} else {
    // iOS version is below 5.0, no need to do anything because there will be no iCloud present
    return YES;
}
}

// now call  above method from where you are storing your files/folders in NSDocumnetsDirectory
-(BOOL) doNotBackUpMyFolderOrFile {

NSString *applicationCacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
                                                                     NSUserDomainMask,
                                                                     YES) lastObject];

NSURL *pathURL= [NSURL fileURLWithPath: applicationCacheDir isDirectory:YES];


NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsURL = [paths lastObject];


NSURL *tmpURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];

NSString* libpath = [NSSearchPathForDirectoriesInDomains(
                                                      NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSURL *libURL= [NSURL fileURLWithPath: libpath isDirectory:YES];

if ([self addSkipBackupAttributeToItemAtURL:documentsURL] &&
    [self addSkipBackupAttributeToItemAtURL:pathURL]      &&
    [self addSkipBackupAttributeToItemAtURL:tmpURL]       &&
    [self addSkipBackupAttributeToItemAtURL:libURL]) {
    return YES;
}
return NO;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

if ([self doNotBackUpMyFolderOrFile]) {
...

Upvotes: 1

Tib
Tib

Reputation: 1280

This question is a bit old now, but I've faced the same issue: I implemented the addSkipBackupAttribute and moved my data in the Cache Directory, but when I checked on the iCloud backup settings, I still had 7MB of backup for my app.

Here is me solution: all my graphical ressources (images, etc.. about 7MB) were placed in the Supporting Files folder in my project. I moved these ressources in my main project folder (or any other classic subfolder of the project), and tadaa: my iCloud app backup is now 14kb :)

Apparently, all the Supporting Files ressources are automatically saved with the app backup...

Upvotes: 0

Related Questions