Note that there are some explanatory texts on larger screens.

plurals
  1. PONSManagedObjectContext Not saving properly to SQLite
    primarykey
    data
    text
    <p>SO,</p> <p>I have a problem with Core Data and trying to save data out to a SQLite database correctly.</p> <p>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).</p> <p>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. <strong>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.</strong> It does, however, have all of the proper tables - just like the SQLite file before I load the data.</p> <p>The odd thing is that if <strong>I open the SQLite DB file in a reader (Base.App) and VACUUM the database, it loads in Display.App perfectly fine</strong>. 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?</p> <p>Basically...</p> <p><strong>Method 1:</strong></p> <ol> <li>Run Loader.App</li> <li>Copy MyAppDB.sqlite to Display.App</li> <li>Run Display.App</li> </ol> <p><strong>Result</strong>: MyAppDB.sqlite has no data inside of it</p> <p><strong>Method 2:</strong></p> <ol> <li>Run Loader.App</li> <li>Open MyAppDB.sqlite with reader (Base.App)</li> <li>VACUUM</li> <li>Copy MyAppDB.sqlite to Display.App</li> <li>Run Display.App</li> </ol> <p><strong>Result</strong>: MyAppDB.sqlite contains data and we have much joy.</p> <p><strong>Here is a trimmed down version of my Loader.App:</strong></p> <pre><code> 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:&amp;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:&amp;error]; //NSError *error; NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE configuration:nil URL:url options:nil error:&amp;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:&amp;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:&amp;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:&amp;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); } } </code></pre> <p>Thanks for your help! :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload