My app had been rejected the 2nd times and I lost 3 weeks :(
The first submit, I excluded ONLY DIRECTORIES from being backed-up in iCloud. Apple rejected...
The second submit, I excluded DIRECTORIES & PICTURES downloaded from being backed-up in iCloud. Apple again rejected... Apple also complaint that I have no "Restore" feature for my In-App purchase, while in fact, I do have a "Restore" button and it worked when I tested it.
I've done as Apple had suggested by excluding the file from being backedup using NSURLIsExcludedFromBackupKey. There was an interesting comment made by Macmade's on stackoverflow here:
sometimes Apple reviewers think your data can be re-generated, when it's not. Then you'll have to explain why the data has to be backed-up
How often do the reviewer misunderstood and we have to explain to them that the content is required offline & not re-generateable?
Here is the code I used to exclude my files & directories from iCloud. Do you spot any problems?
- (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;
}
Go to Settings > [your name] > iCloud. Tap Manage Account Storage or tap Manage Storage, then tap Backups. Tap the name of the device that you're using. Turn off any apps that you don't want to back up.
Manage what is included by going to Settings > [your name] > iCloud and toggle the switch on or off for the apps you do or do not want to sync to iCloud storage.
Here's what iCloud Backup includes Your iPhone, iPad, and iPod touch backups only include information and settings stored on your device. They do not include information already stored in iCloud such as Contacts, Calendars, Bookmarks, Notes, Reminders, Voice Memos4, Messages in iCloud, iCloud Photos, and shared photos.
I think the trick is to add the NSURLIsExcludedFromBackupKey OR 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):
- (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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With