我目前正在编写应用的下一个版本。
在旧版本中,没有CoreData sqlite
在新版本中,我们有一个本地CoreData sqlite数据库。
当我从头开始安装新版本的应用程序时,没有问题,商店就在那里,我可以查询。
但是,当我在具有上一版本的手机上安装应用程序时,我的查询会返回,但没有结果。
当我查看日志时,控制台中没有任何内容,并且不会返回任何错误。
#import "CoreDataHelper.h"
@implementation CoreDataHelper
@synthesize store = _store;
@synthesize coordinator = _coordinator;
#pragma mark -
#pragma mark - FILES
NSString *storeFileName = @"Reporting.sqlite";
#pragma mark -
#pragma mark - PATHS
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
- (NSURL *)applicationStoresDirectory {
NSURL *storesDirectory = [[NSURL fileURLWithPath:[self applicationDocumentsDirectory]]URLByAppendingPathComponent:@"Stores"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:[storesDirectory path]]) {
NSError *error = nil;
if ([fileManager createDirectoryAtURL:storesDirectory
withIntermediateDirectories:YES
attributes:nil
error:&error]) {
//File created
} else {
//Error
}
}
return storesDirectory;
}
- (NSURL *)storeURL {
return [[self applicationStoresDirectory] URLByAppendingPathComponent:storeFileName];
}
#pragma mark -
#pragma mark - SETUP
- (id)init {
if (self = [super init]) {
_model = [NSManagedObjectModel mergedModelFromBundles:nil];
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_context setPersistentStoreCoordinator:_coordinator];
}
return self;
}
- (void)loadStore {
if (_store) return; // Don't load store if it is already loaded
// to generate the database in the app launching comment next lines...
if(![self getFileExistence:storeFileName]){
// file URL in our bundle
NSURL *fileFromBundle = [[NSBundle mainBundle]URLForResource:@"FaultReporting" withExtension:@"sqlite"];
// Destination URL
NSURL *destinationURL = [[self applicationStoresDirectory] URLByAppendingPathComponent:@"FaultReporting.sqlite"];
// copy it over
[[NSFileManager defaultManager]copyItemAtURL:fileFromBundle toURL:destinationURL error:nil];
}
// end of comments
NSError *error = nil;
@try {
_store = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self storeURL]
options:@{ NSMigratePersistentStoresAutomaticallyOption: @(YES),
NSInferMappingModelAutomaticallyOption: @(YES)}
error:&error];
}
@catch (NSException *exception) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Error: %@, %@",error, [error userInfo]] delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alert show];
}
@finally {
//
}
}
答案 0 :(得分:2)
苏。不确定你是否这样做但是尝试以下方法:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError* error;
[managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.storeUrl
options:options // this is required to migrate some core data model attributes
error:&error];
在您进行设置时,基本上必须告诉它在选项中使用此迁移功能。
答案 1 :(得分:1)
我不确定这是否适用于您,但从iOS 7升级到iOS 8时我遇到了类似的情况。在iOS 8 NSManagedObject
中添加了deleted
的属性。我碰巧在托管对象模型上有一个名为deleted
的属性。我必须将已删除列的名称更改为与NSManagedObject
上的新已删除属性不冲突的内容。
答案 2 :(得分:1)
您能否确认已执行了所有这些步骤?
点击您的应用目标(在左侧窗格中显示带有应用名称的顶部图标),然后转到“构建阶段”标签,然后点击“链接二进制文件库”,点击“+”链接然后找到'CoreData.framework'并将其添加到您的项目
然后在所有需要它的对象上导入coredata:
#import <CoreData/CoreData.h>
或在.pch文件中的常用导入下添加导入:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#endif
要添加.xcdatamodel文件,请右键单击/按住Control键并单击右侧窗格中的文件(如在“资源”文件夹中保存),然后选择“添加新文件”,在选择文件类型时单击“核心数据”选项卡然后单击“数据模型”,为其命名并单击“下一步”和“完成”,它将把它添加到您的项目中。当您单击此Model对象时,您将看到使用您想要的任何关系将实体添加到项目的界面。
将这些对象添加到AppDelegate.h
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory; // nice to have to reference files for core data
在AppDelegate.m中合成以前的对象,如下所示:
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
然后将这些方法添加到AppDelegate.m(确保将您添加的模型的名称放在显示的位置):
- (void)saveContext{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
- (NSManagedObjectContext *)managedObjectContext{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAMEOFYOURMODELHERE" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"NAMEOFYOURMODELHERE.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
在ViewController.m
中@synthesize managedObjectContext = _managedObjectContext;
在AppDelegate或创建ViewController的类中,将managedObjectContext设置为与AppDelegate相同
ViewController.managedObjectContext = self.managedObjectContext;
如果您希望使用Core Data的viewcontroller成为FetchedResultsController,那么您需要确保这些内容在ViewController.h中
@interface ViewController : UIViewController <NSFetchedResultsControllerDelegate> {
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
这是在ViewController.m
中@synthesize fetchedResultsController, managedObjectContext;
参考: How to add Core Data to an existing project in Xcode
希望它能解决你的问题。