Jaysquared
Apps for iPhone, iPad and Mobile Web Apps
  • email
  • facebook
  • twitter
  • linkedin
  • apple
  • Home
  • Apps
    • Guess a Spot
    • Where is what?
    • Geoshot
    • CNSR
  • Blog
  • Contact
Select Page ...

Blog

Improved persistentStoreCoordinator for Release

April 30, 2012 Objective C Snippets No Comments

The problem with my situation at the moment, not devoting full time for app development is lack of time to learn, test and calm down. As I am working 50+ hours in an Investment Bank I might have failed to coin in my success with Find the Location. But that will change in 1 month :).

I included a nasty bug, which was caused by reliance to Apple provided standard methods and lack of cleaning derived data before archiving for the App Store. I use Core Data Model Versioning and somehow Migration didn’t work, so the around 1,000,000 users couldn’t use the app, when they updated. As I included ads for monetization I now had either users which couldn’t start the app or users which used the old version without ads.

I now cleaned up my persistentStoreCoordinator to support migration and have a fall back if that should fail for any reason. For reference this is the original method provided by Apple’s template in XCode.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
  if (__persistentStoreCoordinator != nil) {
    return __persistentStoreCoordinator;
  }
  NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"fbexclusive.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;
}

Even when using model versioning, it leads to this error, when you make changes to the model:

The model used to open the store is incompatible with the one used to create the store

So first thing is to include lightweight migration by providing the respective options NSDictionary:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

I included that as soon as I turned on Model Versioning and it worked just fine in development, but somehow created a bug in the Release version, so I included a fallback, checking for errors:

      [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
      [__persistentStoreCoordinator release];
      __persistentStoreCoordinator = nil;
      return [self persistentStoreCoordinator];

This is the complete version of my method I am using now.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
  if (__persistentStoreCoordinator != nil) {
    return __persistentStoreCoordinator;
  }
  NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"jaysquared.sqlite"];
  NSError *error = nil;
  __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];</code>

  NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
  [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
  [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

  if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&amp;error]){

      [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
      [__persistentStoreCoordinator release];
      __persistentStoreCoordinator = nil;
      return [self persistentStoreCoordinator];
  }

  return __persistentStoreCoordinator;
}

I hope this is of any use for you and could save you some headaches. If you have further improvements I am more than happy to include them in the post.

← Find the Location game translated to Japanese
Checklist: What to do before posting to the App Store? →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Contact us

    Contact us for your custom app development project. We speak English and German.
    • Frankfurt am Main, Germany
    • info@jaysquared.com
    • +49 180 3002 2102 600
  • Newsletter

    Subscribe to our monthly Newsletter and stay informed about our latest apps.

  • Recent Posts

    • iOS Screen Resolutions Cheat Sheet
    • Vungle Video Ads
    • Facebook should build on micropayments
    • Checklist: What to do before posting to the App Store?
    • Improved persistentStoreCoordinator for Release
    • Contact us

      Contact us for your custom iPhone, iPad or mobile web app development project.
      • Frankfurt am Main, Germany
      • info@jaysquared.com
      • +49 180 3002 2102 600
    • What we do

      We develop mobile apps for iPhone, iPod Touch and iPad as well as mobile web apps with a focus on casual games and utility apps. Our apps are developed in house together with a network of freelancers from around the world. China, India, Macedonia, Russia, Philippines to name just a few. This way we can provide you with the best service for a reasonable price. Check out our portfolio and decide if we are the right service provider for you.

    • Home
    • Apps
    • Blog
    • Contact
    Copyright © 2013 Jaysquared. All Rights Reserved