0

I am trying to pull a user's twitter handle and populate it into a textfield in a tableview. The request completes successfully and calls the execution block, but the UI takes several seconds to update. I've tried using NSNotifications to trigger the UI change but that still had a delay in updating the UI. Below is the code I use to pull information from ACAccountStore and the only special class I am using for the table is for a custom UITableViewCell. Is anyone else seeing this? or am I missing something that's causing a runtime issue?

- (IBAction)connectTwitter:(id)sender {
      UISwitch *sw = (UISwitch *)sender;
      if (sw.isOn == NO) {
           return;
      }    
     ACAccountStore *account = [[ACAccountStore alloc] init];
     ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    __weak MBSuitUpViewController *weakSelf = self;
    [account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
        if (granted == YES) {
            NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
            if (arrayOfAccounts.count > 0) {
                ACAccount *twitterAccount = [arrayOfAccounts lastObject];
                NSURL *requestURL = [NSURL URLWithString:@"https://api.twitter.com/1/account/verify_credentials.json"];
                SLRequest *user = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
                user.account = twitterAccount;
                [user performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
                    [weakSelf twitterDictionaryHandler:json];
                    weakSelf.userInfo = @{@"name": json[@"name"], @"handle":json[@"screen_name"]};
            }];
            } else {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"No Twitter Account Found" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
                [alert show];
            }
        } else {
            NSLog(@"Permission denied %@", error.localizedDescription);
        }
    }];
}

- (void)twitterDictionaryHandler:(NSDictionary *)dictionary {
    MBSuitUpCell *username = (MBSuitUpCell *)[self.view viewWithTag:2];
    username.textField.text = dictionary[@"screen_name"];
    NSLog(@"Should update textfield");
}

1 Answers1

1

Does it actually call the 'twitterDictionaryHandler' function right away?

If it does that, but does not update the UI for a while then it seems to be a common issue with iOS. What you need to do is place the change of the UI into the GCD (Grand Central Dispatch) Main Queue so that it has priority and is completed ASAP. I've put an example below for anyone else who may have this issue.

dispatch_async(dispatch_get_main_queue(), ^{
    username.textField.text = dictionary[@"screen_name"]; 
}); 
Joey Clover
  • 756
  • 5
  • 14
  • It actually calls the twitterDictionaryHandler function immediately. Since I save the user Information I tried doing an tableview reload with it checking against the userinformation. I logged the end of the block and the table reload and saw an 11 second delay from the end of the block to the table reload. – Dominic Macanas Feb 25 '14 at 20:45
  • 1
    Thanks for the suggestion of running it using GCD, I bumped the twitterDictionaryHandler into the main queue and it updated within a second. – Dominic Macanas Feb 25 '14 at 20:53