iOS Core Data not saving to persistent store

moonman239

macrumors 68000
Original poster
Mar 27, 2009
1,524
22
I have a problem. In one part of the app, I have code which is supposed to make changes to an NSManagedObject, then call the save method of a context. I thought this was enough to save the changes to the managed object, but I guess not.

The app seems to be saving the data to my iPad's RAM, but not to the SQLite store it's supposed to be saving the data to. Am I missing anything?

EDIT: I should add that I did not see any errors, and that I copied the Core Data code from a project that includes it.
 
Last edited:

moonman239

macrumors 68000
Original poster
Mar 27, 2009
1,524
22
Yes, you did not post any code.

Why do you never post any code?
Below is some code from my app. I have excluded RootViewController.h, RootViewController.m and MainViewController.h because they do not contain any relevant code. Everything I've decided to hide has been replaced with the word "hidden" or with "// Hidden code"
AppDelegate.h
Code:
//
//  AppDelegate.h
//
//  Created by Montana on 7/17/13.
//  Copyright (c) 2013 Montana. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property(readonly,strong,nonatomic)NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
AppDelegate.m:
Code:
#import "AppDelegate.h"
#import "RootViewController.h"
#import <SpeechKit/SpeechKit.h>

@implementation AppDelegate

const unsigned char SpeechKitApplicationKey[] = {0xa5, 0x50, 0x4e, 0xc5, 0x6a, 0x78, 0xd0, 0x52, 0x80, 0xd3, 0xdd, 0x68, 0xe3, 0xd7, 0x42, 0xc5, 0x99, 0x5c, 0x43, 0xa3, 0x59, 0xec, 0x86, 0x64, 0x57, 0xcd, 0x24, 0x2a, 0x90, 0xf6, 0xbf, 0x36, 0x47, 0x0d, 0xfb, 0xb1, 0x85, 0xcb, 0x03, 0x05, 0x9f, 0xe0, 0x6d, 0x82, 0xb7, 0xaf, 0x48, 0x51, 0x0c, 0x8b, 0xf4, 0x65, 0x77, 0x7a, 0xc9, 0xcf, 0x47, 0xed, 0xf9, 0xd8, 0xe3, 0xb8, 0x0e, 0x2a};

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    RootViewController *rootViewController = (RootViewController *)self.window.rootViewController;
    rootViewController.managedObjectContext = self.managedObjectContext;
    return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Saves changes in the application's managed object context before the application terminates.
    [self saveContext];
}

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&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.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

#pragma mark - Core Data stack

// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"core_data" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"core_data.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.
         
         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:
         @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
         
         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;
}

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

@end
RootViewController.m contains no significant code, so I will not post its code.

prepareForSegue method in MainViewController.m:
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    RootViewController *rootViewController = (RootViewController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];
    [[segue destinationViewController] hidden].managedObjectContext = [rootViewController managedObjectContext];
    
}
viewLoaded and touchesEnded methods in destination view controller's parent class's .m file:
Code:
- (void)viewLoaded
{
    // Hidden code
    [[self hidden] getManagedObject];
    managedObject = self.hidden.managedObject;
    if ([[managedObject valueForKey:@"individualhidden"] doubleValue] > 0)
    {
        thecount = [[managedObject valueForKey:@"individualhidden"] doubleValue] * [[self words] count];
    }
    [self hidden];
    
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        // Hidden code
            if (hidden <= 60)
            {
                NSString *hidden = [selectedLabel.text stringByAppendingString:self.lastLetters.text];
                if ([letterGroup isEqualToString:correctWord])
                {
                    selectedLabel.text = @"";
                    self.hidden.text = hidden;
                    thecount = thecount + 1;
                    NSInteger score = (thecount / [[self hidden] count]);
                    [managedObject setValue:[NSNumber numberWithInteger:score] forKey:@"hidden"];
                    NSError *error;
                    if ([[[self hidden] managedObjectContext] save:&error])
                    {
                        NSLog(@"%@",[error localizedDescription]);
                        abort();
                    }
                    [self hidden];
                }
            }
    selectedLabel = nil;
}
The managed object is stored as a property of a property of the destination view controller. It is generated using the following code. Each implementation is in its own .m file.

Code:
@implementation hidden
-(void)getManagedObject
{
    self.managedObject = [NSManagedObject managedObjectForhidden:[self name] context:[self managedObjectContext]];
}
@end

