Handle store opening errors more gracefully.
Store opening can fail for example when hard-locking the device while it's opening up.
This commit is contained in:
		@@ -30,6 +30,7 @@
 | 
				
			|||||||
- (id)managedObjectContextChanged:(void ( ^ )(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects))changedBlock;
 | 
					- (id)managedObjectContextChanged:(void ( ^ )(NSDictionary<NSManagedObjectID *, NSString *> *affectedObjects))changedBlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
 | 
					- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
 | 
				
			||||||
 | 
					- (void)retryCorruptStore;
 | 
				
			||||||
- (void)deleteAndResetStore;
 | 
					- (void)deleteAndResetStore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @param completion The block to execute after adding the site, executed from the main thread with the new site in the main MOC. */
 | 
					/** @param completion The block to execute after adding the site, executed from the main thread with the new site in the main MOC. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -232,22 +232,27 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
 | 
				
			|||||||
                }];
 | 
					                }];
 | 
				
			||||||
            } );
 | 
					            } );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Create a new store coordinator.
 | 
					        // Create a new store coordinator.
 | 
				
			||||||
        NSError *error = nil;
 | 
					        NSError *error = nil;
 | 
				
			||||||
        NSURL *localStoreURL = [self localStoreURL];
 | 
					        NSURL *localStoreURL = [self localStoreURL];
 | 
				
			||||||
        if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
 | 
					        if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
 | 
				
			||||||
                                      withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
					                                      withIntermediateDirectories:YES attributes:nil error:&error]) {
 | 
				
			||||||
            MPError( error, @"Couldn't create our application support directory." );
 | 
					            MPError( error, @"Couldn't create our application support directory." );
 | 
				
			||||||
 | 
					            PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
 | 
				
			||||||
 | 
					            self.mainManagedObjectContext = nil;
 | 
				
			||||||
 | 
					            self.privateManagedObjectContext = nil;
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
 | 
					        if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:localStoreURL
 | 
				
			||||||
                                                       options:@{
 | 
					                                                       options:@{
 | 
				
			||||||
                                                               NSMigratePersistentStoresAutomaticallyOption: @YES,
 | 
					                                                               NSMigratePersistentStoresAutomaticallyOption: @YES,
 | 
				
			||||||
                                                               NSInferMappingModelAutomaticallyOption      : @YES,
 | 
					                                                               NSInferMappingModelAutomaticallyOption      : @YES,
 | 
				
			||||||
                                                               STORE_OPTIONS
 | 
					                                                               STORE_OPTIONS
 | 
				
			||||||
                                                       } error:&error]) {
 | 
					                                                       } error:&error]) {
 | 
				
			||||||
            MPError( error, @"Failed to open store." );
 | 
					            MPError( error, @"Failed to open store." );
 | 
				
			||||||
 | 
					            PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
 | 
				
			||||||
 | 
					            self.mainManagedObjectContext = nil;
 | 
				
			||||||
 | 
					            self.privateManagedObjectContext = nil;
 | 
				
			||||||
            self.storeCorrupted = @YES;
 | 
					            self.storeCorrupted = @YES;
 | 
				
			||||||
            [self handleCoordinatorError:error];
 | 
					            [self handleCoordinatorError:error];
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
@@ -274,6 +279,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
 | 
				
			|||||||
    }];
 | 
					    }];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- (void)retryCorruptStore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self.storeCorrupted = @NO;
 | 
				
			||||||
 | 
					    [self loadStore];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (void)deleteAndResetStore {
 | 
					- (void)deleteAndResetStore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @synchronized (self) {
 | 
					    @synchronized (self) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -558,14 +558,15 @@
 | 
				
			|||||||
                            @"This may be due to corruption.  You can either reset Master Password and "
 | 
					                            @"This may be due to corruption.  You can either reset Master Password and "
 | 
				
			||||||
                            @"recreate your user, or E-Mail us your logs and leave your corrupt store as-is for now."
 | 
					                            @"recreate your user, or E-Mail us your logs and leave your corrupt store as-is for now."
 | 
				
			||||||
                                                                    preferredStyle:UIAlertControllerStyleAlert];
 | 
					                                                                    preferredStyle:UIAlertControllerStyleAlert];
 | 
				
			||||||
            [alert addAction:[UIAlertAction actionWithTitle:@"E-Mail Logs" style:UIAlertActionStyleDefault
 | 
					            [alert addAction:[UIAlertAction actionWithTitle:@"Try Again" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
 | 
				
			||||||
                                                    handler:^(UIAlertAction *action) {
 | 
					                [self retryCorruptStore];
 | 
				
			||||||
                                                        [self openFeedbackWithLogs:YES forVC:nil];
 | 
					            }]];
 | 
				
			||||||
                                                    }]];
 | 
					            [alert addAction:[UIAlertAction actionWithTitle:@"Send Logs" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
 | 
				
			||||||
 | 
					                [self openFeedbackWithLogs:YES forVC:nil];
 | 
				
			||||||
 | 
					            }]];
 | 
				
			||||||
            [alert addAction:[UIAlertAction actionWithTitle:@"Reset" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
 | 
					            [alert addAction:[UIAlertAction actionWithTitle:@"Reset" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
 | 
				
			||||||
                [self deleteAndResetStore];
 | 
					                [self deleteAndResetStore];
 | 
				
			||||||
            }]];
 | 
					            }]];
 | 
				
			||||||
            [alert addAction:[UIAlertAction actionWithTitle:@"Ignore" style:UIAlertActionStyleCancel handler:nil]];
 | 
					 | 
				
			||||||
            [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
 | 
					            [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
 | 
				
			||||||
        } );
 | 
					        } );
 | 
				
			||||||
    } );
 | 
					    } );
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user