Closed NorbNorb closed 10 years ago
Sure, you can save the sqlite store. Then you can import it into the local or the cloud store using USM's
- (BOOL)migrateStore:(NSURL *)migrationStoreURL withOptions:(NSDictionary *)migrationStoreOptions
toStore:(NSURL *)targetStoreURL withOptions:(NSDictionary *)targetStoreOptions
strategy:(UbiquityStoreMigrationStrategy)migrationStrategy
error:(__autoreleasing NSError **)outError cause:(UbiquityStoreErrorCause *)cause context:(__autoreleasing id *)context;
Dear Maarten, sorry to ask again, but could you please comment on my approach of creating and restoring snapshots? I want to delete both locally and in iCloud if iCloud is enabled, locally only otherwise. Is this the way your API is intended to be used? I had to do a little workaround for a restoration after a deletion (see below).
Creation:
- (void)snapshotPersistentStoreToPath:(NSString *)localCopyPath
{
[appDelegate.managedObjectContext.persistentStoreCoordinator lock];
NSArray *stores = appDelegate.managedObjectContext.persistentStoreCoordinator.persistentStores;
for (NSPersistentStore *store in stores)
{
NSURL *storeURL = [appDelegate.managedObjectContext.persistentStoreCoordinator URLForPersistentStore:store];
NSString *storeFileName = [storeURL lastPathComponent];
NSURL *dstFileURL = [[NSURL fileURLWithPath:localCopyPath] URLByAppendingPathComponent:storeFileName];
// Remove Write Ahead Log (wal)
NSDictionary *options = @{
NSPersistentStoreRemoveUbiquitousMetadataOption: @YES,
NSSQLitePragmasOption : @{ @"journal_mode" : @"DELETE" }
};
NSError *error;
NSPersistentStore *storeCopy = [appDelegate.managedObjectContext.persistentStoreCoordinator migratePersistentStore:store
toURL:dstFileURL
options:options
withType:NSSQLiteStoreType
error:&error];
if (error)
{
NSLog(@"%@", [error localizedDescription]);
}
if (storeCopy)
{
[appDelegate.managedObjectContext.persistentStoreCoordinator removePersistentStore:storeCopy error:&error];
}
}
[appDelegate.managedObjectContext.persistentStoreCoordinator unlock];
}
Restoring:
I have had the problem that right after a call to deleteCloudContainerLocalOnly:
or deleteLocalStore
, I could not directly start the migration from the backup store.
ubiquityStoreManager:willLoadStoreIsCloud:
gets called twice and I had to make sure the recovering migration happens not until the second run (that's what the variable migrateStoreAfterDeletion
is for).
- (void)restoreFromPersistentStore:(NSURL *)url
{
if (!url)
{
NSLog(@"Didn't get an URL to restore from.");
return;
}
storeURLToMigrateFrom = url;
migrateStoreAfterDeletion = NO;
if (self.ubiquityStoreManager.cloudEnabled)
{
[self.ubiquityStoreManager deleteCloudContainerLocalOnly:NO];
}
else
{
[self.ubiquityStoreManager deleteLocalStore];
}
}
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore
{
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
NSLog( @"Unresolved error: %@\n%@", error, [error userInfo] );
[managedObjectContext reset];
}];
_managedObjectContext = nil;
if (storeURLToMigrateFrom)
{
if (!migrateStoreAfterDeletion)
{
migrateStoreAfterDeletion = YES;
}
else
{
NSURL *dstStoreURL = manager.cloudEnabled ? manager.URLForCloudStore : manager.URLForLocalStore;
NSError *error;
UbiquityStoreErrorCause cause;
id context;
[manager migrateStore:storeURLToMigrateFrom withOptions:nil
toStore:dstStoreURL withOptions:nil
strategy:UbiquityStoreMigrationStrategyIOS
error:&error
cause:&cause
context:&context];
storeURLToMigrateFrom = nil;
migrateStoreAfterDeletion = NO;
}
}
}
Why do you delete the store first?
I want to overwrite the local store or cloud container with the Core Data snapshot. And I need to get the delegate method ubiquityStoreManager:willLoadStoreIsCloud:
called somehow. What's your recommendation?
Hi lhunath, do you have a recommendation on how to handle the restoration locally / to iCloud correctly?
It seems to me the best way would be to migrate the snapshot to USM's local store and then do a -migrateLocalToCloud
if you want a cloud store too, or just a -deleteCloudStoreLocalOnly:NO
and let USM migrate the cloud store from the local store automatically when the user turns on cloud.
Ok, thanks, I'll do it that way.
So you've asked why I delete the store first. Is there a better way than mine? As I said, I need USM to call ubiquityStoreManager:willLoadStoreIsCloud:
, so I can start the migration.
It will do that whenever you change the store. Eg. just a -reloadStore will trigger that.
On 23 January 2014 08:56, NorbNorb notifications@github.com wrote:
Ok, thanks, I'll do it that way. So you've asked why I delete the store first. Is there a better way than mine? As I said, I need USM to call ubiquityStoreManager:willLoadStoreIsCloud:, so I can start the migration.
— Reply to this email directly or view it on GitHubhttps://github.com/lhunath/UbiquityStoreManager/issues/46#issuecomment-33125312 .
Maarten Billemont (lhunath) me: http://www.lhunath.com – business: http://www.lyndir.com – http://masterpasswordapp.com
Hi,
i want to achieve something similar. i´ve tried it as Ihunath described it:
reloadStore
.ubiquityStoreManager:willLoadStoreIsCloud:
ubiquityStoreManager:willLoadStoreIsCloud:
i call manager migrateStore:
but in this line i get the following error: "UbiquityStoreManager: Error (cause:UbiquityStoreErrorCauseSeedStore): Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn’t be completed. (Cocoa error 134080.)" UserInfo=0xd382770 {NSUnderlyingException=Can't add the same store twice} "
So what i´m doing wrong here? Thank you
Hi lhunath,
could you please post a small example which shows how to use the migrateStorewithOptions
Method to replace the actual store with another backup store.
Thank you for your effords.
Is this possible:
I need a way to enable my users to keep snapshots over a long time. I have a complex data model and therefor exporting and importing the data using a custom file format is no solution to me. The complexity would be to high, esp. with schema changes.