2010-11-30 4 views
2

Я работал с Core Data в приложении iPad, и я могу успешно сохранять и извлекать данные внутри приложения. Однако, полностью закрывая приложение, полностью завершайте его, вынимайте его из многозадачности и эти данные исчезают.CoreData Сохранить навсегда?

Значит, Core Data в любом случае сохраняет эти данные в любом месте, когда приложение закрыто? Или мне нужно искать где-то еще?

EDIT: Это в деле делегата didFinishLaunchingWithOptions: [[[UIApplication sharedApplication] delegate] managedObjectContext];, а затем у меня есть: context_ = [(prototypeAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; в подклассе UIView.

Это код Premade NSPersistentStoreCoordinator в приложение делегата:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 

    if (persistentStoreCoordinator_ != nil) { 
     return persistentStoreCoordinator_; 
    } 

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"prototype.sqlite"]; 

    NSError *error = nil; 
    persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 
     /* 
     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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 

     Typical reasons for an error here include: 
     * The persistent store is not accessible; 
     * The schema for the persistent store is incompatible with current managed object model. 
     Check the error message to determine what the actual problem was. 


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. 

     If you encounter schema incompatibility errors during development, you can reduce their frequency by: 
     * Simply deleting the existing store: 
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] 

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. 

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

    return persistentStoreCoordinator_; 
} 

До сих пор я использую это для выборки данных:

NSFetchRequest *fetch = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *testEntity = [NSEntityDescription entityForName:@"DatedText" inManagedObjectContext:context_]; 
    [fetch setEntity:testEntity]; 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"dateSaved == %@", datePicker.date]; 
    [fetch setPredicate:pred]; 

    NSError *fetchError = nil; 
    NSArray *fetchedObjs = [context_ executeFetchRequest:fetch error:&fetchError]; 
    if (fetchError != nil) { 
     NSLog(@"fetchError = %@, details = %@",fetchError,fetchError.userInfo); 
    } 
    noteTextView.text = [[fetchedObjs objectAtIndex:0] valueForKey:@"savedText"]; 

И это, чтобы сохранить данные:

NSManagedObject *newDatedText; 
    newDatedText = [NSEntityDescription insertNewObjectForEntityForName:@"DatedText" inManagedObjectContext:context_]; 
    [newDatedText setValue:noteTextView.text forKey:@"savedText"]; 
    [newDatedText setValue:datePicker.date forKey:@"dateSaved"]; 

    NSError *saveError = nil; 
    [context_ save:&saveError]; 
    if (saveError != nil) { 
     NSLog(@"[%@ saveContext] Error saving context: Error = %@, details = %@",[self class], saveError,saveError.userInfo); 
    } 
+0

Как вы настройке managedObjectContext? Чтобы данные были сохранены после выхода, вам необходимо настроить NSPersistentStoreCoordinator. – DerekH 2010-11-30 22:01:49

+0

Обновленный вопрос с более подробной информацией. – 2010-11-30 22:25:03

+1

Ваш код сохранения окончательно неверен. Вы абсолютно * не должны * смотреть на значение `saveError`, если вызов` -save: `не возвращает NO. Это ошибка программирования и может привести к краху вашего приложения. `-save:` не гарантирует, что эта переменная имеет допустимое значение, за исключением случаев, когда она возвращает NO. Поэтому вы должны использовать `if (! [Context_ save: & saveError]) {/ * читать saveError * /}`. – 2010-12-01 21:36:29

ответ

0

Я обнаружил проблему. Оказывается, что из-за его использование UIDatePicker, в начале программы он установил, что выбор даты на сегодняшний день с помощью:

NSDate *now = [[NSDate alloc] init]; 
[datePicker setDate:now]; 

Так что без использования этого она прекрасно работает. Поэтому в настоящее время я ищу решение этой проблемы, поскольку эта строка, похоже, вызывает проблему.

UIDatePicker Interfering with CoreData

0

Вы должны опубликовать код, который устанавливает ваш NSPsistentStoreCoordinator и добавляет ваш NSPersistentStore. Вы случайно используете NSInMemoryStoreType как тип своего магазина? Потому что это приведет к поведению, которое вы видите. Кроме того, каждый раз вы можете использовать другой путь к хранилищу, который будет давать вам новый магазин каждый раз. Как правило, ваш магазин должен находиться в папке «Документы», и при каждом запуске ему должно быть присвоено одинаковое имя. Также следует использовать NSSQLiteStoreType

2

Вы экономите контекст в нужных местах? Это распространенная ошибка не сохранять контекст при вводе состояния фонового приложения только в willTerminate.

Сохранить контекст в следующем AppDelegate методе:

-(void)applicationDidEnterBackground:(UIApplication *)application 

Вы экономите контекст непосредственно после вставки объекта, этого должно быть достаточно. Проверьте файл sqlite в симуляторе, если он содержит данные после сохранения.

если

noteTextView.text = [[fetchedObjs objectAtIndex:0] valueForKey:@"savedText"]; 

не бросает исключение, есть объект находится в контексте. Может быть, он не содержит ожидаемого значения? Зарегистрируйте возвращаемый объект с вашего fetchrequest на консоль, чтобы узнать, может ли это быть так.

0

Если добавить CoreData после создания вашего project.There риск сделать ошибку в lazy_init вашей NSManagedObject.

-(NSManagedObjectContext*) managedObjectContext{ 
if (!_managedObjectContext) { 
    _managedObjectContext =[self createManageObjectContextWithName:@"name.sqlite"]; 
} 
return _managedObjectContext;} 

Вот это правильный путь:

- (NSManagedObjectContext *)managedObjectContext { 
if (_managedObjectContext != nil) { 
    return _managedObjectContext; 
} 

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