iPhone核心数据轻量级迁移Cocoa错误134130:找不到源存储的模型

esi*_*ver 16 iphone core-data

伙计们,

轻量级迁移在这条线上100%的时间都失败了:

[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]
Run Code Online (Sandbox Code Playgroud)

有错误:

Error: Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x4fbff20 "Operation could not be completed. (Cocoa error 134130.)"
"Can't find model for source store";
Run Code Online (Sandbox Code Playgroud)

这是我的托管对象上下文,模型和持久性存储:

- (NSManagedObjectContext *) managedObjectContext {

    if (managedObjectContext != nil) {
        return managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }

    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Locations.sqlite"]];

    NSError *error;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    // Allow inferred migration from the original version of the application.
    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)

我在我的项目我的模型的两个版本:一个版本4和版本5,如果我把我的版本4作为默认值,它工作正常.如果我选择"设计- >数据模型- >添加模型版本"(如由这个帖子),做出改变,设计- >数据模型- >设置当前版本,构建和运行,它会失败,与上述"灿找不到源存储的模型"错误.将模型设置回版本4,没有问题,addPersistentStoreWithType.或者,如果我添加模型版本,并没有变化,只是从版本4到5无需添加任何新的领域,没有任何问题.如果我然后尝试从5到6,上述错误.

此代码在Simulator和Phone上都失败了.我阅读了几个要求删除和重新安装应用程序的处方,这对于模拟器和手机都有效,但我担心当我向真实用户发布时,它会破坏我的安装基础,因为它们将无法删除并重新安装 - App Store将自动升级它们.

这段代码在过去的版本中工作,我没有任何变化 - 因此我有能力将它一直升级到版本4.我最近升级到iOS4的XCode 3.2.3版本,这可能与此有关.

现在,像我这样的人突然有这个问题吗?有没有人设法超越它?谢谢.

PS - 对于偶然发现此页面的Google员工,以下是您可能会考虑阅读的所有相关页面,如下所示.不幸的是,这些都没有解决我的问题

UPDATE

虽然这不是一个真正的修复,但它确实避免了崩溃客户端的情况:只需删除数据库文件:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {



    // Delete file
    if ([[NSFileManager defaultManager] fileExistsAtPath:storeUrl.path]) {
        if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) 
    {
        // Handle the error.
        NSLog(@"Error: %@",error);
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();

    }
}    
Run Code Online (Sandbox Code Playgroud)

更新2

以下是我检查VersionInfo.plist时会发生的情况:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>NSManagedObjectModel_CurrentVersionName</key>
        <string>Profile 5</string>
        <key>NSManagedObjectModel_VersionHashes</key>
        <dict>
                <key>Profile</key>
                <dict>
                        <key>Profile</key>
                        <data>
                        ZIICGgMBreuldkPXgXUhJwKamgwJzESM5FRTOUskomw=
                        </data>
                </dict>
                <key>Profile 2</key>
                <dict>
                        <key>Profile</key>
                        <data>
                        tEB7HrETWOSUuoeDonJKLXzsxixv8ALHOoASQDUIZMA=
                        </data>
                </dict>
                <key>Profile 3</key>
                <dict>
                        <key>Profile</key>
                        <data>
                        qyXOJyKkfQ8hdt9gcdFs7SxKmZ1JYrsXvKbtFQTTna8=
                        </data>
                </dict>
                <key>Profile 4</key>
                <dict>
                        <key>Profile</key>
                        <data>
                        lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw=
                        </data>
                </dict>
                <key>Profile 5</key>
                <dict>
                        <key>Profile</key>
                        <data>
                        V4PyRK1ezj3xK1QFRCTVzGOqyJhEb7FRMzglrTsP0cI=
                        </data>
                </dict>
        </dict>
</dict>
</plist>
Run Code Online (Sandbox Code Playgroud)

这是我编写的用于检查模型的代码(注意我必须出去添加一个base64编码器,因为这是VersionInfo.plist文件中的内容)

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {


    NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:storeUrl error:&error];
    NSLog(@"%@",storeMeta);
    id someObj = [[storeMeta objectForKey:@"NSStoreModelVersionHashes"] objectForKey:@"Profile"];
    NSLog(@"%@",someObj);
    NSLog(@"%@",[NSString base64StringFromData:someObj length:[someObj length]]);
