Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

newtoiphonesdk

macrumors 6502a
Original poster
Jul 30, 2010
567
2
I'm working on a UISegmentControl to grant access in the app to the user's Twitter accounts. When they click YES, it triggers the method listed below. The intent is that if the user has more than one Twitter account on their phone, it will show an UIActionSheet listing the Twitter accounts, and they can choose which one they want to post from for future. The code seems good to me, but when the action is triggered, it takes anywhere from 10-30 seconds before the actionsheet appears. Any suggestions for making it run quicker?
Code:
-(void)twitteraccess {
    ACAccountStore *account = [[ACAccountStore alloc] init];
    ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
                                  ACAccountTypeIdentifierTwitter];
    
    [account requestAccessToAccountsWithType:accountType options:nil
                                  completion:^(BOOL granted, NSError *error)
    {
        if (granted == YES)
        {
            NSLog(@"Granted");
            
            NSArray *arrayOfAccounts = [account
                                        accountsWithAccountType:accountType];
            if ([arrayOfAccounts count] > 0)
            {
                //detects that there is at least one account signed in
                if ([arrayOfAccounts count] > 1) {
                    UIActionSheet *chooseaccount = [[UIActionSheet alloc]initWithTitle:@"Choose Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
                    for (int i = 0; i < [arrayOfAccounts count]; i++) {
                        
                        ACAccount * accountname = [arrayOfAccounts objectAtIndex:i];
                        [chooseaccount addButtonWithTitle:accountname.username];
                    }
                    
                    [chooseaccount addButtonWithTitle:@"Cancel"];
                    chooseaccount.cancelButtonIndex = arrayOfAccounts.count;
                    
                    [chooseaccount showInView:self.tabBarController.view];
                }
                else {
                ACAccount *twitterAccount = [arrayOfAccounts lastObject];
                [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"twitter"];
                [[NSUserDefaults standardUserDefaults] synchronize];
                }
                
            }
        }
        else {
            if(error.code == 6){
                [self performSelectorOnMainThread:@selector(alertmessagetwitter)
                                       withObject:nil
                                    waitUntilDone:YES];                }
        }
    }];
}
As I mentioned, it all works fine, just takes too long for the actionsheet to appear.

UPDATE: This is now resolved. The updated code is below:

Code:
-(void)twitteraccess {
    ACAccountStore *account = [[ACAccountStore alloc] init];
    ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
                                  ACAccountTypeIdentifierTwitter];
    
    [account requestAccessToAccountsWithType:accountType options:nil
                                  completion:^(BOOL granted, NSError *error)
    {
        if (granted == YES)
        {
            NSLog(@"Granted");
            
            NSArray *arrayOfAccounts = [account
                                        accountsWithAccountType:accountType];
            if ([arrayOfAccounts count] > 0)
            {
                NSLog(@"%i", [arrayOfAccounts count]);
                
                if ([arrayOfAccounts count] > 1) {
                    NSLog(@"Greaterthan1");
                    [self performSelectorOnMainThread:@selector(twitteractionsheet)
                                           withObject:nil
                                        waitUntilDone:YES];
                                   }
                else {
                ACAccount *twitterAccount = [arrayOfAccounts lastObject];
                [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"twitter"];
                [[NSUserDefaults standardUserDefaults] synchronize];
                }
                
            }
        }
        else {
            if(error.code == 6){
                [self performSelectorOnMainThread:@selector(alertmessagetwitter)
                                       withObject:nil
                                    waitUntilDone:YES];                }
        }
    }];
}
-(void)twitteractionsheet {
    ACAccountStore *account = [[ACAccountStore alloc] init];
    ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
                                  ACAccountTypeIdentifierTwitter];
    NSArray *arrayOfAccounts = [account
                                accountsWithAccountType:accountType];
    UIActionSheet *chooseaccount = [[UIActionSheet alloc]initWithTitle:@"Choose Account" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
    for (int i = 0; i < [arrayOfAccounts count]; i++) {
        
        ACAccount * accountname = [arrayOfAccounts objectAtIndex:i];
        [chooseaccount addButtonWithTitle:accountname.username];
        NSLog(@"%@", accountname.username);
    }
    
    [chooseaccount addButtonWithTitle:@"Cancel"];
    chooseaccount.cancelButtonIndex = arrayOfAccounts.count;
    
    [chooseaccount showInView:self.tabBarController.view];

}
 
Last edited:
Near the bottom you have a call to performSelectorOnMainThread:. Is this method called via a non-main thread? If so, then the call to showInView: needs to be performed from the main thread.

If there is only one Twitter account, then you are just writing to the user defaults. I take it that is what you are doing after the user has made their selection and the call to actionSheet:clickedButtonAtIndex: gets executed.

When I don't know where a delay is coming from I might litter a couple of NSLog statements around to review their times. That can help narrow down which line is causing the delay and properly focus on it.
 
Near the bottom you have a call to performSelectorOnMainThread:. Is this method called via a non-main thread? If so, then the call to showInView: needs to be performed from the main thread.

If there is only one Twitter account, then you are just writing to the user defaults. I take it that is what you are doing after the user has made their selection and the call to actionSheet:clickedButtonAtIndex: gets executed.

When I don't know where a delay is coming from I might litter a couple of NSLog statements around to review their times. That can help narrow down which line is causing the delay and properly focus on it.

Wow, can't believe I missed that. It was definitely the issue. Where I was calling for the action sheet i placed a call to performSelectorOnMainThread with a method for an actionsheet to show the user names. It worked instantly. Thanks for your help!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.