I'm trying to mark the entire folder of my app's NSDocumentDirectory so that it is excluded from the iCloud backup, but when I go to the terminal and run: xattr -plxv com.apple.MobileBackup I get this error: No such xattr: com.apple.MobileBackup
Thank you in advance for any help offered.
Here is the code I'm using:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *pathURL= [NSURL fileURLWithPath:documentsDirectory];
[self addSkipBackupAttributeToItemAtURL:pathURL];
}
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
if (&NSURLIsExcludedFromBackupKey == nil) { // iOS <= 5.0.1
const char* filePath = [[URL path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
} else { // iOS >= 5.1
NSLog(@"%d",[URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil]);
return [URL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
}
}
How can you run Terminal on your iOS app's folder? You mean in the Simulator?
For sure Apple is going to ignore or strip out that attribute from the primary Documents folder. What you should do is what Apple tells developers to do (from File Systems Programming Guide):
Handle support files—files your application downloads or generates and can recreate as needed—in one of two ways:
In iOS 5.0 and earlier, put support files in the <Application_Home>/Library/Caches
directory to prevent them from being backed up
In iOS 5.0.1 and later, put support files in the <Application_Home>/Library/Application Support
directory and apply the com.apple.MobileBackup extended attribute to them. This attribute prevents the files from being backed up to iTunes or iCloud. If you have a large number of support files, you may store them in a custom subdirectory and apply the extended attribute to just the directory.
So you create a new directory for your files inside Application Support
, and apply the attribute to that directory.
EDIT: Well, it seems that info is out of date and the document has not been updated. From the iOS 5.1 Release Notes:
iOS 5.1 introduces a new API to mark files or directories that should
not be backed up. For NSURL
objects, add the
NSURLIsExcludedFromBackupKey
attribute to prevent the corresponding
file from being backed up. For CFURLRef objects
, use the corresponding
kCFURLIsExcludedFromBackupKey
attribute.
Apps running on iOS 5.1 and
later must use the newer attributes and not add the
com.apple.MobileBackup
extended attribute directly, as previously
documented. The com.apple.MobileBackup
extended attribute is
deprecated and support for it may be removed in a future release.
It turns out that you can get actual code to do this in the Technical Q&A QA1719.
Also, I found I need to create the Application Support directory, at least in the Simulator. Hope this code helps:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// got to make sure this exists
NSFileManager *manager = [NSFileManager defaultManager];
NSString *appSupportDir = [self applicationAppSupportDirectory];
if(![manager fileExistsAtPath:appSupportDir]) {
__autoreleasing NSError *error;
BOOL ret = [manager createDirectoryAtPath:appSupportDir withIntermediateDirectories:NO attributes:nil error:&error];
if(!ret) {
LTLog(@"ERROR app support: %@", error);
exit(0);
}
}
...
}
- (NSString *)applicationAppSupportDirectory
{
return [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject];
}