0

我有 2 个应用程序,一个免费,一个付费。我设置了这两个应用程序,以便人们可以使用以下代码将他们的数据从免费传输到付费

在免费的(在视图控制器中)

- (IBAction)exportToPro:(id)sender
{
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Medicine_Tracker.sqlite"];
    NSString *storeURLString = [storeURL path];

    if( [[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]] ) NSLog(@"Exists");

    NSData *fileData = [NSData dataWithContentsOfFile:storeURLString];
    NSString *encodedString = [GTMBase64 stringByWebSafeEncodingData:fileData padded:YES];
    NSString *urlString = [NSString stringWithFormat:@"mt://localhost/importDatabase?%@", encodedString];
    NSURL *openURL = [NSURL URLWithString:urlString];
    [[UIApplication sharedApplication] openURL:openURL];
}

并在付费中(在应用程序委托中)

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    if([@"/importDatabase" isEqual:[url path]]) {
        NSString *query = [url query];
        NSData *importUrlData = [GTMBase64 webSafeDecodeString:query];

        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Medicine_Tracker.sqlite"];
        NSString *storeURLString = [storeURL path];
        if( [[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]] ) NSLog(@"Exists");

        // NOTE: In practice you will want to prompt the user to confirm before you overwrite their files!
        [importUrlData writeToFile:storeURLString atomically:YES];
        return YES;
    }
    return NO;
}

现在这段代码有效,但我必须关闭应用程序并重新启动它才能加载新的核心数据。我如何做到这一点,这样您就不必关闭并重新打开应用程序来显示新数据,我尝试在表格上使用重新加载数据,但它仍然显示旧记录

我认为问题出在已经设置持久存储之后调用 handleOpenURL 方法的事实

openurl 方法中的新代码

__persistentStoreCoordinator = nil;
        __managedObjectContext = nil;
        __managedObjectModel = nil;

        NSLog(@"PSC: %@ - MOC: %@ - MOM: %@", __persistentStoreCoordinator, __managedObjectContext, __managedObjectModel);

        NSError *error = nil;
        __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

        if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        }

        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Medicine_Tracker" withExtension:@"momd"];
        __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            __managedObjectContext = [[NSManagedObjectContext alloc] init];
            [__managedObjectContext setPersistentStoreCoordinator:coordinator];
        }

        NSLog(@"PSC: %@", __persistentStoreCoordinator);
        NSLog(@"MOC: %@", __managedObjectContext);
        NSLog(@"MOM: %@", __managedObjectModel);
4

2 回答 2

3

这是因为文件在 Unix 上的工作方式(因此在 iOS 上)。打开文件后,删除它(包括通过覆盖它)实际上不会删除该文件,直到它的所有打开文件句柄都关闭。因此,您一直访问同一个文件,直到您关闭应用程序,这将关闭文件句柄。在下一次运行时,您将获得新版本。

如果可能,解决此问题的简单方法是在覆盖存储文件之前不创建持久性堆栈。不过,这可能并不容易或不可能。在这种情况下,您可以通过删除NSPersistentStore引用它的文件来关闭现有的商店文件。这将意味着完全拆除现有的持久性堆栈并重新开始。这意味着摆脱 , 和 的NSPersistentStoreCoordinator每个NSManagedObjectContext实例NSManagedObject。然后返回并再次构建堆栈,就像应用程序启动时一样。NSPersistentStoreCoordinator(如果您调用removePersistentStore:error:旧版本然后添加新版本,您可以保留它,但这并不能真正简化流程)。

于 2013-07-10T17:47:43.087 回答
0

尝试在您的 handleOpenURL 方法中将 managedObjectContext、managedObjectModel 和 persistentStoreCoordinator 设置为 nil。这应该会强制应用程序在下次使用 CoreData 访问数据时重新加载 db 文件。

于 2013-07-10T17:46:04.510 回答