2015-02-25 1 views
3

J'essaie de déplacer mon NSPersistentStore du sandbox de mon application vers un conteneur de groupe partagé afin que je puisse accéder à CoreData depuis mon extension WatchKit. J'utilise actuellement Core Data avec iCloud et je souhaite déplacer les données des utilisateurs vers le conteneur de groupe partagé. Actuellement, je suis en train de créer le NSPersistentStoreCoordinator comme suit:Migration de NSPersistentStore du sandbox de l'application vers le conteneur de groupe partagé

if (__persistentStoreCoordinator != nil) { 
    return __persistentStoreCoordinator; 
} 

NSURL *url = [self storeURL]; // app's Documents directory 
NSError *error = nil; 
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:[self iCloudPersistentStoreOptions] error:&error]) { 
    NSLog(@"Error adding persistent store: %@", [error localizedDescription]); 
} 

// rest of setup 

return __persistentStoreCoordinator; 

J'ai déjà configuré le conteneur de groupe partagé dans mon objectif d'application et la cible d'extension WatchKit et peut obtenir le NSURL pour le nouvel emplacement de magasin à l'aide - (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier.

Comment puis-je vérifier si j'ai besoin de migrer ou si j'ai déjà migré pour ne pas tenter de migrer plusieurs fois? Au début, je pensais à quelque chose comme ça, mais cela ne fonctionne pas comme l'ancienne URL du magasin n'existe pas

if (__persistentStoreCoordinator != nil) { 
    return __persistentStoreCoordinator; 
} 

NSURL *newURL = [self newStoreURL]; // shared group container 
NSURL *oldURL = [self oldStoreURL]; // app's Documents directory 

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

NSFileManager *fileManager = [NSFileManager defaultManager]; 

if (![fileManager fileExistsAtPath:newURL.path] && [fileManager fileExistsAtPath:oldURL.path]) { 
    NSLog(@"performing migration..."); 
    NSPersistentStore *oldStore = [__persistentStoreCoordinator persistentStoreForURL:oldURL]; 
    NSError *migrateError = nil; 
    NSPersistentStore *newStore = [__persistentStoreCoordinator migratePersistentStore:oldStore toURL:newURL options:[self iCloudPersistentStoreOptions] withType:NSSQLiteStoreType error:&migrateError]; 
    if (!newStore) { 
     NSLog(@"Error migrating store: %@", [migrateError localizedDescription]); 
    } 
} 

// rest of setup 

return __persistentStoreCoordinator; 

Répondre

1

D'après ce que je peux dire, il semble que vous êtes à peu près là si la logique de migration vous avez posté fonctionne. Ce qu'il semble vous manquer est un else if pour gérer le cas où vous n'avez pas de magasin persistant. Ce qui suit devrait gérer ce cas.

if (__persistentStoreCoordinator != nil) { 
    return __persistentStoreCoordinator; 
} 

NSURL *newURL = [self newStoreURL]; // shared group container 
NSURL *oldURL = [self oldStoreURL]; // app's Documents directory 

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

NSFileManager *fileManager = [NSFileManager defaultManager]; 

if (![fileManager fileExistsAtPath:newURL.path] && [fileManager fileExistsAtPath:oldURL.path]) { 
    NSLog(@"performing migration..."); 
    NSPersistentStore *oldStore = [__persistentStoreCoordinator persistentStoreForURL:oldURL]; 
    NSError *migrateError = nil; 
    NSPersistentStore *newStore = [__persistentStoreCoordinator migratePersistentStore:oldStore toURL:newURL options:[self iCloudPersistentStoreOptions] withType:NSSQLiteStoreType error:&migrateError]; 
    if (!newStore) { 
     NSLog(@"Error migrating store: %@", [migrateError localizedDescription]); 
    } 
} else if (![fileManager fileExistsAtPath:newURL.path]) { 
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:newURL options:[self iCloudPersistentStoreOptions] error:&error]) { 
     NSLog(@"Error adding persistent store: %@", [error localizedDescription]); 
    } 
} 

// rest of setup 

return __persistentStoreCoordinator; 
+0

Le problème est que, avec les installations existantes (utilisateurs qui mettent à niveau et possèdent déjà des données), [NSFileManager fileExistsAtPath: oldURL.path] fausses déclarations pour une raison quelconque. – rick

+1

Le fichier de stockage réel dans mon cas se trouve réellement dans le répertoire Documents/CoreDataUbiquitySupport///local/store, ce qui explique pourquoi [NSFileManager fileExistsAtPath: oldURL.path] renvoie false – rick