I just started using Core Data with sql-lite so I’m a bit new. I based my code around various tutorials online and by creating an xcode core data application for reference. For what its worth, I’m integrating this into an existing cocos2d Application.
Everything was going okay, until I noticed that saving was not always working. Context save always returns true though, but sometimes I get back old data when I retrieve it. No errors are ever generated. I’ve debugged to make sure I’m passing it the right data to save, but I cant see what ‘Im doing wrong.
Here is part of my “SaveDataManager” which handles saving and retrieving data. It is an instance object of my app delegate.
The Save function.
- (bool) saveSongOptionData
{
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).managedObjectContext;
NSManagedObject *newData = [NSEntityDescription insertNewObjectForEntityForName:@"SongOptions" inManagedObjectContext:context];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"SongOptions" inManagedObjectContext:context];
//First check if row exists, if not create it. If so, update that row with our new high score information.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
//Only should be 1 record, grab it
[request setFetchLimit:1];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) //None!! Lets create one
{
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].background] forKey:@"background"];
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].random] forKey:@"random"];
[newData setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].vibrate] forKey:@"vibrate"];
}
else
{
matches = [objects objectAtIndex:0];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].background] forKey:@"background"];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].random] forKey:@"random"];
[matches setValue:[NSNumber numberWithBool:[GlobalVariables sharedInstance].vibrate] forKey:@"vibrate"];
}
[request release];
bool success = [context save:&error];
if (!success)
NSLog(@"%@", error.localizedDescription);
return success;
}
In my AppDelegate I create my “SaveDataManager” instance and pass it the context like so in the applicationDidFinishLaunching method:
self.dataManager = [[SavedDataManager alloc] init];
self.dataManager.managedObjectContext = self.managedObjectContext;
And for retrieving the context etc.
#pragma mark - Core Data stack
- (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:@"TestGame" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
return _persistentStoreCoordinator;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestGame.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;
}
I’m not sure if this is enough information, but I would be really grateful if someone could guide me in the right direction on why this might be happening.
Solved it. A simple mistake really. Im actually surprised it was working at all. If you notice in the code I posted I was using “_” variables. This was because I had synthesized the variables, i.e “managedObjectContext = _managedObjectContext” This overwrote my custom getters. Not sure if it will help someone but just make sure to read up on synthesizing as I avoided to do so for a long time 😛