Resolve main thread access issues.
This commit is contained in:
		@@ -76,10 +76,7 @@
 | 
				
			|||||||
    NSDictionary *keyQuery = [self createKeyQueryforUser:user origin:&keyOrigin];
 | 
					    NSDictionary *keyQuery = [self createKeyQueryforUser:user origin:&keyOrigin];
 | 
				
			||||||
    id<MPAlgorithm> keyAlgorithm = user.algorithm;
 | 
					    id<MPAlgorithm> keyAlgorithm = user.algorithm;
 | 
				
			||||||
    MPKey *key = [[MPKey alloc] initForFullName:user.name withKeyResolver:^NSData *(id<MPAlgorithm> algorithm) {
 | 
					    MPKey *key = [[MPKey alloc] initForFullName:user.name withKeyResolver:^NSData *(id<MPAlgorithm> algorithm) {
 | 
				
			||||||
        return ![algorithm isEqual:keyAlgorithm]? nil:
 | 
					        return ![algorithm isEqual:keyAlgorithm]? nil: [PearlKeyChain dataOfItemForQuery:keyQuery];
 | 
				
			||||||
               PearlMainQueueAwait( (id)^{
 | 
					 | 
				
			||||||
                   return [PearlKeyChain dataOfItemForQuery:keyQuery];
 | 
					 | 
				
			||||||
               } );
 | 
					 | 
				
			||||||
    }                                 keyOrigin:keyOrigin];
 | 
					    }                                 keyOrigin:keyOrigin];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ([key keyIDForAlgorithm:user.algorithm])
 | 
					    if ([key keyIDForAlgorithm:user.algorithm])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,7 +131,7 @@
 | 
				
			|||||||
