7

I am working with coredata for the first time and I have to restrict the sqlite db file from iCloud backup which is in documents directory and i have done it using the below code

-(id)init
{
    if((self = [super init]))
    {
        NSURL* documentsDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        NSURL* modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
        NSURL* giveForwardSqliteURL = [documentsDirectoryURL URLByAppendingPathComponent:@"InfoCollection.sqlite"];
        NSError* error;

        m_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
        m_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:m_managedObjectModel];

        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];


        if ([m_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:giveForwardSqliteURL options:options error:&error])
        {
            m_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
            [m_managedObjectContext setPersistentStoreCoordinator:m_persistentStoreCoordinator];

            [self addSkipBackupAttributeToItemAtPath:giveForwardSqliteURL];
        }
        else
        {
            NSLog(@"Failed to create or open database: %@", [error userInfo]);
            return nil;
        }
    }

    return self;
}

//Prevent iCloud to take backup of documents directory folder

- (BOOL)addSkipBackupAttributeToItemAtPath:(NSURL *) URL
{
    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;
}

Now what i didn't understand is do we also need to restrict sqlite-wal and sqlite-shm files from icloud backup, if yes then how to restrict sqlite-wal and sqlite-shm files from icloud backup

And i want a solution without changing the sqlite db location from documents directory folder... how can we do it

Please correct if anything is wrong in the above code

Thanks in advance

kumar
  • 151
  • 1
  • 12
  • 1
    If we need to skip them, creating URLs for the `wal` and `shm` files and passing them to the add skip attribute methods should be quite straight forward. Question is do we need to do this and if yes, when because these file may not be created at the time of the persistent store creation. Also, the WAL journal is periodically merged into the main db and recreated etc. How do we track those changes? – Swapnil Luktuke Aug 10 '15 at 10:57
  • 1
    @lukya i didn't get any clue what to do and what will happen if i leave it like that.. so i added these lines 'if ([[NSFileManager defaultManager] fileExistsAtPath:[sqliteShmURL path]]) { [self addSkipBackupAttributeToItemAtPath:sqliteShmURL]; } if ([[NSFileManager defaultManager] fileExistsAtPath:[sqliteWalURL path]]) { [self addSkipBackupAttributeToItemAtPath:sqliteWalURL]; }' – kumar Aug 10 '15 at 11:05
  • 1
    hmm.. its weird.. i thought i'll get many references... but surprisingly, there is no discussion on this anywhere... i've started a bounty on this question. lets see if any valid answer turns up... – Swapnil Luktuke Aug 10 '15 at 12:38
  • 1
    No activity even after starting a bounty. I guess there is no real answer for this. – Swapnil Luktuke Aug 12 '15 at 11:29
  • I have added a [question on apple developer forums](https://forums.developer.apple.com/message/40222#40222). Will update this post if any useful info turns up. – Swapnil Luktuke Aug 12 '15 at 11:58
  • Ok.. Thank you @lukya – kumar Aug 12 '15 at 11:59

2 Answers2

1

And i want a solution without changing the sqlite db location from documents directory folder... how can we do it

First, make sure you have read this to determine the proper directory in which to place your files.

Second, don't be so tied to putting them directly into the documents directory. In general, it's not a good idea to stuff every file directly into the Documents directory. Instead, you should use a directory hierarchy to logically partition your data.

Next, note that if you exclude a directory from backup, all files in the directory will be excluded as well.

Thus, if you are willing to be somewhat flexible and follow the advice above, you can simply use a subdirectory of the documents directory for your core data database.

NSURL* giveForwardDirURL = [documentsDirectoryURL URLByAppendingPathComponent:@"InfoCollection.dir"];
[[NSFileManager defaultManager] createDirectoryAtURL:giveForwardDirURL
                         withIntermediateDirectories:YES
                                          attributes:nil
                                               error:NULL];
[self addSkipBackupAttributeToItemAtPath:giveForwardDirURL];

NSURL* giveForwardSqliteURL = [giveForwardDirURL URLByAppendingPathComponent:@"InfoCollection.sqlite"];

If, however, you insist on having your files reside in the directory, you will have to search for them at initialization, and then you will have to monitor the directory as the app runs so you can set the flag if/when related files show up.

This thread contains information pertaining to that: Notification of changes to the iPhone's /Documents directory.

Community
  • 1
  • 1
Jody Hagins
  • 27,943
  • 6
  • 58
  • 87
  • Putting the sqlite and related files in a subdirectory was the final approach i went with(about a month ago). So your solution is right. However, i am looking for some official documentation for -wal and -shm files creation and tracking. If nothing else turns up i'll probably award you the bounty. – Swapnil Luktuke Aug 17 '15 at 09:47
  • kqueue implementation to track the documents directory changes, as mentioned in the link you've shared, seems like an overkill for excluding the -wal and -shm files. Subdirectory approach is definitely much better. However, because i haven't found a proper way of tracking those files, I feel like i ran away from a problem because i couldn't find the correct solution. – Swapnil Luktuke Aug 17 '15 at 09:59
  • If that's the solution you went with, then you didn't run away from a problem, you solved it. Putting the Core Data database in its own subdirectory is the right solution, and should, IMO, always be done unless there is a very good reason to do otherwise (it also makes it very easy to nuke the entire database and all temp files). If all you want is documentation for the temporary files, then its here: https://www.sqlite.org/tempfiles.html. However, note that even the SQLite authors state that the information is informational, and not guaranteed to continue working that way in the future. – Jody Hagins Aug 17 '15 at 12:12
  • Yes.. it is a very good solution but I would've felt way more comfortable (closure) if i could've found a way to track and mark the temp files correctly and decided not to go with it because subdirectory approach was easier/better... I've already read the temp file documentation but like you said its informal and does not give me a very good command on tracking those files. – Swapnil Luktuke Aug 17 '15 at 12:51
-1

You can force Core Data to use rollback journalling mode, preventing -shl and -wal files, by adding an options dictionary to the -[NSPersistentStoreCoordinator addPersistentStore…] call, like in this answer:

https://stackoverflow.com/a/24261845/453082

Community
  • 1
  • 1
Aderstedt
  • 6,301
  • 5
  • 28
  • 44
  • I now, but it is a work-around, preventing -shl and -wal files to be created in the first place. The end result is the same - no such files will be backed up. – Aderstedt Aug 17 '15 at 09:59
  • I beg to differ. Expected end result is that the -wal and -shm files should be created but not backed up to iCloud. Not allowing the files to be created is way different from just not backing them up. There are some good cases where the WAL journaling mode has advantages. – Swapnil Luktuke Aug 17 '15 at 10:03