drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 132 forks source link

Handle CDEErrorCodeUnknownModelVersion #211

Closed pronebird closed 8 years ago

pronebird commented 8 years ago

I am obviously developing my app and changing data model pretty often. What is the preferred way to tackle CDEErrorCodeUnknownModelVersion? Speaking of iCloud integration. I'd assume deleting transaction logs from iCloud should be easy.

Roughly, is this enough?

// forgive me for using defaultManager
BOOL removed = [[NSFileManager defaultManager] removeItemAtPath:[[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:cloudFileSystem.relativePathToRootInContainer] error:nil];

Thanks.

drewmccormack commented 8 years ago

How are you migrating? If you use automatic migration, ensembles will usually work ok. As soon as the user updates, the error will disappear. (In Ensembles 2 this is handled a little nicer; devices not updated can continue to sync with other unupdated devices, and the error does not arise.)

If you are not using auto migration, you need to start a new ensemble for each migration. Just assign a new ensemble identifier eg "MyEnsemble.v2"

The book goes into more detail.

Kind regards, Drew

On 29 Dec 2015, at 20:00, Andrey Mikhaylov notifications@github.com wrote:

I am obviously developing my app and changing data model pretty often. What is the preferred way to tackle CDEErrorCodeUnknownModelVersion?

Thanks.

— Reply to this email directly or view it on GitHub.

pronebird commented 8 years ago

During development I don't migrate per se. I just want to drop the entire thing. I'll take a look at the book, thanks! Just trying to put things together to see if it works :)

pronebird commented 8 years ago

I read a book and discovered a method on persistent store that removes all files from iCloud.

pronebird commented 8 years ago

I use automatic migration and just added a single optional, indexed string attribute to one of entities. However sync still throws 204. I'd expect it would be able to do automatic migration.

Do I have to do explicit migration? I was thinking this kind of changes falls into category of inferred automatic migrations.

<entity name="SpotlightIndex" representedClassName="SpotlightIndexModel" syncable="YES">
    <attribute name="domain" optional="YES" attributeType="String" indexed="YES" syncable="YES"/>
   <!-- [..] -->
</entity>

I setup Ensembles with the same options as SQLite store:

    NSMutableDictionary *storeOptions = [[NSMutableDictionary alloc] init];
    storeOptions[NSMigratePersistentStoresAutomaticallyOption] = @YES;
    storeOptions[NSInferMappingModelAutomaticallyOption] = @YES;

    self.storeOptions = [NSDictionary dictionaryWithDictionary:storeOptions];
    NSPersistentStore *store = [coordinator MR_addSqliteStoreAtURL:self.storeURL
                                                       withOptions:self.storeOptions];

    // ...

    CDEPersistentStoreEnsemble *ensemble =
    [[CDEPersistentStoreEnsemble alloc] initWithEnsembleIdentifier:ensembleIdentifier
                                                persistentStoreURL:self.storeURL
                                            persistentStoreOptions:self.storeOptions
                                             managedObjectModelURL:modelURL
                                                   cloudFileSystem:cloudFileSystem
                                         localDataRootDirectoryURL:nil];

Looking at local store in sim using Core Data Editor I can see that SQLite database is properly migrated and new column exists in database.

drewmccormack commented 8 years ago

It does handle that.

I suspect you may have messed around with your model during development. If you change your model and test sync, and then change it again, without two full migrations, the sync data will contain an event for a model version that no longer exists.

It is very easy to accidentally do this as you update your model in development. Solution is clearing the cloud data.

This is not a problem with production, because all the model versions will be available.

Kind regards, Drew

On 03 Jan 2016, at 16:16, Andrey Mikhaylov notifications@github.com wrote:

I use automatic migration and just added a single optional, indexed string attribute to one of entities. However sync still throws 204. I'd expect it would be able to do automatic migration.

I setup Ensembles with the same options:

CDEPersistentStoreEnsemble *ensemble =
[[CDEPersistentStoreEnsemble alloc] initWithEnsembleIdentifier:ensembleIdentifier
                                            persistentStoreURL:self.storeURL
                                        persistentStoreOptions:self.storeOptions
                                         managedObjectModelURL:modelURL
                                               cloudFileSystem:cloudFileSystem
                                     localDataRootDirectoryURL:nil];

— Reply to this email directly or view it on GitHub.

pronebird commented 8 years ago

@drewmccormack thanks for answering that fast and on Sunday. I bet you are right.