Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi.
This pull request enables Core Data migration. It makes it possible to make non-lightweight migrations, with mapping models and migration policies. The main idea behind it is taken from Apple's Incremental Store Programming Guide. As a Note in that section states:
As far as I understand the process of migration proceeds in this way:
NSPersistentStoreCoordinator
is instantiated with some managed object model, which has it's hashes in theentityVersionHashesByName
property.loadMetadata:
method.NSPersistentStore
'smetadata
property. A dictionary in this property must contain managed object model's hashes, used the last time with this store. This method do not perform any migrations on it's own, this is a responsibility of the persistent store coordinator.loadMetadata:
method invoking the coordinator checks themetadata
property. If it's hashes and hashes in this dictionary are different, it starts a migration.NSPersistentStore
class. For this instance the situation looks like it is it's first launch, even though it's managed object model is a new one. During the migration all of the old managed objects retrieved from the old store, passed through migration rules (mapping model, either defined by developer or inferred automatically as a part of a lightweight migration), and inserted into a new stack. From the new stack's persistent store point of view this looks the same as a just new installation.So the problem was in the migration code in the Encrypted Core Data's
loadMetadata
method. I removed it and this gave Core Data a possibility to follow it's procedure, including any kind of migration.Additionally, I removed all of the code, that is related to the migration. Maybe it's to radical.
There is one more technical problem here. To make a migration work it is necessary to store that hashes properly in the
metadata
property. This property must be overriden due toNSPersistentStore
doc, butNSIncrementalStore
overrides it by itself, so that there is no need to do that. Unfortunately, it does it in some strange way. It looks like this: the persistent store properly retrieves it's hashes, set them to themetadata
property, but after the setting there are a new hashes in that property! This is the reason why the migration doesn't start in this situation -- Core Data doesn't see a difference in hashes. So I've overriden themetadata
property, to preserve the hashes and to keep everithing else in the metadata untouched. The latter is important, because thisNSIncrementalStore
's setter additionally sets some internal keys and values in the dictionary. Without this info the migration doesn't start either. Currently this is Apple's bug as for me, so I plan to post a bug to them regarding this property behaviour and look what they will answer.Additionally, I've noticed a lot of tests in the example project. I am sorry but I haven't appropriate knowledge regarding tests. In fact, I wasn't even able to ran this example project -- I've done all of the job in my project, in which ECD is added via Cocoapods. So I haven't touched tests.
The last problem -- I am not aware whether this custom migration in the
loadMetadata
method allowed migration from an unencrypted store to the encrypted one. If so -- this change brakes it. But I believe this is not necessary for all of the Encrypted Core Data users -- if for the first app's users their stores already encrypted, then main priority is to make the migration just for an encrypted store.This change can be useful for such issues: #190, #14, #141, #83.