iOS 11+ How to migrate existing Core Data to Shared App Group for use in extension?

前端 未结 3 600
北荒
北荒 2020-12-09 06:23

When I created an iOS 11 app using the core data template, it auto generated the following code in AppDelete.m.

synthesize persistentContainer = _persistentC         


        
3条回答
  •  半阙折子戏
    2020-12-09 06:49

    I ended up getting it doing the following. The sqlite file was actually the name of my init plus .sqlite at the end.

    + (NSPersistentContainer*) GetPersistentContainer {
        //Init the store.
        NSPersistentContainer *_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"Test_App"];
    
        //Define the store url that is located in the shared group.
        NSURL* storeURL = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.Test_App"] URLByAppendingPathComponent:@"Test_App.sqlite"];
    
        //Determine if we already have a store saved in the default app location.
        BOOL hasDefaultAppLocation = [[NSFileManager defaultManager] fileExistsAtPath: _persistentContainer.persistentStoreDescriptions[0].URL.path];
    
        //Check if the store needs migration.
        BOOL storeNeedsMigration = hasDefaultAppLocation && ![_persistentContainer.persistentStoreDescriptions[0].URL.absoluteString isEqualToString:storeURL.absoluteString];
    
        //Check if the store in the default location does not exist.
        if (!hasDefaultAppLocation) {
            //Create a description to use for the app group store.
            NSPersistentStoreDescription *description = [[NSPersistentStoreDescription alloc] init];
    
            //set the automatic properties for the store.
            description.shouldMigrateStoreAutomatically = true;
            description.shouldInferMappingModelAutomatically = true;
    
            //Set the url for the store.
            description.URL = storeURL;
    
            //Replace the coordinator store description with this description.
            _persistentContainer.persistentStoreDescriptions = [NSArray arrayWithObjects:description, nil];
        }
    
        //Load the store.
        [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
            //Check that we do not have an error.
            if (error == nil) {
                //Check if we need to migrate the store.
                if (storeNeedsMigration) {
                    //Create errors to track migration and deleting errors.
                    NSError *migrateError;
                    NSError *deleteError;
    
                    //Store the old location URL.
                    NSURL *oldStoreURL = storeDescription.URL;
    
                    //Get the store we want to migrate.
                    NSPersistentStore *store = [_persistentContainer.persistentStoreCoordinator persistentStoreForURL: oldStoreURL];
    
                    //Set the store options.
                    NSDictionary *storeOptions = @{ NSSQLitePragmasOption : @{ @"journal_mode" : @"WAL" } };
    
                    //Migrate the store.
                    NSPersistentStore *newStore = [_persistentContainer.persistentStoreCoordinator migratePersistentStore: store toURL:storeURL options:storeOptions withType:NSSQLiteStoreType error:&migrateError];
    
                    //Check that the store was migrated.
                    if (newStore && !migrateError) {
                        //Remove the old SQLLite database.
                        [[[NSFileCoordinator alloc] init] coordinateWritingItemAtURL: oldStoreURL options: NSFileCoordinatorWritingForDeleting error: &deleteError byAccessor: ^(NSURL *urlForModifying) {
                            //Create a remove error.
                            NSError *removeError;
    
                            //Delete the file.
                            [[NSFileManager defaultManager] removeItemAtURL: urlForModifying error: &removeError];
    
                            //If there was an error. Output it.
                            if (removeError) {
                                NSLog(@"%@", [removeError localizedDescription]);
                            }
                        }
                         ];
    
                        //If there was an error. Output it.
                        if (deleteError) {
                            NSLog(@"%@", [deleteError localizedDescription]);
                        }
                    }
                }
            } else {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
    
                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                NSLog(@"Unresolved error %@, %@", error, error.userInfo);
                abort();
            }
        }];
    
        //Return the container.
        return _persistentContainer;
    }
    

提交回复
热议问题