且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

iOS 11+如何将现有的核心数据迁移到共享应用程序组以用于扩展?

更新时间:2022-05-17 01:29:23

我最终得到它做以下。 sqlite文件实际上是我的init加上最后一个.sqlite的名称。

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;
}