将先前的模型版本(Load a previous model version)

2019-07-30 02:03发布

我加载NSManagedObjectModel模型与initWithContentsOfURL:构造是这样的:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDocument" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

然而,这只是给了我访问的最新车型/当前版本。 难道是更多钞票来加载以前版本的同一个文件momd? 怎么样?

Answer 1:

其实你可以加载使用旧版本:

- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString *)version
{
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"AppModel.momd/AppModel %@",version] withExtension:@"mom"];
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        return model;
 }

只需用型号名称替换AppModel。

我用这个来让自己出的,涉及的iCloud粘性手动迁移情况。 搜索的高和低,找不到这在任何地方。



Answer 2:

如果你只是想加载与特定的现有商店尝试兼容模式的版本:

NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType 
                                                                                         URL:storeURL 
                                                                                       error:&error];
NSManagedObjectModel *oldManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]] 
                                                                          forStoreMetadata:storeMetadata];

请注意,如果您使用的XCode版本标识符为您的数据模型版本,持久性存储的当前版本标识符通过在存储元数据字典中的NSStoreModelVersionIdentifiersKey入口访问。

至于加载特定版本的任意而言,妈妈文件通常位于您的应用程序的包的momd目录下,因此你可以使用的NSFileManager一一列举。 我相信,找到一个与特定的版本标识,你将不得不使用NSManagedObjectModel的initWithContentsOfURL:初始化,然后检查versionIdentifiers财产,或使用isConfiguration:compatibleWithStoreMetadata:实例方法来确定兼容性。



Answer 3:

做出的解决方案通过提供@Schoob成一类,因为他们摇滚。

@interface NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version;
@end

@implementation NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version
{
    if(!bundle)
        bundle = [NSBundle mainBundle];

    NSString *resource = [[modelName stringByAppendingPathExtension:@"momd"] stringByAppendingPathComponent:version];
    NSURL *modelURL = [bundle URLForResource:resource withExtension:@"mom"];
    NSAssert(modelURL,@"Unable to find MOM - %@",resource);
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    NSAssert(model,@"Unable to load MOM at URL- %@",modelURL);
    return model;
}
@end


Answer 4:

斯威夫特版本。 替换文件名。

import CoreData

extension NSManagedObjectModel
{
    class func model(forVersion version: Int) -> NSManagedObjectModel?
    {
        if let fileUrl = Bundle.main.url(forResource: "Model.momd/Model \(version)", withExtension: "mom")
        {
            return NSManagedObjectModel(contentsOf: fileUrl)
        }
        return .none
    }
}


Answer 5:

不,它不是预见,这是可能的。 我推断,从NSManagedObjectModel 文档 ,它说:在讨论财产versionIdentifiers

这个值是为了用作调试提示,以帮助您确定合并,以创建一个合并的模型,该模型。

因此,它似乎没有你应该使用以前的模型版本的程序逻辑。



文章来源: Load a previous model version