SO,
I have a problem with Core Data and trying to save data out to a SQLite database correctly.
I have two "Apps": one for loading the SQLite data (Lets call that "Loader.App"), and one for displaying the data ("Display.App"). The loader is just a convenience "bridge" between a web-based CMS which exports data as JSON data and the App which needs an SQLite DB (which is, again, loaded by Core Data).
When I save the context in Loader.App, it saves the data into the SQLite file. I can open this file in a SQLite reader (like Base.App) and it shows all the data. The problem is: when I bring that SQLite file to Display.App, it copies the file into the documents directory but it doesn't have any data inside of it. It does, however, have all of the proper tables - just like the SQLite file before I load the data.
The odd thing is that if I open the SQLite DB file in a reader (Base.App) and VACUUM the database, it loads in Display.App perfectly fine. From experience with file io in Python I know that if you don't close the file properly, the data isn't written to the file from the io buffer. Clearly, the data is being written to the SQLite file (thus I can open it with a reader (Base.App)). But it makes me wonder if there a file closing method that I am not calling?
Basically...
Method 1:
Run Loader.App
Copy MyAppDB.sqlite to Display.App
Run Display.App
Result: MyAppDB.sqlite has no data inside of it
Method 2:
Run Loader.App
Open MyAppDB.sqlite with reader (Base.App)
VACUUM
Copy MyAppDB.sqlite to Display.App
Run Display.App
Result: MyAppDB.sqlite contains data and we have much joy.
Here is a trimmed down version of my Loader.App:
int main(int argc, const char * argv[])
{
#autoreleasepool {
// Create the managed object context
NSManagedObjectContext *context = managedObjectContext();
// Custom code here...
importDataEntriesFromJSON(context);
// Save the managed object context
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Error while saving %#", ([error localizedDescription] != nil) ? [error localizedDescription] : #"Unknown Error");
exit(1);
}
}
return 0;
}
static NSManagedObjectModel *managedObjectModel() {
static NSManagedObjectModel *model = nil;
if (model != nil) {
return model;
}
NSString *path = #"MyAppDB";
path = [path stringByDeletingPathExtension];
NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:#"mom"]];
model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return model;
}
static NSManagedObjectContext *managedObjectContext() {
static NSManagedObjectContext *context = nil;
if (context != nil) {
return context;
}
#autoreleasepool {
context = [[NSManagedObjectContext alloc] init];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel()];
[context setPersistentStoreCoordinator:coordinator];
NSString *STORE_TYPE = NSSQLiteStoreType;
NSString *path = #"MyAppDB";
path = [path stringByDeletingPathExtension];
NSURL *url = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:#"sqlite"]];
// Clear old SQLite
NSFileManager *manager = [NSFileManager defaultManager];
NSError *error;
[manager removeItemAtURL:url error:&error];
//NSError *error;
NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE configuration:nil URL:url options:nil error:&error];
if (newStore == nil) {
NSLog(#"Store Configuration Failure %#", ([error localizedDescription] != nil) ? [error localizedDescription] : #"Unknown Error");
}
}
return context;
}
void importDataEntriesFromJSON( NSManagedObjectContext *context ) {
NSError* err = nil;
NSString* dataPath = [[NSBundle mainBundle] pathForResource:#"data_entries" ofType:#"json"];
NSArray* data_entries = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath]
options:kNilOptions
error:&err];
NSLog(#"Imported %lu data_entries from JSON", (unsigned long)[data_entries count]);
[data_entries enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
DBDataEntry *dataEntry = [NSEntityDescription
insertNewObjectForEntityForName:#"DBDataEntry"
inManagedObjectContext:context];
dataEntry.data_entry_id = [NSNumber numberWithInt:[[obj objectForKey:#"data_entry_id"] integerValue]];
dataEntry.data_entry_keywords = [obj objectForKey:#"data_entry_keywords"];
dataEntry.data_entry_name = [obj objectForKey:#"data_entry_name"];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
}];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"DBDataEntry"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for( DBDataEntry *dataEntry in fetchedObjects ) {
//NSLog(#"data_entry_id: %#", dataEntry.data_entry_id);
//NSLog(#"data_entry_keywords: %#", dataEntry.data_entry_keywords);
//NSLog(#"data_entry_name: %#", dataEntry.data_entry_name);
NSLog(#"data_entry_id: %# name: %#", dataEntry.data_entry_id, dataEntry.data_entry_name);
}
}
Thanks for your help! :)
The most likely reason is that you're copying the SQLite file itself but not its journal files. On iOS 7 Core Data normally uses SQLite in WAL (write-ahead logging) mode. That means that besides MyAppDB.sqlite there will be files named MyAppDB.sqlite-wal and MyAppDB.sqlite-shm. Those files are crucial. If you copy just the SQLite file but not the journals, you'll lose data (as you've seen).
When you open the SQLite file in Base.app and vacuum, all the changes in the journal files are rolled into the main SQLite file itself. You're doing an extra step that eliminates the need to copy the journal files.
You have a couple of different options:
The easy way is to just copy all of the files. Problem solved.
Another option is to change the journal mode in your loader app to avoid the need to copy more files. You'd do this by passing an extra option when adding the persistent store:
NSDictionary *options = #{ NSSQLitePragmasOption : #{ #"journal_mode": #"DELETE" } };
Use that when calling addPersistentStoreWithType:configuration:URL:options:error:.
Related
in a XCTest class I get the managed object context like this:
//setup Core Data Stack
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"FabApp" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSError *error = nil;
XCTAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error] ? YES : NO, #"Should be able to add in-memory store");
self.moc = [[NSManagedObjectContext alloc] init];
self.moc.persistentStoreCoordinator = psc;
the ManagedObejctContex is created successfully but when I try to fetch some entities it does not find any. I am 100% sure that this entities exist in Core Data as I use them in the app
- (void) testAllInputIsSavedInCoreData{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Employ"
inManagedObjectContext:_moc];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *results = [_moc executeFetchRequest:fetchRequest error:&error];
XCTAssertEqual([[_lines objectAtIndex:0] count], [results count],#"Missmatch in saved data read %lu but saved %lu",(unsigned long)[[_lines objectAtIndex:0] count], (unsigned long)[results count]);
}
how is that possible, am I missing something?
You are using an in-memory persistent store (NSInMemoryStoreType) instead of SQLite (or XML). Everything "stored" in the in-memory store is not written to a sqlite database, it only exists until the context is deallocated which happens every time you setup your stack.
When writing Unit Tests, you typically want this behavior because you don't want to store extra objects in Core Data every time you run your tests.
Check that the test modelURL is the same as the app modelURL
Check that the test MOM is not nil
addPersistentStoreWithType::::: returns the store or nil (not a BOOL)
You are using an in-memory store PSC (which is not persisted)
In your test, are you adding entities to the in-memory store first?
[[_lines objectAtIndex:0] count] doesn't look right and it's not referenced previously in your testAllInputIsSavedInCoreData method.
I am building a Core Data IOS application and for testing purposes, I have created a PLIST file containing demo data. My Core Data model contains multiple entities with of course multiple relationships.
Like I said, I was able to create the PLIST and have the data loaded automatically on first launch but I was able to "pre-build" the relationships.
My question is: Can this be done and if so how?
I just can't see how I can set the value of a key to another object...
Any help would be greatly appreciated.
In the meantime, I will thinker with attempting to re-create those relationships using "dummy indexes", if I can manage to make this work.
Well, the "Dummy Index" way worked after a fashion
Knowing what the location (index) of each object in my array of dictionaries, I was able to set the desired relationships after loading my entities with the appropriate data.
BTW, for someone attempting to accomplish the same thing, here is the procedure I took:
Create a new PLIST file in XCode (File -> New -> File -> IOS Resource -> Property List)
Populate the PLIST:
Under Root, added an ARRAY item for each Entity in my Data Model.
Within each ARRAY, added a DICTIONARY item for each Entity Object.
Within each DICTIONARY, added item reflecting Attributes NAMES, TYPES and VALUES.
Added a the following lines under the ViewDidLoad method of my first TableViewController:
if ([[self.fetchedResultsController fetchedObjects] count] < 1)
{
[Utilities loadDefaultDataInManagedObjectContext:self.managedObjectContext];
}
My "loadDefaultDataInManagedObjectContext:(NSManagedObjectContext *)context" method:
+ (void)loadDefaultDataInManagedObjectContext:(NSManagedObjectContext *)context
{
NSError *errorDesc = nil;
NSPropertyListFormat format;
NSString *plistPath;
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
plistPath = [rootPath stringByAppendingPathComponent:#"DefaultData.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:#"DefaultData" ofType:#"plist"];
}
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSDictionary *entities = (NSDictionary *)[NSPropertyListSerialization propertyListWithData:plistXML options:NSPropertyListMutableContainers format:&format error:&errorDesc];
if (!entities)
{
NSLog(#"Error reading plist: %#, format: %lu", errorDesc, format);
}
else
{
// ENTITY 1 data
NSArray *entityNames = [entities valueForKey:#"EntityName"];
for (NSDictionary *entityName in entityNames)
{
EntityName *newEntity = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:context];
newEntity.attributeName1 = [entityName valueForKey:#"attributeName1"];
newEntity.attributeName2 = [entityName valueForKey:#"attributeName2"];
}
// ENTITY 2 data
//...
// ENTITY 3 data
//...
NSError *error = nil;
if (![context 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. 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.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
NSLog(#"Loaded Default Data");
[Utilities setRelationshipsInManagedObjectContext:context];
}
My "setRelationshipsInManagedObjectContext:(NSManagedObjectContext *)context" method:
+ (void)setRelationshipsInManagedObjectContext:(NSManagedObjectContext *)context
{
NSError *error;
// Initialize all neccessary fetch requests
NSFetchRequest *entityName1Request = [[NSFetchRequest alloc] initWithEntityName:#"entityName1"];
entityName1Request.predicate = nil;
NSFetchRequest *entityName2Request = [[NSFetchRequest alloc] initWithEntityName:#"entityName2"];
entityName2Request.predicate = nil;
NSFetchRequest *entityName3Request = [[NSFetchRequest alloc] initWithEntityName:#"entityName3"];
entityName3Request.predicate = nil;
//...
NSArray *entities1 = [context executeFetchRequest:entityName1Request error:&error];
NSArray *entities2 = [context executeFetchRequest:entityName2Request error:&error];
NSArray *entities3 = [context executeFetchRequest:entityName3Request error:&error];
//...
// Declaring my Objects
Entity1 *entity1;
Entity1 *entity2;
Entity1 *entity2;
// ...
if (entities1)
{
for (entity1 in entities1)
{
// set the required relationship according to your data and schema
if ([entity1.attributeName1 isEqualToString:#"Whatever"])
{
entity2 = (Entity2 *)[entities2 objectAtIndex:0];
entity1.relatedAttribute = entity2;
}
else if ([entity1.attributeName1 isEqualToString:#"SomethingElse"])
{
entity3 = (Entity3 *)[Entities3 objectAtIndex:2];
[entity1 addEntity3Object:entity3]; // for to many relationships
}
else // ...
{
}
}
}
// repeat the same process for your other entities that contain relationship
if (![context 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. 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.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
NSLog(#"Set relationships");
}
Still would like someone to confirm or deny the possibility of doing all this from within the PLIST.
TIA,
Michel
I'll try to expose my problem, because is a bit complex.
I use Core Data and I have a problem with the data stored.
When I use this code:
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"ItemMessage"];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
NSMutableArray *values = [[NSMutableArray alloc] init];
if (error == nil) {
for (int i = 0; i<results.count; i++) {
NSLog(#"results %#",[results objectAtIndex:i]);
ItemMessage *itemMessage = [results objectAtIndex:i];
[values addObject:itemMessage];
}
ecc. the problem is that the value printed by NSLog is correct (the "results" contains something) but the itemMessage contains always 0 key/value pairs (it seems empty).
To understand what is the problem I went back and saw that in insertNewObjectForEntityForName I have also this problem, this is the code that I used when I save the messages data in Core Data:
for (id key in objectMessage) {
ItemMessage *itemmessage = [[ItemMessage alloc] init];
itemmessage.itemMessageId = [key objectForKey:#"itemMessageId"];
itemmessage.message = [key objectForKey:#"message"];
itemmessage.sender = [key objectForKey:#"sender"];
itemmessage.users = [key objectForKey:#"users"];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *newMessage;
newMessage = [NSEntityDescription insertNewObjectForEntityForName:#"ItemMessage" inManagedObjectContext:context];
[newMessage setValue: itemmessage.itemMessageId forKey:#"itemMessageId"];
[newMessage setValue: itemmessage.message forKey:#"message"];
[newMessage setValue: itemmessage.sender forKey:#"sender"];
[newMessage setValue: itemmessage.users forKey:#"users"];
[context save:&error];
if (error != nil) {
NSLog(#"Coredata error");
}
The problem is that newMessage after the insertNewObjectForEntityForName and the setValue contains also 0 key/value pairs.
Can you help me?
You don't seem to insert the new managed objects correctly into the context.
It should be:
for (id key in objectMessage) {
NSManagedObjectContext *context = [appDelegate managedObjectContext];
ItemMessage *itemmessage = (ItemMessage*)[NSEntityDescription insertNewObjectForEntityForName:#"ItemMessage"
inManagedObjectContext:context];
itemmessage.itemMessageId = [key objectForKey:#"itemMessageId"];
itemmessage.message = [key objectForKey:#"message"];
itemmessage.sender = [key objectForKey:#"sender"];
itemmessage.users = [key objectForKey:#"users"];
}
//save your inserts
To create a class file for your managed objects you could:
Go to your model file (xcdatamodeld) ->
select an entity ->
from the menu select:
Editor-> Create NSManagedObjectSubclass -> select the entities your like class files for.
Now you will have managed objects you could access with ease (NSManagedObject subclass) and benefit from CoreData features.
When you insert to manage object contest you have to call save: method, also the saving method should looks something like that:
newMessage = [NSEntityDescription insertNewObjectForEntityForName:#"ItemMessage" inManagedObjectContext:context];
// 2
newMessage.property1 = self.firstNameTextfield.text;
newMessage.property2 = self.lastNameTextfield.text;
if (![context save:&error]) {
NSLog(#"Error: %#", [error localizedDescription]);
}
I have a JSON request which returns different parameters, name for example. I would like to cache a variable for the name parameter, which I can view in the app later.
For example: name from JSON request = david. the variable is called firstname. firstname should equal "david". firstname should be stored so I can view it in all parts of my apps.
For something simple as a string, the quick and dirty solution is to store it in NSUserDefaults.
Storing
[[NSUserDefaults standardDefaults] setObject:firstname forKey:#"kUserFirstName"];
[[NSUserDefaults standardDefaults] synchronize];
Retrieving
NSString *string = [[NSUserDefaults standardDefaults] objectforKey:#"kUserFirstName"];
If it gets more complicated than that, you have to consider a more structured persistence store. A valid option is CoreData.
There exist a few frameworks that might help you in storing JSON resources in CoreData, the most interesting being RestKit.
First off, you might consider checking out RestKit as it successfully accomplishes a whole slew of server interaction and CoreData persistence in iOS.
I'm a little short on time (on a lunch break here) so I'll just lazily post an example from an app I have.
- (void)loadFiltersFromJSON {
NSString *path = [[NSBundle mainBundle] pathForResource:#"FreeFilterBank" ofType:#"json"];
NSData *filterData = [NSData dataWithContentsOfFile:path];
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:filterData options:kNilOptions error:&err];
if (err) { //TODO this can be removed prior to shipping the app
NSLog(#"%#", err);
}
NSArray *definedFilters = [json objectForKey:#"Filter"];
NSManagedObjectContext* moc = [self managedObjectContext];
for (NSDictionary *filter in definedFilters) {
NSString *name = [filter valueForKey:#"name"];
BOOL exists = [self alreadyExists:name inManagedObjectContext:moc];
if (!exists) {
NSString *imageNamed = [filter valueForKey:#"imageName"];
NSString *filterDesignator = [filter valueForKey:#"filterDesignator"];
NSString *paid = [filter valueForKey:#"paidOrFree"];
[self createFilterWithName:name imageNamed:imageNamed filterDesignator:filterDesignator paidOrFree:paid];
}
}
}
- (BOOL)alreadyExists:(NSString*)filterNamed inManagedObjectContext:(NSManagedObjectContext*)moc {
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"name == %#", filterNamed];
NSEntityDescription* description = [NSEntityDescription entityForName:#"Filter" inManagedObjectContext:moc];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:description];
[request setPredicate:predicate];
NSError* error;
NSArray* fetchedResult = [moc executeFetchRequest:request error:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
}
if (fetchedResult.count == 0) {
return NO;
}
else {
return YES;
}
}
- (void)createFilterWithName:(NSString*)name imageNamed:(NSString*)imageName filterDesignator:(NSString*)designator paidOrFree:(NSString *)paid {
NSManagedObjectContext* moc = [self managedObjectContext];
Filter* newFilter = [NSEntityDescription insertNewObjectForEntityForName:#"Filter" inManagedObjectContext:moc];
newFilter.name = name;
newFilter.imageName = imageName;
newFilter.filterDesignator = designator;
newFilter.paidOrFree = paid;
NSError* error;
[moc save:&error];
if (error) {
NSLog(#"%#",error.localizedDescription);
}
}
TL;DR This loads data from a JSON stored in the bundle, checks the SQLite data store to see if we already have something with the same name, and creates a new persistent instance of this object if we don't.
Take this example for what you will, there are many many more invocations for serialized data pulled from the web and persistent data within iOS beyond this one example.
The easiest way is to use NSUserDefaults and set the key to #"firstname" and the value would be #"david". That being said, you might consider using a better persistence model like CoreData. You can also use an Sqlite database or have the key/value saved in a plist. There are a number of ways to do this.
For reference ,see this:
Save string to the NSUserDefaults?
I have a controller that is the root of a workflow. If there is no data object for the workflow, then I create a new one, and if there is, I use the existing one. I have a property for the model object (an NSManagedObject)
#property (nonatomic, retain) Round *currentRound;
and I call the following whenever the corresponding view is shown
self.currentRound = [self.service findActiveRound];
if (!self.currentRound) {
NSLog((#"configure for new round"));
self.currentRound = [self.service createNewRound];
...
} else {
NSLog(#"configure for continue");
// bad data here
}
The problem is at the place marked in the above, sometimes the data object is corrupted. In the parts I didn't show I set the values on some text fields to represent the values in the model. Sometimes its ok, but eventually the properties on the model object are empty and things break
In the debugger, the reference to the round doesn't appear to change, but NSLogging the relevant properties shows them nullified. debugging seems to delay the onset of the corruption.
I am aware I am not saving the context...should that matter? And if so, how come it doesn't always fail the first time I come back to this controller?
My findActiveRound message is nothing special, but in case it matters
-(Round *) findActiveRound
{
NSLog(#"Create Active Round");
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Round" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"isComplete == %#", [NSNumber numberWithBool:NO]];
[request setPredicate:pred];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if ([results count] == 0) {
return nil;
} else {
return [results objectAtIndex:0];
}
}
Many thanx.
EDIT FOR RESPONSE
By corrupted I mean when I try to get some simple string properties off the model object, I get nil values. So In the code above (where I think I have a round) I do stuff like
self.roundName.text = self.currentRound.venue;
self.teeSelection.text = self.currentRound.tees;
and don't see the data I entered. Since it only fails sometimes, but always fails eventually, I will see the data I entered for a while before its gone.
I'm pretty sure the context is the same. My service is a singleton and created like so
#implementation HscService
+(id) getInstance
{
static HscService *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[self alloc] init];
});
return singleton;
}
-(id) init
{
if (self = [super init]) {
model = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSString *path = [self itemArchivePath];
NSURL *storeUrl = [NSURL fileURLWithPath:path];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption, nil];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
[NSException raise:#"Open failed" format: #"Reason: %#", [error localizedDescription]];
}
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:psc];
[context setUndoManager:nil];
}
return self;
}
-(NSString *) itemArchivePath
{
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dir = [docDirectories objectAtIndex:0];
return [dir stringByAppendingPathComponent:#"hsc1.data"];
}
and in every controller I get the singleton to perform operations. I plan on defining a delegate around round operations, and implementing it in my AppDelegate, so I'm only getting the service once in the app, but don't think that should matter for now....
Are you sure the data is actually corrupted? Managed object contexts are highly efficient, and it's normal to fault in the debugger. From the docs:
"Faulting is a mechanism Core Data employs to reduce your
application’s memory usage..."
See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html
If the data is actually missing and cannot be accessed by other methods, make sure you're using the same Managed Object Context to access the data. If the data has not been committed to the data store, it will not "sync" between MOCs.