简体   繁体   中英

UIAlertView doesn't work in completion handler block

I'm writing code to gain access to a users Twitter account, but am having trouble handling the case where no accounts are on the device. What I'd like to do is display an alert telling the user that in order to authenticate with Twitter, they'll first need to create the account in their settings.

Here's my code:

self.accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountTypeTwitter = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

[self.accountStore requestAccessToAccountsWithType:accountTypeTwitter options:nil completion:^(BOOL granted, NSError *error) {
    if(granted) {
        //Doesn't matter for the present case
    } else if (error){

        [SVProgressHUD dismiss]; //not directly relevant to the present question, but it also doesn't work within the block, so I'm leaving it as a clue

        switch ([error code]){
            case (6):

                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"No Twitter Account Detected" message:@"Please go into your device's settings menu to add your Twitter account." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show]; //triggers an error
                break;

        }
    } 
}];

I'm no expert with the Xcode debugger, but apparently the error is occurring in the ACAccountStoreReply thread, about 25 calls deep after [alert show] is called, in a process called ucol_getVersion. Debugger states EXC_BAD_ACCESS(code=2, address=0xcc).

I've searched on Stack Overflow and the internet at large for solutions regarding UIAlertViews not working in blocks, and also for general problems showing alerts (I've tried different values for the delegate), and also for general problems with calls to requestAccessToAccountsWithType.

I've also attempted to brush up on my understanding of blocks by reading various online resources, and the relevant pages of Programming in Objective-C, 4th addition.

Any help is appreciated.

You should always make sure any UI interaction is done on the main thread. Wrap your UIAlertView call in a dispatch_async :

dispatch_async(dispatch_get_main_queue(), ^{
   UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Twitter Account Detected" message:@"Please go into your device's settings menu to add your Twitter account." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
   [alert show];
});

You also had two nil s at the end of the call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM