2012-06-23 32 views
15

Tôi tải một mô hình NSManagedObjectModel với initWithContentsOfURL: constructor như thế này:tải một mô hình phiên bản trước

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

Tuy nhiên điều này chỉ mang lại cho tôi tiếp cận với phiên bản mới nhất/hiện tại của một mô hình. Có thể tải các phiên bản trước đó bằng cùng một tệp momd không? làm sao?

Trả lời

32

Trên thực tế bạn có thể tải phiên bản cũ với:

- (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; 
} 

Chỉ cần thay thế AppModel với tên mô hình của bạn.

Tôi đang sử dụng tính năng này để thoát khỏi tình huống di chuyển thủ công liên quan đến iCloud. Tìm kiếm cao và thấp và không thể tìm thấy ở bất cứ đâu.

+0

fyi trên phiên bản của tôi (7.1) phiên bản .mom (s) nằm trong một tệp có cùng tên với phiên bản (vì vậy @ "... /% @", phiên bản thay vì @ "/.../ AppModel% @", phiên bản) –

-2

Không, không thể dự đoán được điều này là có thể. Tôi suy luận rằng từ NSManagedObjectModeldocumentation, nơi nó nói thảo luận về bất động sản versionIdentifiers:

Giá trị này có nghĩa là để được sử dụng như một gợi ý gỡ lỗi để giúp bạn xác định các mô hình đã được kết hợp để tạo ra một mô hình sáp nhập.

Vì vậy, có vẻ như bạn không phải sử dụng các phiên bản mô hình trước đó cho logic chương trình của bạn.

+0

bạn thường làm cách nào để di chuyển tùy chỉnh? để tạm thời giải quyết điều này, tôi tạo một bản sao của thư mục cho mô hình dữ liệu của tôi (chứa tất cả các phiên bản một lần nữa) và đặt làm phiên bản mặc định của phiên bản cũ mà tôi muốn hỗ trợ. Bằng cách đó tôi có thể xây dựng các trường hợp cũ và mới của NSManagedObjectModel mà tôi cần cho NSMigrationManager – SystematicFrank

+0

Tôi không đồng ý với điều này. Xin vui lòng xem câu trả lời của tôi. – Schoob

3

Nếu bạn chỉ muốn tải các phiên bản của mô hình đó là tương thích với một cửa hàng đặc biệt thử hiện:

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

Lưu ý rằng nếu bạn sử dụng định danh phiên bản XCode cho các phiên bản mô hình dữ liệu của bạn, phiên bản hiện tại các cửa hàng liên tục của định danh có thể truy cập thông qua mục nhập NSStoreModelVersionIdentifiersKey trong từ điển siêu dữ liệu cửa hàng.

Khi tải một phiên bản tùy ý cụ thể, các tệp mẹ thường nằm trong thư mục mẹ trong gói ứng dụng của bạn, vì vậy bạn có thể liệt kê chúng bằng NSFileManager. Tôi tin rằng để tìm một với một định danh phiên bản cụ thể bạn sẽ phải sử dụng initWithContentsOfURL của NSManagedObjectModel: initializer và sau đó kiểm tra thuộc tính versionIdentifiers, hoặc sử dụng phương thức instance isConfiguration: compatibleWithStoreMetadata: để xác định khả năng tương thích.

+0

Và kiểm tra một cửa hàng nilMetadata trong trường hợp bạn không có một cơ sở dữ liệu hiện có, do đó cần phải tạo một cơ sở dữ liệu! –

2

Làm cho solution được @Schoob cung cấp thành một danh mục, vì chúng đá.

@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 
0

Phiên bản Swift. Thay thế tên tệp.

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 
    } 
} 
Các vấn đề liên quan