Обнаружение облегченной миграции основных данных - PullRequest
21 голосов
/ 11 июня 2010

Я успешно использую облегченную миграцию Core Data.Однако, когда конкретная сущность создается во время миграции, я бы хотел заполнить ее некоторыми данными.Конечно, я мог бы проверять, является ли объект пустым при каждом запуске приложения, но это кажется неэффективным, когда Core Data имеет инфраструктуру миграции.

Можно ли определить, когда происходит легкая миграция (возможно, с помощью KVO или уведомлений), или для этого требуется реализация стандартных миграций?

Я пытался использовать NSPersistentStoreCoordinatorStoresDidChangeNotification, но он не срабатывает, когда происходят миграции.

Ответы [ 3 ]

58 голосов
/ 12 июня 2010

Чтобы определить необходимость миграции, проверьте, совместима ли модель управляемого объекта координатора постоянного хранилища с метаданными существующего хранилища (адаптировано из Необходима ли миграция Apple ):

NSError *error = nil;
persistentStoreCoordinator = /* Persistent store coordinator */ ;
NSURL *storeUrl = /* URL for the source store */ ;

// Determine if a migration is needed
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
                                                                                          URL:storeUrl
                                                                                        error:&error];
NSManagedObjectModel *destinationModel = [persistentStoreCoordinator managedObjectModel];
BOOL pscCompatibile = [destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata];
NSLog(@"Migration needed? %d", !pscCompatibile);

Если pscCompatibile равно NO, то потребуется выполнить миграцию.Чтобы проверить изменения сущности, сравните ключ NSStoreModelVersionHashes в словаре sourceMetadata со значением [destinationModel entities]:

NSSet *sourceEntities = [NSSet setWithArray:[(NSDictionary *)[sourceMetadata objectForKey:@"NSStoreModelVersionHashes"] allKeys]];
NSSet *destinationEntities = [NSSet setWithArray:[(NSDictionary *)[destinationModel entitiesByName] allKeys]];

// Entities that were added
NSMutableSet *addedEntities = [NSMutableSet setWithSet:destinationEntities];
[addedEntities minusSet:sourceEntities];

// Entities that were removed
NSMutableSet *removedEntities = [NSMutableSet setWithSet:sourceEntities];
[removedEntities minusSet:destinationEntities];

NSLog(@"Added entities: %@\nRemoved entities: %@", addedEntities, removedEntities);
2 голосов
/ 21 июля 2018

Принятый ответ конвертируется в Swift ...

  var persistentStoreCoordinator: NSPersistentStoreCoordinator?
  var url: URL
  do {
    let sourceMetadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: url, options: nil)
    if let destinationModel = persistentStoreCoordinator?.managedObjectModel {
      let compatibile = destinationModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: sourceMetadata)
      if !compatibile {
        if let versionHashes = sourceMetadata["NSStoreModelVersionHashes"] as? [String: Any] {
          let sourceEntities = Set(versionHashes.keys)
          let destinationEntities = Set(destinationModel.entitiesByName.keys)

          var addedEntities = Set(destinationEntities)
          addedEntities.subtract(sourceEntities)

          var removedEntities = Set(sourceEntities)
          removedEntities.subtract(destinationEntities)
          let modelName = (destinationModel.versionIdentifiers.first as? String) ?? ""
          NSLog("Core Data requires a migration to model '\(modelName)'...\nAdded: \(addedEntities)\nRemoved: \(removedEntities)")
        }
      }
    }
  } catch {
            ...
  }
1 голос
/ 21 сентября 2010

Как насчет создания подкласса NSManagedObject для этой сущности, а затем переопределения -awakeFromInsert :? Или вы создаете эту сущность в других частях вашего приложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...