0
votes

In my app, I am using using CoreData to save data, and also I am pushing and pulling data from server. I also sync data across multiple devices, with same account.

But recently, I am getting this crash from crashLytics report.

This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation

So in my below function, I am calling "saveContext" method this way.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
    {
         AppDelegate *appDelegate = (AppDelegate *)[[UIApplication  sharedApplication]  delegate]; 

 //Creating a new instance of an managed object.
        Entity *cycle = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:appDelegate.managedObjectContext];

        [cycle setEmailID:m_emailId];
        [cycle setStartDate:dateFromServer];
        [cycle setEndDate:dateFromServer];   



       [appDelegate saveContext];
    }


//appDelegate.m

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil)
    {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"LoveCycles.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;
}

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

Create ManagedObject Context (MOC)

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil)
    {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
         _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }

    return _managedObjectContext;
}

So I have few doubts.

1) Should I call "[appDelegate saveContext]" everytime, the data is received from server, or it should be saved on only exit of the app.

2) CrashLytics report is pointing to "[appDelegate saveContext]". Also this is happening from iOS 9.

3) I am not able to replicate this issue on my device, running iOS 9. So not understanding, whether user is actually is seeing this crash, and what are the consequences of this error.

1
The error is telling you that the managedObjectContext has no persistent store associated with it. You might want to uncomment your error handling code because your call to persistentStoreCoordinator{} is probably failing. - Duncan Groenewald
Hey @DuncanGroenewald, is my code correct? - Ranjit
@DuncanGroenewald, I uncommented and tried. But no crash. - Ranjit
Use users device might have run out of space or something like that, you need to handle errors more gracefully than commenting out the abort and letting it run until something else goes wrong. Presumably you aren't seeing a lot of this crash in your logs? - Wain
@Wain I am seeing a lot of crash in my logs. Also they have less RAM only 141MB, but they have 18 GB space, this data is from crash logs. - Ranjit

1 Answers

0
votes

Somewhere you need to associate the ManagedObjectContext with the persistentStore, like this (Swift code):

lazy var managedObjectContext: NSManagedObjectContext? = {
        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
        let coordinator = self.persistentStoreCoordinator
        if coordinator == nil {
            FLOG(5, message: " Error getting managedObjectContext because persistentStoreCoordinator is nil")
            return nil
        }
        var managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator

        // Set the MergePolicy to prioritise external inputs
        let mergePolicy = NSMergePolicy(mergeType:NSMergePolicyType.MergeByPropertyStoreTrumpMergePolicyType )
        managedObjectContext.mergePolicy = mergePolicy

        return managedObjectContext
        }()