@implementation NSManagedObject (FamilyManagedObjectCategory)
+ (NSManagedObject *)managedObjectForhidden:(NSString *)wordFamily context:(NSManagedObjectContext *)context
{
    NSManagedObject *managedObject;
    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
    NSString *predicateFormat = [@[@"familyName LIKE '",hidden,@"'"] componentsJoinedByString:@""];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"hidden" inManagedObjectContext:context];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setEntity:entityDescription];
    NSError *error = [[NSError alloc] init];
    NSArray *managedObjectArray = [context executeFetchRequest:fetchRequest error:&error];
    if (managedObjectArray != nil)
    {
        if ([managedObjectArray count] == 0)
        {
        managedObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];
            [managedObject setValue:hidden forKey:@"familyName"];
            if (![context save:&error]) {
                NSLog(@"%@",[error localizedDescription]);
            }
            }
        else
        {
            managedObject = [managedObjectArray firstObject];
        }
        }
    else
    {
        NSLog(@"%@",[error localizedDescription]);
    }
    return managedObject;
}
@end
 

namanhams

macrumors regular
Jun 3, 2009
153
0
When you save CoreData, you call this :

Code:
NSError *error = nil;  // (1)
[yourManagedObjectContext save:&error];  // (2)
Make sure that 'yourManagedObjectContext' is not nil, and that (2) returns true. If not, definitely 'error' will contain the information about the issue.
 

crossi81

macrumors member
Aug 13, 2012
40
1
Try

Code:
managedObject = [NSEntityDescription insertNewObjectForEntityForName:@"hidden" inManagedObjectContext:context];
And build "context" this way:

NSManagedObjectContext *context = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
(remember to import AppDelegate.h)

instead of

managedObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
We can't help you troubleshoot code that isn't real code. As posted, your code makes no sense. The word "hidden" is used as a method name, instance variable name, property name, and I don't know what else, and those different uses conflict. In your touchesEnded method, you only update your managed object context if hidden <= 60. Then you replace hidden with a string.

You said you replaced various things with hidden, but as a result, you've hidden the code that we need to see.


Below is some code from my app. I have excluded RootViewController.h, RootViewController.m and MainViewController.h because they do not contain any relevant code. Everything I've decided to hide has been replaced with the word "hidden" or with "// Hidden code"
AppDelegate.h
Code:
//
//  AppDelegate.h
//
//  Created by Montana on 7/17/13.
//  Copyright (c) 2013 Montana. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property(readonly,strong,nonatomic)NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
AppDelegate.m:
Code:
#import "AppDelegate.h"
#import "RootViewController.h"
#import <SpeechKit/SpeechKit.h>

@implementation AppDelegate

const unsigned char SpeechKitApplicationKey[] = {0xa5, 0x50, 0x4e, 0xc5, 0x6a, 0x78, 0xd0, 0x52, 0x80, 0xd3, 0xdd, 0x68, 0xe3, 0xd7, 0x42, 0xc5, 0x99, 0x5c, 0x43, 0xa3, 0x59, 0xec, 0x86, 0x64, 0x57, 0xcd, 0x24, 0x2a, 0x90, 0xf6, 0xbf, 0x36, 0x47, 0x0d, 0xfb, 0xb1, 0x85, 0xcb, 0x03, 0x05, 0x9f, 0xe0, 0x6d, 0x82, 0xb7, 0xaf, 0x48, 0x51, 0x0c, 0x8b, 0xf4, 0x65, 0x77, 0x7a, 0xc9, 0xcf, 0x47, 0xed, 0xf9, 0xd8, 0xe3, 0xb8, 0x0e, 0x2a};

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    RootViewController *rootViewController = (RootViewController *)self.window.rootViewController;
    rootViewController.managedObjectContext = self.managedObjectContext;
    return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Saves changes in the application's managed object context before the application terminates.
    [self saveContext];
}

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&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.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

#pragma mark - Core Data stack

// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"core_data" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"core_data.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.
         
         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:
         @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
         
         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;
}

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

@end
RootViewController.m contains no significant code, so I will not post its code.

