2
0

More robust against exceptions and a few other fixes.

This commit is contained in:
Maarten Billemont 2014-10-22 21:17:02 -04:00
parent bb97e8f3e8
commit 85dab50996
6 changed files with 106 additions and 55 deletions

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit 717bc5e5e7be3aedb997581260b67579eb651f8e Subproject commit 3c7b13b3649c92f7d30e4b8bd0570c8c6b1798c6

View File

@ -32,6 +32,13 @@ fi
### DEPENDENCIES ### DEPENDENCIES
digest() {
if hash xxd 2>/dev/null; then
openssl sha1 -binary < "$1" | xxd -p
else
openssl sha1 < "$1" | sed 's/.* //'
fi
}
fetch() { fetch() {
if hash wget 2>/dev/null; then if hash wget 2>/dev/null; then
wget -O "${1##*/}" "$1" wget -O "${1##*/}" "$1"
@ -54,7 +61,7 @@ unpack() {
fi fi
printf 'Verifying package: %s, against digest: %s...' "$1" "$2" printf 'Verifying package: %s, against digest: %s...' "$1" "$2"
[[ $(openssl sha < "$1") = $2 ]] || { [[ $(digest "$1") = $2 ]] || {
printf ' mismatch!\n' printf ' mismatch!\n'
echo 2>&1 "Downloaded package doesn't match digest." echo 2>&1 "Downloaded package doesn't match digest."
exit 1 exit 1

View File

@ -56,7 +56,11 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO; return NO;
[mainManagedObjectContext performBlock:^{ [mainManagedObjectContext performBlock:^{
mocBlock( mainManagedObjectContext ); @try {
mocBlock( mainManagedObjectContext );
} @catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}]; }];
return YES; return YES;
@ -69,7 +73,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO; return NO;
[mainManagedObjectContext performBlockAndWait:^{ [mainManagedObjectContext performBlockAndWait:^{
mocBlock( mainManagedObjectContext ); @try {
mocBlock( mainManagedObjectContext );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}]; }];
return YES; return YES;
@ -84,7 +93,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady; moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlock:^{ [moc performBlock:^{
mocBlock( moc ); @try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}]; }];
return YES; return YES;
@ -99,7 +113,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady; moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlockAndWait:^{ [moc performBlockAndWait:^{
mocBlock( moc ); @try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}]; }];
return YES; return YES;
@ -195,7 +214,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
^(NSNotification *note) { ^(NSNotification *note) {
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext. // When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
[self.mainManagedObjectContext performBlock:^{ [self.mainManagedObjectContext performBlock:^{
[self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note]; @try {
[self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
}
@catch (NSException *exception) {
err( @"While merging changes:\n%@", [exception fullDescription] );
}
}]; }];
}]; }];

View File

@ -23,7 +23,7 @@
} }
@catch (NSException *exception) { @catch (NSException *exception) {
success = NO; success = NO;
err( @"While saving: %@", exception ); err( @"While saving: %@", [exception fullDescription] );
} }
}]; }];
} }
@ -128,10 +128,15 @@
- (NSString *)debugDescription { - (NSString *)debugDescription {
return strf( @"{%@: name=%@, user=%@, type=%lu, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}", @try {
NSStringFromClass( [self class] ), self.name, self.user.name, (long)self.type, (long)self.uses, self.lastUsed, return strf( @"{%@: name=%@, user=%@, type=%lu, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}",
(long)self.version, NSStringFromClass( [self class] ), self.name, self.user.name, (long)self.type, (long)self.uses, self.lastUsed,
self.loginName, self.requiresExplicitMigration ); (long)self.version,
self.loginName, self.requiresExplicitMigration );
} @catch (NSException *exception) {
return strf( @"{%@: inaccessible: %@}",
NSStringFromClass( [self class] ), [exception fullDescription] );
}
} }
- (BOOL)tryMigrateExplicitly:(BOOL)explicit { - (BOOL)tryMigrateExplicitly:(BOOL)explicit {

View File

@ -257,8 +257,11 @@
return; return;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[context deleteObject:[self siteInContext:context]]; MPSiteEntity *site_ = [self siteInContext:context];
[context saveToStore]; if (site_) {
[context deleteObject:site_];
[context saveToStore];
}
}]; }];
} cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil]; } cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil];
} }

View File

