测试已测试 | ✗ |
语言语言 | Obj-CObjective C |
许可证 | BSD |
发布最后发布 | 2014年12月 |
由 fogisland 维护。
AXTProgressiveMigrationManager 优化了在 iOS 平台上迁移 Core Data 存储的程序。
在 轻量级迁移的情况下,Core Data 框架可以自动完成工作。但是当涉及到重量级迁移时,情况就变得复杂了。开发者需要创建一个映射模型和一个映射策略来完成迁移工作(请参阅官方文档)。
然而,在完成重量级迁移后,又出现了一个新的更加麻烦的问题:Core Data 框架不支持渐进式迁移过程。也就是说,例如,尽管数据库可以通过重量级迁移从版本2迁移到版本3,并通过轻量级迁移从版本3迁移到版本4,但仍需要开发者定义的新映射模型来从版本2迁移到版本4。随着数据库版本的演变,维护将变得越来越困难。
AXTProgressiveMigrationManager 提供了对 Core Data 数据库进行渐进式迁移的支持。在上面的示例中,不再需要从版本2迁移到版本4的新映射模型。基本思路来源于这部卓越的 Core Data 书籍,并增加了一些增强功能以支持轻量级和重量级迁移混合的渐进式迁移。
AXTProgressiveMigrationManager 从查找源数据库文件的相应 ManagedObjdectModel 开始,并查找连续的 ManagedObjdectModel,直到达到目标 ManagedObjdectModel。对于两个连续的 ManagedObjdectModel,AXTProgressiveMigrationManager 检查是否存在相应的映射模型。如果存在,则执行重量级迁移步骤;如果不存在,则执行轻量级迁移步骤。当数据库文件与目标 ManagedObjdectModel 兼容时,该流程结束。
NSError *error;
/* Migrate the SQLite database file located at storePath to a new version
* which is compatible with the targetManagedObjectModel.
*/
Bool isSuccess = [[AXTProgressiveMigrationManager sharedManager]
migrateStoreAtUrl:[NSURL fileURLWithPath:storePath]
storeType:NSSQLiteStoreType
targetModel:targetManagedObjectModel
error:&error];
AXTProgressiveMigrationManager 需要一个 ManagedObjectModel 的搜索规则,因此它可以找到从源到目标的所有连续的 ManagedObjectModels。此规则通过以下协议实现
@protocol AXTProgressiveMigrateDelegate <NSObject>
@required
- (NSManagedObjectModel *)nextModelOfModel:(NSManagedObjectModel *)model amongModelPaths:(NSArray *)allModelPaths;
@end
将遵守 AXTProgressiveMigrateDelegate
协议的实例分配给 AXTProgressiveMigrationManager 的 delegate
属性以实现搜索规则。
请注意,此配置是可选的,AXTProgressiveMigrationManager 有一个默认的内部搜索规则,该规则通过找到具有 Identifier
属性增加 1 的下一个连续的 ManagedObjectModel 来搜索(在 XCode 中 Data Model 文件的属性检查器面板中设置)。如果您使用默认的搜索规则,您需要确保所有 ManagedObjectModel 的 Identifier 值都已正确设置(例如,1、2、3、...)。并且未来添加的每个新的 ManagedObjectModel 也需要设置正确的 Identifier 值。
AXTProgressiveMigrationManager 从 Marcus S. Zarra 的 Core Data 书籍中学到了很多。感谢他的出色工作。
AXTProgressiveMigrationManager 在 BSD 许可下可用。有关更多信息,请参阅 LICENSE 文件。
AXTProgressiveMigrationManager 用来优化 iOS 上 Core Data 数据库的迁移工作。
在 Core Data 数据库升级只涉及轻量级变更时,Core Data 框架可以自动完成升级工作;但如果涉及重量级变更,情况就会变得复杂,开发人员需要自定义 Mapping Model 和 Mapping Policy 来完成升级工作(参见官方文档)。
但实现自定义的重量级升级后,还存在一个更麻烦的问题:Core Data 框架不支持渐进式数据库升级。假设数据库版本 Version2 到 Version3 使用了重量级升级,随后 Version3 到 Version4 使用轻量级升级,那么从 Version2 到 Version4 的升级工作并不能基于现有的 Mapping Model 自动完成,而是需要开发人员定义一个新的 Mapping Model 来对应 Version2 到 Version4 的升级工作。随着版本的增加,对于 Mapping Model 的维护工作将会变得非常麻烦和困难。
AXTProgressiveMigrationManager 提供了对渐进式数据库升级的支持。在上面的例子中,Version2 到 Version4 的升级工作不再需要一个新的 mapping model。基本思路来源于这本优秀的 Core Data 教程,在此基础上进行了优化,支持轻量级升级和重量级升级混合在一起的渐进式升级。
AXTProgressiveMigrationManager 从源数据库文件对应的 managedObjectModel 开始,在 bundle 内一路搜索到目标 managedObjectModel;并对每两个连续的 managedObjectModel,在 bundle 内搜索对应的 mapping model 是否存在,如果存在则进行一次重量级升级,否则进行一次轻量级升级;直到最后数据库文件和目标 managedObjectModel 相兼容。
NSError *error;
/* 将位于 storePath 的 SQLite 数据库文件
* 升级到和 Core Data 数据库模型targetManagedObjectModel 匹配的版本
*/
Bool isSuccess = [[AXTProgressiveMigrationManager sharedManager]
migrateStoreAtUrl:[NSURL fileURLWithPath:storePath]
storeType:NSSQLiteStoreType
targetModel:targetManagedObjectModel
error:&error];
AXTProgressiveMigrationManager 需要一个 managedObjectModel 的搜索规则,来搜索出从源 managedObjectModel 到目标 managedObjectModel 的所有连续 managedObjectModel。这个规则通过下面的 Protocol 实现:
@protocol AXTProgressiveMigrateDelegate <NSObject>
@required
- (NSManagedObjectModel *)nextModelOfModel:(NSManagedObjectModel *)model amongModelPaths:(NSArray *)allModelPaths;
@end
通过将实现了 AXTProgressiveMigrateDelegate
的实体设置为 AXTProgressiveMigrationManager 的 delegate
来完成。这一步是可选的,如果您不实现这一步,AXTProgressiveMigrationManager 的默认 managedObjectModel 搜索规则是:Identifier
(在 dataModel 文件的 File Inspector 中设置) 递增 1。
因此,如果您采用默认的排序规则,需要手动将现有的所有 dataModel 文件的 Identifier 按版本顺序设置为递增的值:1、2、3、4......并且以后增加的新版本 dataModel 也需要记得设置好 Identifier 值。
AXTProgressiveMigrationManager 基于 Marcus S. Zarra 的 Core Data 教程 内的思路进行开发,感谢他编写的这本教程。
AXTProgressiveMigrationManager 在 BSD 协议下获得许可,查阅 LICENSE 文件以获取更多信息。