- (IBAction)valueChanged:(id)sender {
 | 
					- (IBAction)valueChanged:(id)sender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sender == self.savePasswordSwitch)
 | 
					    if (sender == self.savePasswordSwitch)
 | 
				
			||||||
        [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					        [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
            MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
					            MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
				
			||||||
            if ((activeUser.saveKey = self.savePasswordSwitch.on))
 | 
					            if ((activeUser.saveKey = self.savePasswordSwitch.on))
 | 
				
			||||||
                [[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
 | 
					                [[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
 | 
				
			||||||
@@ -139,13 +139,11 @@
 | 
				
			|||||||
                [[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
 | 
					                [[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
 | 
				
			||||||
            [context saveToStore];
 | 
					            [context saveToStore];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PearlMainQueue( ^{
 | 
					            [self reload];
 | 
				
			||||||
                [self reload];
 | 
					 | 
				
			||||||
            } );
 | 
					 | 
				
			||||||
        }];
 | 
					        }];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sender == self.touchIDSwitch)
 | 
					    if (sender == self.touchIDSwitch)
 | 
				
			||||||
        [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					        [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
            MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
					            MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
				
			||||||
            if ((activeUser.touchID = self.touchIDSwitch.on))
 | 
					            if ((activeUser.touchID = self.touchIDSwitch.on))
 | 
				
			||||||
                [[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
 | 
					                [[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
 | 
				
			||||||
@@ -153,9 +151,7 @@
 | 
				
			|||||||
                [[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
 | 
					                [[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
 | 
				
			||||||
            [context saveToStore];
 | 
					            [context saveToStore];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PearlMainQueue( ^{
 | 
					            [self reload];
 | 
				
			||||||
                [self reload];
 | 
					 | 
				
			||||||
            } );
 | 
					 | 
				
			||||||
        }];
 | 
					        }];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sender == self.generated1TypeControl || sender == self.generated2TypeControl || sender == self.storedTypeControl) {
 | 
					    if (sender == self.generated1TypeControl || sender == self.generated2TypeControl || sender == self.storedTypeControl) {
 | 
				
			||||||
@@ -167,42 +163,34 @@
 | 
				
			|||||||
            self.storedTypeControl.selectedSegmentIndex = -1;
 | 
					            self.storedTypeControl.selectedSegmentIndex = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MPResultType defaultType = [self typeForSelectedSegment];
 | 
					        MPResultType defaultType = [self typeForSelectedSegment];
 | 
				
			||||||
        [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					        [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
            [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = defaultType;
 | 
					            [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = defaultType;
 | 
				
			||||||
            [context saveToStore];
 | 
					            [context saveToStore];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PearlMainQueue( ^{
 | 
					            [self reload];
 | 
				
			||||||
                [self reload];
 | 
					 | 
				
			||||||
            } );
 | 
					 | 
				
			||||||
        }];
 | 
					        }];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (IBAction)previousAvatar:(id)sender {
 | 
					- (IBAction)previousAvatar:(id)sender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					    [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
        MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
					        MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
				
			||||||
        activeUser.avatar = (activeUser.avatar - 1 + MPAvatarCount) % MPAvatarCount;
 | 
					        activeUser.avatar = (activeUser.avatar - 1 + MPAvatarCount) % MPAvatarCount;
 | 
				
			||||||
        [context saveToStore];
 | 
					        [context saveToStore];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        NSUInteger avatar = activeUser.avatar;
 | 
					        self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)activeUser.avatar )];
 | 
				
			||||||
        PearlMainQueue( ^{
 | 
					 | 
				
			||||||
            self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
 | 
					 | 
				
			||||||
        } );
 | 
					 | 
				
			||||||
    }];
 | 
					    }];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (IBAction)nextAvatar:(id)sender {
 | 
					- (IBAction)nextAvatar:(id)sender {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					    [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
        MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
					        MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
 | 
				
			||||||
        activeUser.avatar = (activeUser.avatar + 1 + MPAvatarCount) % MPAvatarCount;
 | 
					        activeUser.avatar = (activeUser.avatar + 1 + MPAvatarCount) % MPAvatarCount;
 | 
				
			||||||
        [context saveToStore];
 | 
					        [context saveToStore];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        NSUInteger avatar = activeUser.avatar;
 | 
					        self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)activeUser.avatar )];
 | 
				
			||||||
        PearlMainQueue( ^{
 | 
					 | 
				
			||||||
            self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
 | 
					 | 
				
			||||||
        } );
 | 
					 | 
				
			||||||
    }];
 | 
					    }];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -149,11 +149,13 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            case MPActiveUserStateLogin: {
 | 
					            case MPActiveUserStateLogin: {
 | 
				
			||||||
                self.entryField.enabled = NO;
 | 
					                self.entryField.enabled = NO;
 | 
				
			||||||
                [self selectedAvatar].spinnerActive = YES;
 | 
					                MPAvatarCell *selectedAvatar = [self selectedAvatar];
 | 
				
			||||||
 | 
					                selectedAvatar.spinnerActive = YES;
 | 
				
			||||||
 | 
					                NSIndexPath *selectedPath = selectedAvatar? [self.avatarCollectionView indexPathForCell:selectedAvatar]: nil;
 | 
				
			||||||
                NSString *masterPassword = self.entryField.text;
 | 
					                NSString *masterPassword = self.entryField.text;
 | 
				
			||||||
                if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
					                if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
 | 
				
			||||||
                    BOOL signedIn = NO, isNew = NO;
 | 
					                    BOOL signedIn = NO, isNew = NO;
 | 
				
			||||||
                    MPUserEntity *user = [self selectedUserInContext:context isNew:&isNew];
 | 
					                    MPUserEntity *user = selectedPath? [self userForIndexPath:selectedPath inContext:context isNew:&isNew]: nil;
 | 
				
			||||||
                    if (!isNew && user)
 | 
					                    if (!isNew && user)
 | 
				
			||||||
                        signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
 | 
					                        signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
 | 
				
			||||||
                                                    usingMasterPassword:masterPassword];
 | 
					                                                    usingMasterPassword:masterPassword];
 | 
				
			||||||
@@ -570,21 +572,10 @@ referenceSizeForFooterInSection:(NSInteger)section {
 | 
				
			|||||||
    return (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:selectedIndexPaths.firstObject];
 | 
					    return (MPAvatarCell *)[self.avatarCollectionView cellForItemAtIndexPath:selectedIndexPaths.firstObject];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (MPUserEntity *)selectedUserInContext:(NSManagedObjectContext *)context isNew:(BOOL *)isNew {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    MPAvatarCell *selectedAvatar = [self selectedAvatar];
 | 
					 | 
				
			||||||
    if (!selectedAvatar) {
 | 
					 | 
				
			||||||
        // No selected user.
 | 
					 | 
				
			||||||
        *isNew = NO;
 | 
					 | 
				
			||||||
        return nil;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return [self userForIndexPath:[self.avatarCollectionView indexPathForCell:selectedAvatar] inContext:context isNew:isNew];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- (MPUserEntity *)userForIndexPath:(NSIndexPath *)indexPath inContext:(NSManagedObjectContext *)context isNew:(BOOL *)isNew {
 | 
					- (MPUserEntity *)userForIndexPath:(NSIndexPath *)indexPath inContext:(NSManagedObjectContext *)context isNew:(BOOL *)isNew {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    if ((*isNew = indexPath.item >= [self.userIDs count]))
 | 
					    *isNew = NO;
 | 
				
			||||||
 | 
					    if (!indexPath || (*isNew = indexPath.item >= [self.userIDs count]))
 | 
				
			||||||
        return nil;
 | 
					        return nil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return [MPUserEntity existingObjectWithID:self.userIDs[indexPath.item] inContext:context];
 | 
					    return [MPUserEntity existingObjectWithID:self.userIDs[indexPath.item] inContext:context];
 | 
				
			||||||
@@ -756,9 +747,11 @@ referenceSizeForFooterInSection:(NSInteger)section {
 | 
				
			|||||||
    PearlMainQueue( ^{
 | 
					    PearlMainQueue( ^{
 | 
				
			||||||
        BOOL isNew = NO;
 | 
					        BOOL isNew = NO;
 | 
				
			||||||
        NSManagedObjectID *selectUserID = [MPiOSAppDelegate get].activeUserOID;
 | 
					        NSManagedObjectID *selectUserID = [MPiOSAppDelegate get].activeUserOID;
 | 
				
			||||||
        if (!selectUserID)
 | 
					        if (!selectUserID) {
 | 
				
			||||||
            selectUserID = [self selectedUserInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]
 | 
					            selectUserID = [self userForIndexPath:self.avatarCollectionView.indexPathsForSelectedItems.firstObject
 | 
				
			||||||
                                                 isNew:&isNew].permanentObjectID;
 | 
					                                        inContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]
 | 
				
			||||||
 | 
					                                            isNew:&isNew].permanentObjectID;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        [self.avatarCollectionView reloadData];
 | 
					        [self.avatarCollectionView reloadData];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        NSUInteger selectedAvatarItem = isNew? [self.userIDs count]: selectUserID? [self.userIDs indexOfObject:selectUserID]: NSNotFound;
 | 
					        NSUInteger selectedAvatarItem = isNew? [self.userIDs count]: selectUserID? [self.userIDs indexOfObject:selectUserID]: NSNotFound;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user