@ -64,7 +64,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
self.view.backgroundColor = [UIColor clearColor]; self.view.backgroundColor = [UIColor clearColor];
[self.passwordCollectionView automaticallyAdjustInsetsForKeyboard]; [self.passwordCollectionView automaticallyAdjustInsetsForKeyboard];
self.passwordsSearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone; self.passwordsSearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
if ([self.passwordsSearchBar respondsToSelector:@selector(keyboardAppearance)]) if ([self.passwordsSearchBar respondsToSelector:@selector( keyboardAppearance )])
self.passwordsSearchBar.keyboardAppearance = UIKeyboardAppearanceDark; self.passwordsSearchBar.keyboardAppearance = UIKeyboardAppearanceDark;
else else
[self.passwordsSearchBar enumerateViews:^(UIView *subview, BOOL *stop, BOOL *recurse) { [self.passwordsSearchBar enumerateViews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
@ -170,23 +170,29 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
if (controller == _fetchedResultsController) { if (controller == _fetchedResultsController) {
[self.passwordCollectionView performBatchUpdates:^{ @try {
[self fetchedItemsDidUpdate]; [self.passwordCollectionView performBatchUpdates:^{
switch (type) { [self fetchedItemsDidUpdate];
case NSFetchedResultsChangeInsert: switch (type) {
[self.passwordCollectionView insertItemsAtIndexPaths:@[ newIndexPath ]]; case NSFetchedResultsChangeInsert:
break; [self.passwordCollectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
case NSFetchedResultsChangeDelete: break;
[self.passwordCollectionView deleteItemsAtIndexPaths:@[ indexPath ]]; case NSFetchedResultsChangeDelete:
break; [self.passwordCollectionView deleteItemsAtIndexPaths:@[ indexPath ]];
case NSFetchedResultsChangeMove: break;
[self.passwordCollectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath]; case NSFetchedResultsChangeMove:
break; [self.passwordCollectionView moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
case NSFetchedResultsChangeUpdate: break;
[self.passwordCollectionView reloadItemsAtIndexPaths:@[ indexPath ]]; case NSFetchedResultsChangeUpdate:
break; [self.passwordCollectionView reloadItemsAtIndexPaths:@[ indexPath ]];
} break;
} completion:nil]; }
} completion:nil];
}
@catch (NSException *exception) {
wrn( @"While updating password cells: %@", [exception fullDescription] );
[self.passwordCollectionView reloadData];
}
} }
} }
@ -249,7 +255,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
if (searchBar == self.passwordsSearchBar) { if (searchBar == self.passwordsSearchBar) {
if ([self.query length] && [[self.query stringByTrimmingCharactersInSet:_siteNameAcceptableCharactersSet] length]) if ([self.query length] && [[self.query stringByTrimmingCharactersInSet:_siteNameAcceptableCharactersSet] length])
[self showTips:MPPasswordsBadNameTip]; [self showTips:MPPasswordsBadNameTip];
[self updatePasswords]; [self updatePasswords];
} }
} }
@ -261,7 +267,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
[UIView animateWithDuration:0.3f animations:^{ [UIView animateWithDuration:0.3f animations:^{
if (showTips & MPPasswordsBadNameTip) if (showTips & MPPasswordsBadNameTip)
self.badNameTipContainer.alpha = 1; self.badNameTipContainer.alpha = 1;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
if (finished) if (finished)
PearlMainQueueAfter( 5, ^{ PearlMainQueueAfter( 5, ^{
[UIView animateWithDuration:0.3f animations:^{ [UIView animateWithDuration:0.3f animations:^{
@ -375,28 +381,34 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
if (![self.fetchedResultsController performFetch:&error]) if (![self.fetchedResultsController performFetch:&error])
err( @"Couldn't fetch sites: %@", [error fullDescription] ); err( @"Couldn't fetch sites: %@", [error fullDescription] );
[self.passwordCollectionView performBatchUpdates:^{ @try {
[self fetchedItemsDidUpdate]; [self.passwordCollectionView performBatchUpdates:^{
[self fetchedItemsDidUpdate];
NSInteger fromSections = self.passwordCollectionView.numberOfSections; NSInteger fromSections = self.passwordCollectionView.numberOfSections;
NSInteger toSections = [self numberOfSectionsInCollectionView:self.passwordCollectionView]; NSInteger toSections = [self numberOfSectionsInCollectionView:self.passwordCollectionView];
for (NSInteger section = 0; section < MAX( toSections, fromSections ); ++section) { for (NSInteger section = 0; section < MAX( toSections, fromSections ); ++section) {
if (section >= fromSections) if (section >= fromSections)
[self.passwordCollectionView insertSections:[NSIndexSet indexSetWithIndex:section]]; [self.passwordCollectionView insertSections:[NSIndexSet indexSetWithIndex:section]];
else if (section >= toSections) else if (section >= toSections)
[self.passwordCollectionView deleteSections:[NSIndexSet indexSetWithIndex:section]]; [self.passwordCollectionView deleteSections:[NSIndexSet indexSetWithIndex:section]];
else if (section < [oldSections count]) else if (section < [oldSections count])
[self.passwordCollectionView reloadItemsFromArray:oldSections[section] [self.passwordCollectionView reloadItemsFromArray:oldSections[section]
toArray:[[self.fetchedResultsController sections][section] objects] toArray:[[self.fetchedResultsController sections][section] objects]
inSection:section]; inSection:section];
else else
[self.passwordCollectionView reloadSections:[NSIndexSet indexSetWithIndex:section]]; [self.passwordCollectionView reloadSections:[NSIndexSet indexSetWithIndex:section]];
} }
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
if (finished) if (finished)
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top ) [self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top )
animated:YES]; animated:YES];
}]; }];
}
@catch (NSException *exception) {
wrn( @"While updating password cells: %@", [exception fullDescription] );
[self.passwordCollectionView reloadData];
}
}]; }];
} }