Reputation: 9497
Referencing iCloud + Storage of media in iPhone Documents folder, which shows how to set the iOS 5.0.1 "Do Not Backup" attribute for a file.
Is there an efficient way to do this for an entire folder/file hierarchy? E.g., my app creates /Library/PrivateDocs, and populates that with several folders, sub-folders, and files. Can I just set the do-not-backup attribute on the top-level folder, or must it be set on every individual file and folder under that also?
And, if it must be set on each file/subfolder, what's an efficient way to do so?
Upvotes: 11
Views: 11036
Reputation: 2129
maybe this would help someone using swift 2:
Just before @UIApplicationMain
add this:
extension NSFileManager{
func addSkipBackupAttributeToItemAtURL(url:NSURL) throws {
try url.setResourceValue(true, forKey: NSURLIsExcludedFromBackupKey)
}
}
In your lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
after you declare your URL you can add this:
do {
let url = url
try NSFileManager.defaultManager().addSkipBackupAttributeToItemAtURL(url)
} catch {
// Handle error here
print("Error: \(error)")
}
Upvotes: 1
Reputation: 129
Correction on above method,use this for swift
func addSkipBackupAttributeToItemAtURL(URL:NSURL) ->Bool {
let fileManager = NSFileManager.defaultManager()
assert(fileManager.fileExistsAtPath(URL.absoluteString!))
var error:NSError?
let success:Bool = URL.setResourceValue(NSNumber(bool: true),forKey: NSURLIsExcludedFromBackupKey, error: &error)
if !success{
println("Error excluding \(URL.lastPathComponent) from backup \(error)")
}
return success;
}
Upvotes: -1
Reputation: 1828
For all my friends here, who needs in Swift - just look below (iOS8.0)
func addSkipBackupAttributeToItemAtURL(URL:NSURL) ->Bool{
let fileManager = NSFileManager.defaultManager()
assert(fileManager.fileExistsAtPath(URL.absoluteString))
var error:NSError?
let success:Bool = URL.setResourceValue(NSNumber.numberWithBool(true),forKey: NSURLIsExcludedFromBackupKey, error: &error)
if !success{
println("Error excluding \(URL.lastPathComponent) from backup \(error)")
}
return success;
}
Upvotes: 9
Reputation: 5426
you can do the following in swift
:
func addSkipBackupAttributeToItemAtPath(path:String) -> Bool {
let filePath = path.fileSystemRepresentation()
let attrName = "com.apple.MobileBackup"
var attrValue : uint_fast8_t = 1
let result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue.dynamicType), 0, 0)
return result == 0
}
Upvotes: -1
Reputation: 51
For me, in Swift, the previously answered functions didn't quite work. In particular the assert line failed. I needed to update it from URL.absoluteString! to URL.path! So in the end mine looks like this:
func addSkipBackupAttributeToItemAtURL(URL:NSURL) ->Bool{
let fileManager = NSFileManager.defaultManager()
assert(fileManager.fileExistsAtPath(URL.path!))
var error:NSError?
let success:Bool = URL.setResourceValue(NSNumber(bool: true),forKey: NSURLIsExcludedFromBackupKey, error: &error)
if !success{
println("Error excluding \(URL.lastPathComponent) from backup \(error)")
}
return success;
}
Upvotes: 2
Reputation: 1332
You could put one specific directory inside the documents dir for this purpose, put everything inside and only mark that single directory as do-not-backup using the
addSkipBackupAttributeToItemAtURL
method shown in the article you linked, or use this one that uses a path instead of an URL:
+ (void)addSkipBackupAttributeToPath:(NSString*)path {
u_int8_t b = 1;
setxattr([path fileSystemRepresentation], "com.apple.MobileBackup", &b, 1, 0, 0);
}
example using a directory:
NSString *docsDirPath = [(AppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory];
NSString *yourContentsDirPath = [docsDirPath stringByAppendingPathComponent:gContentsDirName];
[Utilities addSkipBackupAttributeToPath:yourContentsDirPath];
[EDIT]
I forgot this method use in the delegate to get the documents dir:
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
Upvotes: 25