Подтвердить что ты не робот

Выполнение пользовательского кода после легкого перемещения определенной версии

У меня есть 2 объектных модели в Core Data (скажем, v1 и v2). Эта миграция имеет право на легкую миграцию. Теперь я хочу выполнить пользовательский код после миграции, но только тогда, когда миграция происходит от v1 до v2. Позже, если я введу v3, я не хочу, чтобы пользовательский код выполнялся.

Есть ли способ сделать это?

Спасибо заранее, Anupam

4b9b3361

Ответ 1

Вот как справиться с этой ситуацией, в основном, используя метаданные хранилища, как предложили инженеры Apple на WWDC 2010:

  • Откройте хранилище (с параметрами миграции)
  • Проверить метаданные для настраиваемого ключа, например. "DonePostProcessing"
  • После обработки...
    • Начисление атрибутов
    • Вставка или удаление объектов
    • Установить метаданные хранилища ( "DonePostProcessing" = YES)
  • Сохранить изменения и метаданные

Более или менее, что-то вроде



- (void)loadStoreWithMigration:(NSURL *)url {
    ...

   store = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: url options: opts error: &err];

   m = [store metadata];
   key = @"DonePostProcessing";
   if (m && ([[m objectForKey: key] integerValue] < 2) ){
      [self doPostProcessingInContext: context];
      m2 = [[m mutableCopy] autorelease];
      [m2 setObject: [NSNumber numberWithInteger: 2] forKey: key];
      [store setMetadata: m2];

      ok = [context save:&err];
   }

}

Ответ 2

Там может быть лучший способ, купить это должно работать:

Отслеживайте версию БД, сохраняя объект в Core Data с именем "Информация" и обладающий свойством "CoreDataVersion" .

После завершения кода переноса добавьте код для проверки номера версии в основных данных.

Если значение "CoreDataVersion" равно "v1" , и ваше приложение теперь находится на "v2" (это может быть жестко запрограммировано с каждой версией), выполните дополнительный настраиваемый код и затем напишите новую версию обратно в базу данных.

Если у вас уже есть "v1" для пользователей, просто скажите, что если в базе данных нет "CoreDataVersion" , то это "v1" .

Ответ 3

- (void) _performMaintanaceUpdate:(NSUInteger) newVersion oldVersion:(NSUInteger) oldVersion {
            if (newVersion>=1020500 && oldVersion < 1020500) {
                NSString *storePath = [[PreferenceDataModel getDataPath] stringByAppendingPathComponent: @"wcal.sqlite"];
                NSFileManager *fileManager = [NSFileManager defaultManager];
                if ([fileManager fileExistsAtPath:storePath]) {
                        [fileManager removeItemAtPath:storePath error:NULL];
                }
                [PreferenceDataModel setVersionOfLastMaintanace:newVersion]; 
            }
}

 (void) _checkAndPerformMaintenance{
    NSString* strVersion = [PreferenceDataModel getApplicationVersion];
    //legal version is xx.xx.xx where x is a dec digit 1.2 or 1.2.33 is legit 
    NSUInteger ver = 0;
    NSUInteger finalVer = 0;
    int t = 3; 

    for (int i=0; i<[strVersion length]; i++) {
        char c = [strVersion characterAtIndex:i];
        if (isdigit(c)) {
            ver*=10;
            ver+=c - 48;
        }
        else {
            finalVer+= ver * pow(100, t--); 
            ver = 0;
        }
    }
    finalVer+= ver * pow(100, t);
    [self _performMaintanaceUpdate:finalVer oldVersion:[PreferenceDataModel getVersionOfLastMaintanace]];
}

и именно так вы получаете версию приложений

+(NSString *) getApplicationVersion {
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
}

Ответ 4

Прежде чем создавать постоянное хранилище, которое выполняет автоматическую миграцию, определите, будет ли вы переноситься на версию 2. Если вы хотите, установите флаг для внесения изменений после переноса.

Чтобы определить, из чего вы будете перемещаться, сделайте следующее:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
NSString *version = [managedObjectModel.versionIdentifiers anyObject];

Идентификаторы версии задаются в Xcode.

Ответ 6

Другое решение, которое сработало для меня:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSInteger currVersion = [defaults integerForKey:@"dataModelVersion"];
    NSString *version = [managedObjectModel.versionIdentifiers anyObject];
    if (currVersion == 0) {
        [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"];
    }
    else if (currVersion < [version integerValue]) {
        NSLog(@"Migration Code");
        [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"];
    }