Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLIsExcludedFromBackupKey - Apps must follow the iOS Data Storage Guidelines or they will be rejected

My app was rejected cause it seems that 7 mb are stored in documents folder and they are automatically send to icloud. So i have looped all files that will be written to documents folder throught this method :

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL {   

   const char* filePath = [[URL path] fileSystemRepresentation];
   const char* attrName = "com.apple.MobileBackup";
   if (&NSURLIsExcludedFromBackupKey == nil) {
   // iOS 5.0.1 and lower
   u_int8_t attrValue = 1;
   int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
   return result == 0;
 }
  else {
   // First try and remove the extended attribute if it is present
   int result = getxattr(filePath, attrName, NULL, sizeof(u_int8_t), 0, 0);
   if (result != -1) {
       // The attribute exists, we need to remove it
       int removeResult = removexattr(filePath, attrName, 0);
       if (removeResult == 0) {
           NSLog(@"Removed extended attribute on file %@", URL);
       }
   }

   // Set the new key
   NSError *error = nil;
   [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
   return error == nil;
  }

The version 1.1 of my app was approved after this code implementation. Last week i tried to send the version 1.2 of the same app (nothing has changed in file management, all files that are stored in documents folder are looped through the addSkipBackupAttributeToItemAtURL method). My app was rejected again for the same reason.  I can't move my file to temp or cache folder because my app can't completely restore the file (one of this file is a db, restoring db means loose any user inserted data), so this one can't be the solution. Anyway i have found an issue in the code, this is how i call the method :

[self addSkipBackupAttributeToItemAtURL:[NSURL fileURLWithPath:fullPath]];

using [NSURL fileURLWithPath:fullPath] device with ios 5.1 return an error and it seems impossible to create the attribute. If i change the initialization of the nsurl with [NSURL URLWithString:defaultStorePath], device with 5.1 seems to add correctly the attribute.

With ios 5.0.1 all is inverted , [NSURL URLWithString:defaultStorePath] return an error while [NSURL fileURLWithPath:fullPath] works.

Maybe i can check ios version and set an appropriate nsurl initialization, but  it  still remains a problem. In rejection explanation i read :

In particular, we found that on launch and/or content download, your app stores 7mb. To check how much data your app is storing:

  • Install and launch your app
  • Go to Settings > iCloud > Storage & Backup > Manage Storage
  • If necessary, tap "Show all apps"
  • Check your app's storage

If i try to check this value i see 7 mb also with the correct nsurl initialization (when all the attributes are set  correctly) . What is the correct behaviour? Anyone with this problem?  Do I have to do something specific before the app storage check suggested by apple to make it significant?

like image 655
Cri1682 Avatar asked Nov 03 '22 21:11

Cri1682


1 Answers

I think the trick is to add the NSURLIsExcludedFromBackupKey AND make sure the directory is outside the documents directory. I did this by moving my documents to the Library/Application Support folder (since it didn't make sense in the /tmp or /Caches folders):

// store in /Library/Application Support/BUNDLE_IDENTIFIER/Reference
// make sure Application Support folder exists
NSURL *applicationSupportDirectory = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
                                                                            inDomain:NSUserDomainMask
                                                                   appropriateForURL:nil
                                                                              create:YES
                                                                               error:&error];
if (error) {
    NSLog(@"KCDM: Could not create application support directory. %@", error);
    return nil;
}

NSURL *referenceFolder = [applicationSupportDirectory URLByAppendingPathComponent:@"Reference" isDirectory:YES];
if (![[NSFileManager defaultManager] createDirectoryAtPath:[referenceFolder path]
                               withIntermediateDirectories:YES
                                                attributes:nil
                                                     error:&error]) {
    NSLog(@"KCDM: Error creating Reference folder to store model %@: %@", modelName, error);
    return nil;
}

BOOL success = [referenceFolder setResourceValue:@YES forKey: NSURLIsExcludedFromBackupKey error: &error];
if(!success){
    NSLog(@"KCDM: Error excluding %@ from backup %@", referenceFolder, error);
}
like image 173
Gujamin Avatar answered Nov 08 '22 08:11

Gujamin