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

View File

@ -56,7 +56,11 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO;
[mainManagedObjectContext performBlock:^{
mocBlock( mainManagedObjectContext );
@try {
mocBlock( mainManagedObjectContext );
} @catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@ -69,7 +73,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO;
[mainManagedObjectContext performBlockAndWait:^{
mocBlock( mainManagedObjectContext );
@try {
mocBlock( mainManagedObjectContext );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@ -84,7 +93,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlock:^{
mocBlock( moc );
@try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@ -99,7 +113,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlockAndWait:^{
mocBlock( moc );
@try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@ -195,7 +214,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
^(NSNotification *note) {
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
[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) {
success = NO;
err( @"While saving: %@", exception );
err( @"While saving: %@", [exception fullDescription] );
}
}];
}
@ -128,10 +128,15 @@
- (NSString *)debugDescription {
return strf( @"{%@: name=%@, user=%@, type=%lu, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}",
NSStringFromClass( [self class] ), self.name, self.user.name, (long)self.type, (long)self.uses, self.lastUsed,
(long)self.version,
self.loginName, self.requiresExplicitMigration );
@try {
return strf( @"{%@: name=%@, user=%@, type=%lu, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}",
NSStringFromClass( [self class] ), self.name, self.user.name, (long)self.type, (long)self.uses, self.lastUsed,
(long)self.version,
self.loginName, self.requiresExplicitMigration );
} @catch (NSException *exception) {
return strf( @"{%@: inaccessible: %@}",
NSStringFromClass( [self class] ), [exception fullDescription] );
}
}
- (BOOL)tryMigrateExplicitly:(BOOL)explicit {

View File

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

View File

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