将UITableView中的数据与iOS5中的TWRequest同步

将UITableView中的数据与iOS5中的TWRequest同步,uitableview,twitter,ios5,block,Uitableview,Twitter,Ios5,Block,我一直在尝试使用TWrequest并检索一块tweet,但在保持数据同步和更新tableview方面遇到了问题 我在TableViewController中有以下相对简单的块来获取用户帐户信息: - (void)viewDidLoad { NSArray *twitterAccounts = [[NSArray alloc] init]; if ([TWRequest class]) { store = [[ACAccountStore alloc] in

我一直在尝试使用TWrequest并检索一块tweet,但在保持数据同步和更新tableview方面遇到了问题

我在TableViewController中有以下相对简单的块来获取用户帐户信息:

- (void)viewDidLoad
{
  NSArray *twitterAccounts = [[NSArray alloc] init];    
  if ([TWRequest class]) {        
    store = [[ACAccountStore alloc] init];
    ACAccountType *twitterType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    [store requestAccessToAccountsWithType:twitterType withCompletionHandler:^(BOOL granted, NSError *error){
        if (granted == YES) {
            NSLog(@"Access granted to Twitter Accounts");
        } else {
            NSLog(@"Access denied to Twitter Accounts");
        }
    }];       
    twitterAccounts = [store accountsWithAccountType:twitterType];
    self.account = [[store accounts] objectAtIndex:0];
  } else {
    // The iOS5 Twitter Framework is not supported so need to provide alternative
  }

  self.homeTimeLineData = [NSMutableArray array];
  self.profileImages = [NSMutableDictionary dictionary];
  [self updateTimeLineData:HOME_TIMELINE_URL];
  [super viewDidLoad];
}
从用户主页时间线上获取最新的20条推文:

- (void)updateTimeLineData:(NSString *)urlString {

  NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"20", @"count", nil];    
  TWRequest *myHomeTimeLine = [[TWRequest alloc] initWithURL:[NSURL URLWithString:urlString] parameters:parameters requestMethod:TWRequestMethodGET];
  myHomeTimeLine.account = account;

  [myHomeTimeLine performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {    
    NSError *jsonError = nil;
    NSArray *timeLineData = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self refresh:timeLineData]; 
    }); 
  }];    
}
解析时间线数据并重新加载tableview:

- (void)refresh:(NSArray *)arrayOfTweets {

  for (int i=0; i < [arrayOfTweets count]; i++) {       
    NSDictionary *rawTweetJSON = [arrayOfTweets objectAtIndex:i];

    Tweet *tweet = [[Tweet alloc] init];
    tweet.screenName = [[rawTweetJSON objectForKey:@"user"] objectForKey:@"screen_name"];
    tweet.tweetText = [rawTweetJSON objectForKey:@"text"];
    tweet.createdAt = [rawTweetJSON objectForKey:@"created_at"];

    [self.homeTimeLineData insertObject:tweet atIndex:i];
  }

  [self.tableView reloadData];    
}
一行

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
故事板将负责在没有一个单元出列的情况下自动创建单元的新副本。我查看了苹果的文档,上面也写着

我遵循了这个建议,只使用了单行声明,在某种程度上起到了作用,但当我重构和重新排列代码时,我开始发现断言失败了

我正在使用带有IBOutlets的自定义UITableViewCell来重新定位单元格中的不同元素,因此,要删除“检查单元格返回值”的行,您必须坚持使用标准单元格,并在情节提要和界面生成器中进行所有自定义,这可能是一个限制


有人遇到过类似的问题吗?

我想你正在使用ARC。确保保留
帐户存储
,例如,通过声明如下强属性:

// AccountsListViewController.h
@property (strong, nonatomic) ACAccountStore *accountStore;
// TweetListViewController.h
@property (strong, nonatomic) ACAccount *account;
@property (strong, nonatomic) id timeline;
// TweetListViewController.m
- (void)fetchData
{
    NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/1/statuses/home_timeline.json"];
    TWRequest *request = [[TWRequest alloc] initWithURL:url 
                                                 parameters:nil 
                                              requestMethod:TWRequestMethodGET];
    [request setAccount:self.account];    
    [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        if ([urlResponse statusCode] == 200) {
            NSError *jsonError = nil;

            self.timeline = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });
        }
    }];

}
然后,您可以使用此列表获取设备上的帐户列表:

// AccountsListViewController.m
- (void)fetchData
{
    if (_accounts == nil) {
        if (_accountStore == nil) {
            self.accountStore = [[ACAccountStore alloc] init];
        }
        ACAccountType *accountTypeTwitter = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
        [self.accountStore requestAccessToAccountsWithType:accountTypeTwitter withCompletionHandler:^(BOOL granted, NSError *error) {
            if(granted) {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    self.accounts = [self.accountStore accountsWithAccountType:accountTypeTwitter];
                    [self.tableView reloadData]; 
                });
            }
        }];
    }
}
一旦用户选择其中一个帐户,将其分配给视图控制器,您将使用该视图控制器显示tweet列表:

// AccountsListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    TweetsListViewController *tweetsListViewController = [[TweetsListViewController alloc] init];
    tweetsListViewController.account = [self.accounts objectAtIndex:[indexPath row]];
    [self.navigationController pushViewController:tweetsListViewController animated:TRUE];
}
现在,在TweetListViewController中,您需要在强属性中保留帐户,如下所示:

// AccountsListViewController.h
@property (strong, nonatomic) ACAccountStore *accountStore;
// TweetListViewController.h
@property (strong, nonatomic) ACAccount *account;
@property (strong, nonatomic) id timeline;
// TweetListViewController.m
- (void)fetchData
{
    NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/1/statuses/home_timeline.json"];
    TWRequest *request = [[TWRequest alloc] initWithURL:url 
                                                 parameters:nil 
                                              requestMethod:TWRequestMethodGET];
    [request setAccount:self.account];    
    [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        if ([urlResponse statusCode] == 200) {
            NSError *jsonError = nil;

            self.timeline = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });
        }
    }];

}
最后在您的视图中获取推文,如下所示:

// AccountsListViewController.h
@property (strong, nonatomic) ACAccountStore *accountStore;
// TweetListViewController.h
@property (strong, nonatomic) ACAccount *account;
@property (strong, nonatomic) id timeline;
// TweetListViewController.m
- (void)fetchData
{
    NSURL *url = [NSURL URLWithString:@"https://api.twitter.com/1/statuses/home_timeline.json"];
    TWRequest *request = [[TWRequest alloc] initWithURL:url 
                                                 parameters:nil 
                                              requestMethod:TWRequestMethodGET];
    [request setAccount:self.account];    
    [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
        if ([urlResponse statusCode] == 200) {
            NSError *jsonError = nil;

            self.timeline = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self.tableView reloadData];
            });
        }
    }];

}
解析
performRequestWithHandler
中的JSON数据一点也不坏。事实上,我不认为这样做有什么不对。您正在以一种很好的异步方式工作,利用GCD返回主线程——这很好


关于我发布的源代码的完整讨论可以在这里找到:,源代码可以在Github上找到:

感谢您的回复。正如我在更新中提到的,问题似乎与故事板没有自动分配新单元有关。无论如何,我将仔细看看您在Github上的教程和代码。再次感谢你,诺曼