prepareForSegue method in MainViewController.m:
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    RootViewController *rootViewController = (RootViewController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];
    [[segue destinationViewController] hidden].managedObjectContext = [rootViewController managedObjectContext];
    
}
viewLoaded and touchesEnded methods in destination view controller's parent class's .m file:
Code:
- (void)viewLoaded
{
    // Hidden code
    [[self hidden] getManagedObject];
    managedObject = self.hidden.managedObject;
    if ([[managedObject valueForKey:@"individualhidden"] doubleValue] > 0)
    {
        thecount = [[managedObject valueForKey:@"individualhidden"] doubleValue] * [[self words] count];
    }
    [self hidden];
    
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        // Hidden code
            if (hidden <= 60)
            {
                NSString *hidden = [selectedLabel.text stringByAppendingString:self.lastLetters.text];
                if ([letterGroup isEqualToString:correctWord])
                {
                    selectedLabel.text = @"";
                    self.hidden.text = hidden;
                    thecount = thecount + 1;
                    NSInteger score = (thecount / [[self hidden] count]);
                    [managedObject setValue:[NSNumber numberWithInteger:score] forKey:@"hidden"];
                    NSError *error;
                    if ([[[self hidden] managedObjectContext] save:&error])
                    {
                        NSLog(@"%@",[error localizedDescription]);
                        abort();
                    }
                    [self hidden];
                }
            }
    selectedLabel = nil;
}
The managed object is stored as a property of a property of the destination view controller. It is generated using the following code. Each implementation is in its own .m file.

Code:
@implementation hidden
-(void)getManagedObject
{
    self.managedObject = [NSManagedObject managedObjectForhidden:[self name] context:[self managedObjectContext]];
}
@end

@implementation NSManagedObject (FamilyManagedObjectCategory)
+ (NSManagedObject *)managedObjectForhidden:(NSString *)wordFamily context:(NSManagedObjectContext *)context
{
    NSManagedObject *managedObject;
    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
    NSString *predicateFormat = [@[@"familyName LIKE '",hidden,@"'"] componentsJoinedByString:@""];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"hidden" inManagedObjectContext:context];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setPredicate:predicate];
    [fetchRequest setEntity:entityDescription];
    NSError *error = [[NSError alloc] init];
    NSArray *managedObjectArray = [context executeFetchRequest:fetchRequest error:&error];
    if (managedObjectArray != nil)
    {
        if ([managedObjectArray count] == 0)
        {
        managedObject = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];
            [managedObject setValue:hidden forKey:@"familyName"];
            if (![context save:&error]) {
                NSLog(@"%@",[error localizedDescription]);
            }
            }
        else
        {
            managedObject = [managedObjectArray firstObject];
        }
        }
    else
    {
        NSLog(@"%@",[error localizedDescription]);
    }
    return managedObject;
}
@end
 

dejo

Moderator
Staff member
Sep 2, 2004
15,981
450
The Centennial State
We can't help you troubleshoot code that isn't real code. As posted, your code makes no sense. The word "hidden" is used as a method name, instance variable name, property name, and I don't know what else, and those different uses conflict. In your touchesEnded method, you only update your managed object context if hidden <= 60. Then you replace hidden with a string.

You said you replaced various things with hidden, but as a result, you've hidden the code that we need to see.
I'm guessing they're trying to show their code without revealing it's true purpose and avoiding having someone steal that idea and produce their own app. In that case, I would suggest creating a test app to "demonstrate" to us the problem issue. If it doesn't recreate the issue, than perhaps the issue lies with other code.
 

moonman239

macrumors 68000
Original poster
Mar 27, 2009
1,524
22
I'm guessing they're trying to show their code without revealing it's true purpose and avoiding having someone steal that idea and produce their own app.
Exactly.

I would like to thank everyone for helping me out here. Programs are hard to debug when the code looks good.
 

moonman239

macrumors 68000
Original poster
Mar 27, 2009
1,524
22
News? Did my suggestion work?
The context is not nil, but my view controllers are referring to a nil context. This appears to be because mainViewController is referencing a nil property of one of my view controllers.

Update: I just edited mainViewController.m so that the view controller sets the aforementioned property to a new instance of that property's subclass.

Update #2: The program still will not save the data.
 
Last edited:

moonman239

macrumors 68000
Original poster
Mar 27, 2009
1,524
22
Update #3: It appears that the problem lies with a variable that's supposed to be updated every time the user increases his or her score.

Every time the user makes a correct choice, the value of an integer named "thecount" increases by 1. The app is supposed to store the current score, which equals the number of questions answered correctly divided by the number of questions that either have been or will be presented, in a double named "score".

Despite the fact that thecount's value increases, score's value stays the same.

EDIT: I decided that I was telling the app to perform integer division. Thanks to the people who answered this Java question.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.