我有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;
}
现在这段代码可以运行了,但我必须关闭应用程序并重新启动才能获取要加载的新核心数据。如何制作它,以便您不必关闭并重新打开应用程序以显示新数据,我已尝试在表格上使用重新加载数据,但它仍显示旧记录
我认为问题来自于在已经设置了persistentstore之后调用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);
答案 0 :(得分:3)
这是因为文件在Unix上(因此在iOS上)的工作方式。一旦文件打开,删除它(包括通过覆盖它)实际上不会删除文件,直到关闭它的所有打开文件句柄。因此,在关闭应用程序之前,您将继续访问同一文件,从而关闭文件句柄。在下一次运行中,您将获得新版本。
如果可能,处理此问题的简单方法是在覆盖存储文件之前不要创建持久性堆栈。但这可能并不容易或不可能。在这种情况下,您可以通过删除引用它的NSPersistentStore
来关闭现有的商店文件。这将意味着彻底拆除现有的持久性堆栈并重新开始。这意味着摆脱NSPersistentStoreCoordinator
,NSManagedObjectContext
和NSManagedObject
的每个实例。然后返回并再次构建堆栈,就像应用程序启动时一样。 (如果您为旧版本调用NSPersistentStoreCoordinator
然后添加新版本,则可以保留removePersistentStore:error:
,但这并不能简化该过程。
答案 1 :(得分:0)
尝试使用handleOpenURL方法将managedObjectContext,managedObjectModel和persistentStoreCoordinator设置为nil。这应该会强制应用程序在下次使用CoreData访问数据时重新加载db文件。