core-data - tutorial - swift 4 core data example
Cargar una versión del modelo anterior. (5)
Estoy cargando un modelo NSManagedObjectModel con initWithContentsOfURL: constructor como este:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDocument" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Sin embargo, esto solo me da acceso a la versión más reciente / actual de un modelo. ¿Es posible cargar versiones anteriores con el mismo archivo momd ? ¿cómo?
En realidad puedes cargar una versión anterior con:
- (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;
}
Simplemente reemplace AppModel con el nombre de su modelo.
Estoy usando esto para salir de una situación de migración manual que involucra iCloud. Busqué alto y bajo y no pude encontrar esto en ninguna parte.
Hizo la solution ofrecida por @Schoob en una categoría, porque oscilan.
@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
No, no está previsto que esto sea posible. Deduzco eso de la documentation NSManagedObjectModel
, donde dice que discute la propiedad versionIdentifiers
:
Este valor se debe utilizar como una sugerencia de depuración para ayudarlo a determinar los modelos que se combinaron para crear un modelo fusionado.
Por lo tanto, no parece que deba utilizar versiones de modelo anteriores para la lógica de su programa.
Si solo desea cargar la versión del modelo que es compatible con una tienda existente en particular, intente:
NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSManagedObjectModel *oldManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]
forStoreMetadata:storeMetadata];
Tenga en cuenta que si utiliza los identificadores de versión de XCode para las versiones de su modelo de datos, podrá acceder a los identificadores de la versión actual de la tienda persistente a través de la entrada NSStoreModelVersionIdentifiersKey en el diccionario de metadatos de la tienda.
En lo que respecta a la carga de una versión arbitraria en particular, los archivos mom normalmente se encuentran debajo del directorio momd en el paquete de su aplicación, por lo que podría enumerarlos usando NSFileManager. Creo que para encontrar uno con un identificador de versión en particular, tendría que usar NSManagedObjectModel initWithContentsOfURL: initializer y luego inspeccionar la propiedad versionIdentifiers, o usar isConfiguration: compatibleWithStoreMetadata: método de instancia para determinar la compatibilidad.
Versión rápida. Reemplace el nombre del archivo.
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
}
}