ios - 如何等待委托(delegate)方法完成 block 内的操作表

标签 ios objective-c twitter uiactionsheet

我正在尝试创建一个包含 twitter 帐户列表的操作表,这是我的代码。

这是一些重要方法的代码

//SocialNetworking.m 文件

- (BOOL)loginWithTwitterCompletionBlock:(UIView *)sender :(void (^)(User *,ACAccount *selAccount, NSError *))completionBlock
{
    ACAccountStore *store = [[ACAccountStore alloc] init];
    ACAccountType *twitterType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    [store requestAccessToAccountsWithType:twitterType withCompletionHandler:^(BOOL granted, NSError *error) {
        NSArray *twitterAccounts = [store accountsWithAccountType:twitterType];

        if(twitterAccounts == nil || [twitterAccounts count] == 0) {
            NSMutableDictionary* details = [NSMutableDictionary dictionary];
            [details setValue:@"Account unavailable" forKey:NSLocalizedDescriptionKey];
            NSError *error=[NSError errorWithDomain:@"authentication" code:10 userInfo:details];

            completionBlock(nil,nil, error);

        } else {

                if (granted && !error)
                    {
                        twitterAccountsArray = [store accountsWithAccountType:twitterType];

                        if ([twitterAccountsArray count] > 1)
                        {

                            dispatch_sync(dispatch_get_main_queue(), ^{
                                [self accountListActionSheetDynamic:twitterAccountsArray Sender:sender];
                            });
                        }
                        else
                        {
                            selectedAccount = [twitterAccounts objectAtIndex:0];
                        }
                    }
NSURL *userDetailsURL=[NSURL URLWithString:@"https://api.twitter.com/1.1/users/show.json"];
//Getting the exception in this line below
                NSDictionary *params = @{@"screen_name" : selectedAccount.username,
                                         @"entities" : @"0"};

            TWRequest *request = [[TWRequest alloc] initWithURL:userDetailsURL parameters:params requestMethod:TWRequestMethodGET];
            [request setAccount:selectedAccount];
            [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
             {
                if (responseData)
                {
                    NSError *error = nil;
                    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];


                User *socialUser=[[User alloc] init];

                socialUser.twitterName=[responseDict valueForKey:@"name"];
                socialUser.twitterUserName=selectedAccount.username;
                socialUser.twitterProfileId = [responseDict valueForKey:@"id_str"];
                socialUser.twitterProfileImageURLString=[responseDict valueForKey:@"profile_image_url"];
                socialUser.twitterProfileBackgroundURLString=[responseDict valueForKey:@"profile_background_image_url"];


                completionBlock(socialUser,selectedAccount, nil);
            }

            else
                {
                completionBlock(nil,nil, error);
                }
        }];

}

//Action sheet For Multiple TwitterAccounts
- (void)accountListActionSheetDynamic:(NSArray *) accounts Sender:(UIView*) senderView {

    UIActionSheet *sheet = [[UIActionSheet alloc]
                            initWithTitle:@"Choose a Twitter Account"
                            delegate:self
                            cancelButtonTitle:nil
                            destructiveButtonTitle:nil
                            otherButtonTitles:nil];

    for(int i=0;i<accounts.count;i++)
    {
        NSLog(@"i=%d,AccountName:%@",i,[[accounts objectAtIndex:i] valueForKey:@"username"]);
        [sheet addButtonWithTitle:[[accounts objectAtIndex:i] valueForKey:@"username"]]; 
    }
    [sheet addButtonWithTitle:@"Cancel"];
    sheet.cancelButtonIndex = sheet.numberOfButtons-1;

    [sheet showFromRect:senderView.bounds inView:senderView animated:YES];

}


-(void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == actionSheet.cancelButtonIndex)
    {
        return;
    }
    else
    {

     for(int i=0;i<twitterAccountsArray.count;i++)
        {
            if([[actionSheet buttonTitleAtIndex:buttonIndex] caseInsensitiveCompare:[[twitterAccountsArray objectAtIndex:i] valueForKey:@"username"]]==NSOrderedSame)
            {
                selectedAccount = [twitterAccountsArray objectAtIndex:i];

                return;
            }

        }
    }

}

现在的问题是我在 NSDictionary *params 行遇到异常,因为直到整个代码完成后才会出现操作表,有没有办法在执行移动到 NSDictionary *params 行之前显示操作表作为 selectedAccount 的值尚未设置。

对此有何建议或替代解决方案?我目前正在使用 Xcode 5 并在模拟 iOS 7 中运行。

最佳答案

将该代码封装到一个带有参数的函数中,该参数将被选中。

从 2 个地方调用此函数:

  • 在 selectedAccount = [twitterAccounts objectAtIndex:0] 之后;
  • 在 selectedAccount = [twitterAccountsArray objectAtIndex:i] 之后;
  • 关于ios - 如何等待委托(delegate)方法完成 block 内的操作表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19856495/

    相关文章:

    java - 如何识别 Twitter4j RateLimitStatusEvent 包含哪个端点的限制

    python - 在没有 GoogleService-Info.plist 的情况下将调试符号上传到 Crashlytics

    ios - 如何在 swift 项目中隐藏与我的导航 Controller 相连的所有 View Controller 的页脚?

    ios - 返回 uicolors 数组的类别

    ios - 从 Realm 的子类中调用 [super defaultPropertyValues] 是一个好习惯吗?

    objective-c - 最前面的窗口使用 CGWindowListCopyWindowInfo

    iphone - IOS在TabBar前添加登录界面

    ios - 如何识别 NSString 中的特殊字符?

    ruby - 推特的oauth过程。客户端和Web应用程序之间的区别

    android - Android 中的 Twitter 身份验证