Run Code Online (Sandbox Code Playgroud)

这是调试输出:

{
    NSPersistenceFrameworkVersion = 310;
    NSStoreModelVersionHashes =     {
        Profile = <97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c>;
        SerializedMessage = <4530863c d943479a edfb4dfb 5059c28d d6137dc4 d1153d36 ed52be49 11074f13>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
    );
    NSStoreType = SQLite;
    NSStoreUUID = "823FD306-696F-4A0F-8311-2792825DC66E";
    "_NSAutoVacuumLevel" = 2;
}

<97258324 9d2419cb 3fa5438c a1d77743 5ca60ef7 5188d5ee 8b8342a4 bc43152c>
lyWDJJ0kGcs/pUOModd3Q1ymDvdRiNXui4NCpLxDFSw=
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,是开头最后一行"立法院"的比赛资料4 VersionInfo.plist ......所以我看不出有什么理由应该失败.还有其他想法吗?

Tec*_*Zen 9

我阅读了几个要求删除和重新安装应用程序的处方,这对于模拟器和手机都有效,但我担心当我向真实用户发布时,它会破坏我的安装基础,因为它们将无法删除并重新安装.

这是一个问题,因为当模型文件被更改时,Xcode不会从模拟器/ dev-device中删除旧的momc文件,例如更改名称.旧文件仍然会导致混淆.这是你在开发过程中只看到的东西,因为它是Xcode操纵应用程序包的方式的工件,而不是每次完全重新安装它,就像发布版本必须发生的那样.

您可以确认此记录返回:

[[NSBundle mainBundle] URLsForResourcesWithExtension:@"momc"subdirectory:nil];
Run Code Online (Sandbox Code Playgroud)

...应该显示应用程序包中所有已编译的模型文件

在开发过程中依赖迁移是不好的做法,因为如果要对模型和存储进行更改,迁移失败是很常见的.所有代码都被固定后,您应该只使用迁移.我还建议您每次运行时从头开始重新生成商店.通过更改模型很容易在商店中建立垃圾.


esi*_*ver -2

各位,

根据记录,我完全停止使用核心数据。我的代码很复杂,并且根据上述问题,不可靠。我现在直接使用 SQLLite,并且更加高兴。我不建议在任何情况下使用 Core Data。

  • 您不应该将“我不理解 API”误认为“它太复杂了”。使用 SQL 和 Core Data 后,后者总体上是更简单的 API,尤其是当应用程序变得更加复杂时。我认为您的问题是由于尝试迁移开发版本引起的,特别是尝试迁移已经失败的文件。 (11认同)
  • 根据我的经验,这并不是“太复杂”,API 完全不符合规范。核心数据非常适合具有简单迁移需求的玩具应用程序;正如您从我的问题和本页上的其他评论中看到的,自动迁移在一定程度的复杂性下会崩溃。也许他们已经修复了它,但我不会回去,因为 SQLite 既可以工作,又很容易理解。 (3认同)
  • 我对核心数据也感到非常恼火。当出现问题时,“神奇”的数据迁移过程就太不透明了。我没有在一个地方找到足够的详细信息来揭开盖子并深入了解数据迁移所遇到的问题。 (2认同)
  • 作为一个具有 35 个不同模型版本的应用程序的 Core Data 的重度用户,并且每个版本之间都有迁移,我可以高兴地说,这个答案比 Core Data 差 10 倍。是的,它可能会引起一些头痛,但它们的存在是有原因的。Core Data 的强大,只要你运用得当。提倡其他人因为你不喜欢它而拒绝使用它,甚至仅仅因为它复杂而拒绝使用它,这对公众没有好处。正确的答案应该是如何解决您的问题。不要完全扔掉一切。 (2认同)
  • 更新:显然开发社区分享了我对这项技术的经验:https://news.ycombinator.com/item?id=5454491 (2认同)
  • 那是 iCloud,而不是核心数据。我同意,与 iCloud 的核心数据同步严重损坏。但核心数据本身就很惊人。 (2认同)