我的iPhone应用程序需要迁移其核心数据存储,而且一些数据库非常庞大.Apple的文档建议使用"多次传递"来迁移数据以减少内存使用.但是,文档非常有限,并没有很好地解释如何实际执行此操作.有人可以指出我一个好的例子,或者详细解释如何实际解决这个问题的过程吗?
我正在尝试更新实现核心数据存储的应用程序.我正在为其中一个实体添加一个属性.
我将以下代码添加到我的委托类:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Shoppee.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
NSLog(@"Error: %@",error);
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
Run Code Online (Sandbox Code Playgroud)
这来自以下网址: Doc
执行代码时出现以下错误:
2009-12-01 20:04:22.877
Shoppee [25633:207]错误:错误
Domain = NSCocoaErrorDomain Code = 134130 …
我在核心数据模型上成功完成了轻量级迁移.
我的自定义实体Vehicle收到了一个新属性'tirePressure',它是double类型的可选属性,默认值为0.00.
当"旧"车辆从商店取出时(在迁移发生之前创建的车辆),他们的'tirePressure'属性的值为零.(这是预期的行为吗?)
所以我想:"没问题,我会在Vehicle类中做到这一点:"
- (void)awakeFromFetch {
[super awakeFromFetch];
if (nil == self.tirePressure) {
[self willChangeValueForKey:@"tirePressure"];
self.tirePressure = [NSNumber numberWithDouble:0.0];
[self didChangeValueForKey:@"tirePressure"];
}
}
Run Code Online (Sandbox Code Playgroud)
由于"更改处理明确禁用" awakeFromFetch,我认为调用willChangeValueForKey和didChangeValueForKey会将'tirePresure'标记为脏.
但他们没有.
每次这些车辆从商店取出"轮胎压力",尽管已经保存了上下文,但仍然是零.
我正在成功使用Core Data的自动轻量级迁移.但是,当在迁移期间创建特定实体时,我想用一些数据填充它.当然,我可以在每次应用程序启动时检查实体是否为空,但是当Core Data具有迁移框架时,这似乎效率低下.
是否可以检测轻量级迁移何时发生(可能使用KVO或通知),还是需要实现标准迁移?
我尝试过使用它NSPersistentStoreCoordinatorStoresDidChangeNotification,但是在迁移发生时它不会触发.
我真的陷入了从iPhone应用程序的v1到v2的升级测试.我有IPA版本,我正在测试通过iTunes临时分发到我的iPhone设备,一个用于应用程序的v1,另一个用于v2.注意:
错误的片段......*
reason=**Can't find model for source store**}, {
URL = "file://localhost/var/mobile/Applications/AAAAF424-D6ED-40FE-AB8D-66879386739D/Documents/MyApp.sqlite";
metadata = {
NSPersistenceFrameworkVersion = 320;
<cut>
Run Code Online (Sandbox Code Playgroud)
问题 - 任何想法如何解决这个问题?我可以在这做什么调试/分析?如果您需要更多信息,请告诉我.
我作为概述所做的是:
PS更全面的错误版本,如果这有帮助 - 这次它来自模拟模拟器上的迁移错误
, reason=Can't find model for source store}, {
URL = "file://localhost/Users/greg/Library/Application%20Support/iPhone%20Simulator/4.3.2/Applications/69FDFDCF-631D-4191-B852-CD75151B1EA9/Documents/MyApp.sqlite";
metadata = {
NSPersistenceFrameworkVersion = 320;
NSStoreModelVersionHashes = {
Config = <5f92f988 71e11a66 554ae924 61887562 22b8de8a c318b110 e3e4a569 81adafa2>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers …Run Code Online (Sandbox Code Playgroud) 所以我在App Store中拥有我的Core Data应用程序版本1,现在我开始处理第2版.
我对我的数据库模型进行了一些小的更改,并且我需要在完成从版本1到版本2的升级之后运行一些自定义代码.
我可以使用Core Data的轻量级迁移来处理模型更改,并且我可以在迁移完成后运行自定义代码.
问题是,我不确定将来会发生什么,当我构建版本3,4,5 ...
假设是这种情况:
版本1到版本2 - 使用轻量级迁移
版本2到版本3 - 使用模型映射
版本3到版本4的自定义迁移- 再次使用轻量级迁移
等等.
我不确定如何构建一个处理轻量级和自定义迁移混合的机制.
我在网上或在核心数据文档中找不到任何谈论这个问题的代码,我的意思是这是大多数核心数据应用程序的一个非常常见的问题,是否有针对此问题的最佳实践示例?
从由两个单独的xcdatamodel文件定义的存储迁移时,我遇到执行轻量级迁移的问题.
在我的应用程序的1.0版本中,我将模型分解为分析模型,模型A以及模型B中的所有其他模型.编译时,模型将组合在一起,一切都顺利进行.
在处理新版本1.1时,我通过向模型B添加新模型版本并将该新版本设置为活动来升级模型B.
从1.0升级到1.1时会出现问题.似乎Core Data检查磁盘上的模型存储(由版本1.0创建)并查找描述它的模型,但无法找到定义整个存储的SINGLE模型(模型A仅涵盖分析,模型B覆盖其他一切),所以它抛出"无法找到源存储模型"错误.
有没有人找到分离模型的解决方案,但仍然允许升级+轻量级迁移工作,而无需定义自定义迁移的额外麻烦?
以下是用于加载模型的代码片段:
NSArray *modelNames = [NSArray arrayWithObjects:@"model-A", @"model-B", nil];
NSMutableArray *models = [NSMutableArray array];
for (NSString *name in modelNames)
{
LogInfo(@"loading model %@", name);
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:name withExtension:@"momd"];
NSManagedObjectModel *model = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] autorelease];
[models addObject:model];
}
// combine all the separate models into one big one
objectModel = [[NSManagedObjectModel modelByMergingModels:models] retain];
NSURL *documentsDirectory = [NSURL fileURLWithPath:[SuperFileManager documentsDirectory] isDirectory:YES];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"database.sqlite"];
NSError *error = nil;
coordinator = [[NSPersistentStoreCoordinator …Run Code Online (Sandbox Code Playgroud) 我正在使用自定义实体迁移策略为我的迁移构建映射模型,我真的想为此迁移构建一些单元测试.当我运行应用程序时,迁移似乎正常工作,但当我通过单元测试运行迁移时,根本不会调用我的NSEntityMigrationPolicy子类方法.
我正在使用Xcode的内置OCUnit框架.
我的测试代码:
- (void)test1to2Migration_appIdentifierMoved {
[self createVersion1Store];
// TODO Perform migration
NSManagedObjectModel *version1Model = [self version1Model];
NSManagedObjectModel *version2Model = [self version2Model];
NSError *error = nil;
NSMappingModel *mappingModel = [NSMappingModel
inferredMappingModelForSourceModel:version1Model
destinationModel:version2Model error:&error];
STAssertNotNil(mappingModel, @"Error finding mapping model: %@", error);
NSMigrationManager *migrationManager =
[[[NSMigrationManager alloc]
initWithSourceModel:version1Model
destinationModel:version2Model]
autorelease];
BOOL migrationSucceeded =
[migrationManager migrateStoreFromURL:self.version1StoreURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:self.version2StoreURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&error];
STAssertTrue(migrationSucceeded, @"Error migrating store: %@", error);
// TODO Verify appIdentifier is moved from Project to its Tests
[self deleteTempStores];
} …Run Code Online (Sandbox Code Playgroud) 我试图在手机IOS 13 Beta上从Xcode11 beta构建我的应用程序。加载应用程序时发生崩溃。
2019-07-22 13:58:12.910460 + 0300 GoodWine [3738:792501] [错误]错误:此应用程序中的一个或多个模型使用的可变形属性的变压器名称未设置或设置为NSKeyedUnarchiveFromDataTransformerName。请改用“ NSSecureUnarchiveFromData”或NSSecureUnarchiveFromDataTransformer的子类。在某些时候,当指定nil时,Core Data将默认使用“ NSSecureUnarchiveFromData”,并且包含不支持NSSecureCoding的类的可转换属性将变得不可读。
CoreData:错误:此应用程序中的一个或多个模型正在使用可变形的属性,且其变压器名称未设置或设置为NSKeyedUnarchiveFromDataTransformerName。请改用“ NSSecureUnarchiveFromData”或NSSecureUnarchiveFromDataTransformer的子类。在某些时候,当指定nil时,Core Data将默认使用“ NSSecureUnarchiveFromData”,并且包含不支持NSSecureCoding的类的可转换属性将变得不可读。
2019-07-22 13:58:12.910595 + 0300 GoodWine [3738:792501] [错误] CoreData:此应用程序中的一个或多个模型使用的可变形属性的变压器名称未设置或设置为NSKeyedUnarchiveFromDataTransformerName。请改用“ NSSecureUnarchiveFromData”或NSSecureUnarchiveFromDataTransformer的子类。在某些时候,当指定nil时,Core Data将默认使用“ NSSecureUnarchiveFromData”,并且包含不支持NSSecureCoding的类的可转换属性将变得不可读。
CoreData:警告:实体“ SFMCKeyValueEntity”上的属性“值”正在使用nil或不安全的NSValueTransformer。请改用“ NSSecureUnarchiveFromData”或NSSecureUnarchiveFromDataTransformer的子类。
我们有两个独立的应用程序,我们已合并到同一工作区中的2个目标.两者都有他们的核心数据模型(app1.xcdatamodeld和app2.xcdatamodeld).
既然两者都在同一个工作区,就不需要2个模型,因为它们有99%的相似性.所以我想将.xcdatamodeld包的名称更改为allApps.xcdatamodeld.我能够重命名它,但是在执行此操作时我没有找到有关迁移行为的任何参考.
这是错误 -
2015-07-28 09:04:06.079 AppName[51306:1423128] CoreData: error:
-addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/shani/Library/Developer/CoreSimulator/Devices/EA75A69F-B108-4036-AB3D-B923F83D16DE/data/Containers/Data/Application/B1CB3AF3-DEF4-40DF-9A61-721063ECBB1D/Documents/AppName.sqlite
options:{
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSSQLitePragmasOption = {
"journal_mode" = WAL;
}; } ... returned error Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error
134130.)" UserInfo=0x7fc39c194360 {URL=file:///Users/shani/Library/Developer/CoreSimulator/Devices/EA75A69F-B108-4036-AB3D-B923F83D16DE/data/Containers/Data/Application/B1CB3AF3-DEF4-40DF-9A61-721063ECBB1D/Documents/AppName.sqlite,
metadata={
NSPersistenceFrameworkVersion = 519;
NSStoreModelVersionHashes = {
Attempt = <b4d1e878 69a97917 e751a67c 89e1887a ae4df1dc f380e4ee c9585f60 f39ff51e>;
BookmarkFlashcard = <33112f7c 2fa20bec eb2e019c b5d619b4 92be2547 a65fabee 1ac86ab7 92dd77bb>;
BookmarkQuestion = …Run Code Online (Sandbox Code Playgroud) core-data ×10
ios ×8
iphone ×5
objective-c ×2
ios13 ×1
ocunit ×1
swift ×1
unit-testing ×1
xcode ×1
xcode11 ×1