2012-10-06 25 views
5

câu hỏi ngắn:Xác định khi có phiên bản mới trong mô hình dữ liệu cốt lõi

Tôi muốn chạy một mã số nhất định trong ứng dụng của tôi chỉ khi model Core Data của tôi đã thay đổi (thực thể mới, tính chất mới, vv). Làm cách nào để xác định xem mô hình có thay đổi hay không?

Chỉ cần một số mã giả:

if (current_model_version != previous_model_version) { 
    //do some code 
    } else { 
    // do some other code 
    } 

Tôi đoán tôi có thể sử dụng versionHashes để làm điều này, hoặc isConfiguration: compatibleWithStoreMetadata :, nhưng tôi không chắc chắn như thế nào.

Một số chỉnh sửa để làm rõ: 'hiện tại' như trong 'hiện tại' và 'trước' như trong 'ứng dụng thời gian qua đã được khởi chạy'.

+1

Có lẽ [Lõi Data Model Versioning and Data Migration] (http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreDataVersioning/Articles/Introduction.html) hướng dẫn giúp. – Rob

+0

Vâng, tôi đã đào bới nó. isConfiguration: compatibleWithStoreMetadata: đã giải quyết nó cho tôi, nhưng tôi cần một ví dụ về việc thực hiện để hiểu chính xác nó được sử dụng như thế nào. –

+0

'isConfiguration: compatibleWithStoreMetadata:' sẽ không cho bạn biết rằng có phiên bản mới - nó sẽ chỉ cho bạn biết rằng có phiên bản _incompatible_. Nếu phiên bản mới của bạn có thể được di chuyển tự động thì điều này sẽ trả về 'CÓ'. _ Tôi chỉ chắc chắn 90% về điều này - bạn có thể phải thử nghiệm để chứng minh tôi đúng/sai! _ – deanWombourne

Trả lời

8

Câu trả lời có vẻ là isConfiguration: compatibleWithStoreMedia:.

Tôi tìm thấy một số thông tin hữu ích ở đây:

http://mipostel.com/index.php/home/70-core-data-migration-standard-migration-part-2

tôi thiết lập nó theo cách này:

- (BOOL)modelChanged 
{ 
    NSError *error; 
    NSURL * sourceURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"db.sqlite"]; 
    NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:sourceURL error:&error]; 
    BOOL isCompatible = [[self managedObjectModel] isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata]; 

    return isCompatible; 

} 

'tự' là lưu trữ dữ liệu chia sẻ của tôi, không phải là nó nhất thiết phải đi đó.

deanWombourne chỉ ra rằng điều này thực sự là xác định liệu dữ liệu có thể được tự động di chuyển hay không, vì vậy nó không chính xác là giải pháp cho vấn đề tôi đặt ra. Nó phục vụ nhu cầu của tôi trong trường hợp này.

+1

Có lỗi đánh máy trong đó - không chuyển sourcePath thành tham số cấu hình cho isConfiguration: compatibleWithStoreMetadata: Cũng lưu ý rằng điều này sẽ chỉ trả về YES nếu cửa hàng khớp với mô hình đối tượng hiện tại, vì vậy bạn không thể sử dụng để xác định cửa hàng có thể được di chuyển. Bạn phải thử di chuyển và kiểm tra lỗi. – DavidA

+0

Điều này sẽ trả về nghịch đảo logic của isCompatible, phải không? Nếu nó không tương thích, đó là vì mô hình đã thay đổi, đúng không? –

+1

Tôi đã thay thế isConfiguration: sourcePath bằng isConfiguration: không làm cho mã hoạt động. Nó có vẻ giống như một lỗi đánh máy – sergtk

1

Đây là mã thay thế cho - (NSPersistentStoreCoordinator *)persistentStoreCoordinator mà bạn nhận được nếu bạn đánh dấu vào hộp Dữ liệu cốt lõi khi thiết lập dự án mới trong XCode.

Cố gắng mở tệp sqlite hiện có (sử dụng di chuyển nhẹ nếu cần). Nếu điều đó không thành công, nó sẽ xóa và tạo lại cửa hàng.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator != nil) { 
     return _persistentStoreCoordinator; 
    } 

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 

    NSError *error = nil; 

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error]) 
    { 
     NSLog(@"Couldn't open the store. error %@, %@", error, [error userInfo]); 

     [self deleteSqliteFilesForStore:self.storeURL]; 

     if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error]) 
     { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

      // or [NSException raise ...] 
     } 
     else 
     { 
      NSLog(@"Store deleted and recreated"); 

      // TEST DATA RE-INITIALIZATION CODE GOES HERE 
     } 
    } 
    else 
    { 
     NSLog(@"Existing Store opened successfully"); 
    } 

    return _persistentStoreCoordinator; 
} 

- (void)deleteSqliteFilesForStore:(NSURL *)storeURL 
{ 
    NSURL *baseURL = [storeURL URLByDeletingPathExtension]; 

    // Delete the associated files as well as the sqlite file 

    for (NSString *pathExtension in @[@"sqlite",@"sqlite-shm",@"sqlite-wal"]) 
    { 
     NSURL *componentURL = [baseURL URLByAppendingPathExtension:pathExtension]; 

     BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[componentURL path]]; 
     if(fileExists) 
     { 
      [[NSFileManager defaultManager] removeItemAtPath:[componentURL path] error:nil]; 
     } 
    } 
} 
Các vấn đề liên quan