Excluir de la copy de security de iCloud: NSURLIsExcludedFromBackupKey

Mi aplicación había sido rechazada la segunda vez y perdí 3 semanas 🙁

La primera vez que envié, excluí SOLO DIRECTORIOS de las copys de respaldo en iCloud. Apple rechazó …

En la segunda presentación, excluyo los DIRECTORIOS Y FOTOGRAFIAS descargados de las copys de respaldo en iCloud. Apple rechazó nuevamente … Apple también denuncia que no tengo ninguna function de "Restaurar" para mi compra en la aplicación, mientras que de hecho, tengo un button "Restaurar" y funcionó cuando lo probé.

He hecho lo que Apple sugirió al excluir el respaldo del file utilizando NSURLIsExcludedFromBackupKey. Hubo un comentario interesante hecho por Macmade en stackoverflow aquí :

a veces, los revisores de Apple piensan que sus datos pueden volverse a generar, cuando no lo son. Luego tendrás que explicar por qué hay que hacer una copy de security de los datos.

¿Con qué frecuencia el revisor no entiende bien y tenemos que explicarles que el contenido se requiere fuera de línea y no se puede volver a generar?

Aquí está el código que usé para excluir mis files y directorys de iCloud. ¿Ves algún problema?

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL { // There's a chance the download failed, but don't assert here //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; } //Download picture from Google and exclude it from being backed-up in iCloud - (void)downloadFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error { if (error == nil) { // successfully retrieved this photo's data; save it to disk GDataEntryPhoto *photoEntry = [fetcher propertyForKey:@"photo entry"]; // Create album directory if it doesn't already exist NSString *path = [self findOrCreateApplicationSupportSubPath:[photoEntry albumTitle]]; path = [path stringByAppendingPathComponent:[[photoEntry title] stringValue]]; if (path != nil) { // Write to disk BOOL didSave = [data writeToFile:path options:NSDataWritingAtomic error:&error]; if (didSave) { // Exclude file from being backed up in iCloud NSURL *url = [NSURL fileURLWithPath:path]; BOOL excludeBackupResult = [self addSkipBackupAttributeToItemAtURL:url]; if (excludeBackupResult == NO) { NSLog(@"Error excluding FILE from iCloud: %@", path); } // Update the download progress bar _downloadedFileCounter = _downloadedFileCounter + 1; float progress = _downloadedFileCounter / kMaleWireframeImagesTotal; [self updateProgress:progress]; // The download completed. -2 just incase a package is lost, but let the user move on... if (_downloadedFileCounter >= _downloadableFilesTotal -2) { [_panel6 downloadCompleted]; } } else { // error saving file. Perhaps out of space? Write permissions error? NSLog(@"Save anatomy picture failed: %@", error.localizedDescription); } } else { NSLog(@"downloadFetcher: Cannot create directory"); } } else { NSLog(@"downloadFetcher failed: %@", error); } } //Create directory and exclude it from being backed-up in iCloud -(NSString*)findOrCreateApplicationSupportSubPath:(NSString*)subPath { NSString *resolvedPath; NSArray *appSupportDir = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); if ([appSupportDir count] != 0) { resolvedPath = [appSupportDir objectAtIndex:0]; // Append the name of this application NSString *executableName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"]; resolvedPath = [resolvedPath stringByAppendingPathComponent:executableName]; resolvedPath = [resolvedPath stringByAppendingPathComponent:subPath]; NSFileManager *manager = [NSFileManager defaultManager]; if (![manager fileExistsAtPath:resolvedPath]) { // Path doesn't exist, creates it NSError *error; BOOL successful = [manager createDirectoryAtPath:resolvedPath withIntermediateDirectories:YES attributes:nil error:&error]; if(!successful) { NSLog(@"ERROR creating APP Support Sub-Directory: %@", error.localizedDescription); return nil; } else { // Exclude path from backing-up in iCloud NSURL *url = [NSURL fileURLWithPath:resolvedPath]; BOOL excludeBackupResult = [self addSkipBackupAttributeToItemAtURL:url]; if(!excludeBackupResult){ NSLog(@"Error excluding DIRECTORY from iCloud backup. This is a violation to their guideline."); return nil; } } } } else { NSLog(@"No Application Support Path available"); return nil; } return resolvedPath; } 

Creo que el truco es agregar el NSURLIsExcludedFromBackupKey Y asegurarme de que el directory está fuera del directory de documentos. Lo hice moviendo mis documentos a la carpeta de Soporte de Biblioteca / Aplicación (ya que no tenía sentido en las carpetas / tmp o / Caches):

 - (void)createNewRefFolder { NSError *error; // 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); } 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: %@ ...", error); } BOOL success = [referenceFolder setResourceValue:@YES forKey: NSURLIsExcludedFromBackupKey error: &error]; if(!success){ NSLog(@"KCDM: Error excluding %@ from backup %@", referenceFolder, error); } }