iOS Lag when Updating Button in ACAccountStoreRequestAccessCompletionHandler for Twitter

389 views Asked by At

I'm trying to make a toggle button that to indicate sharing to Twitter, like in the Instagram share page that appears after taking a photo. Specifically it's a UIButton that start in the Normal state, then when it's pressed it goes into the Selected state with the user's Twitter handle as the title.

On the first tap, it checks with the ACAccountStore for a stored Twitter account. The problem is lagginess in the ACAccountStoreRequestAccessCompletionHandler in the requestAccessToAccountsWithType function. In the handler I make the change to setup the Twitter handle and to select the button. However, the button takes a long time to visually change the selected state. This is despite it being in the selected state as verified by an NSLog after the call.

I can't figure out what's causing this lag. This is the code that handles the button.

- (IBAction)pressedTwitter:(id)sender {
    UIButton *button = (UIButton*)sender;
    if (button.selected) {
        button.selected = !button.selected;
    } else {
        if (self.twitterAccount != nil) {
            button.selected = !button.selected;
        } else {
            [self getTwitterAccount:button];
        }
    }
}


- (void)getTwitterAccount:(UIButton*)button
{
    // Get Account
    ACAccountStore *store = [[ACAccountStore alloc] init];
    ACAccountType *twitterAccountType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    //  Request permission from the user to access the available Twitter accounts
    [store requestAccessToAccountsWithType:twitterAccountType options:nil completion:^(BOOL granted, NSError *error) {
        if (granted) {
            NSArray *twitterAccounts = [store accountsWithAccountType:twitterAccountType];

            if ([twitterAccounts count] > 0) {
                self.twitterAccount = [twitterAccounts objectAtIndex:0];
                [self.twitterButton setTitle:self.twitterAccount.username forState:UIControlStateSelected];


                [self setTwitterButtonNormalText:YES];
                self.twitterButton.selected = YES;
                NSLog(@"Twitter Button Selected");

                self.statusLabel.text = @"Twitter Account Found";
            } else {
                [self setTwitterButtonNormalText:NO];
                button.selected = NO;

                NSLog(@"Not enough Twitter Accounts");
            }
        } else {
            NSLog(@"Twitter Account Permission Not Granted");

            [self setTwitterButtonNormalText:NO];
            button.selected = NO;

        }
    }];
}

- (void)setTwitterButtonNormalText:(BOOL)accountAvailable
{
    if (accountAvailable) {
        [self.twitterButton setTitle:@"Twitter" forState:UIControlStateNormal];
        [self.twitterButton setTitleColor:[UIColor colorWithWhite:0.5 alpha:1.0] forState:UIControlStateNormal];
    } else {
        [self.twitterButton setTitle:@"No Twitter" forState:UIControlStateNormal];
        [self.twitterButton setTitleColor:[UIColor colorWithRed:125./255. green:21./255. blue:0 alpha:1] forState:UIControlStateNormal];
    }
}

Thanks for any help you can provide.

1

There are 1 answers

0
deramko On

I just solved a similar problem. It is because the requestAccessToAccountsWithType completion function is on a different thread and you must go back to main thread if you want to intreact with the interface.

You can go back to the main thread:

dispatch_sync(dispatch_get_main_queue(), ^{
    // code that change the ui, perfom segues, ...
});

Try this:

- (void)getTwitterAccount:(UIButton*)button
{
    // Get Account
    ACAccountStore *store = [[ACAccountStore alloc] init];
    ACAccountType *twitterAccountType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    //  Request permission from the user to access the available Twitter accounts
    [store requestAccessToAccountsWithType:twitterAccountType options:nil completion:^(BOOL granted, NSError *error) {
        if (granted) {
            NSArray *twitterAccounts = [store accountsWithAccountType:twitterAccountType];

            if ([twitterAccounts count] > 0) {
                self.twitterAccount = [twitterAccounts objectAtIndex:0];
                // go back to the main thread
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [self.twitterButton setTitle:self.twitterAccount.username forState:UIControlStateSelected];
                    [self setTwitterButtonNormalText:YES];
                    self.twitterButton.selected = YES;
                });
                NSLog(@"Twitter Button Selected");

                self.statusLabel.text = @"Twitter Account Found";
            } else {
                // go back to the main thread
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [self setTwitterButtonNormalText:NO];
                    button.selected = NO;
                });
                NSLog(@"Not enough Twitter Accounts");
            }
        } else {
            NSLog(@"Twitter Account Permission Not Granted");
            // go back to the main thread
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self setTwitterButtonNormalText:NO];
                button.selected = NO;
            });
        }
    }];
}