2011-11-23 43 views
1

我一直在嘗試使用TWrequest並檢索一段Tweets,但我遇到了保持數據同步和更新tableview的問題。UITableView中的數據與iOS5中的TWRequest同步

我在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];  
} 

這工作正常但eac小時所需時間我儘量讓我跑在這個變化轉換問題

  1. 如果我嘗試解析在performRequestWithHandler塊的JSON日期和傳回的解析數據,我得到一個斷言失敗。
  2. 如果我將訪問帳戶的請求移動到AppDelegate(以便最終可以在不同的視圖控制器之間共享帳戶信息)並將需要的帳戶傳遞給TableViewController,則會發生斷言失敗。

在這兩種情況下,斷言失敗似乎是相同的:實現代碼如下將會更新足夠的tweets來填充屏幕的第一時間,然後它會做出的tableView一個電話:numberOfRowsInSection:併爲下一個單元格中的數據後,一片空白。

2011-11-23 00:02:57.470 TwitteriOS5Tutorial [9750:10403] *在聲明失敗 - [UITableView的_createPreparedCellForGlobalRow:withIndexPath:],/SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:6072

2011-11-23 00:02:57.471 TwitteriOS5Tutorial [9750:10403] *終止應用程序由於未捕獲的異常 'NSInternalInconsistencyException',原因: '數據源的UITableView必須從的tableView返回一個細胞:的cellForRowAtIndexPath:'

我試過看其他類似的問題,但我不明白如何保持不同租用塊同步。讓我感到奇怪的是,賬戶信息請求所在的位置的影響。

homeTimeLineData在這種情況下只是一個NSMutableArray。是去核心數據和使用NSFetchResultsController的解決方案?

我對塊的知識仍然有限,所以任何見解都將不勝感激。 謝謝, 諾曼


更新:
我相信我發現這個問題,它關係到故事板和TableViewCells。

在對故事板我也跟着教程它說,你可以用一條線

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"]; 

更換

NSString *CellIdentifier = @"MyCell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) { 
    cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
} 

和故事板會自動如果需要創建細胞的新副本的護理沒有一個出軌。我檢查了Apple的文檔,它也這樣說。

我遵循這個建議,只使用了單行聲明,它工作到一定程度,但隨後當我重構並重新安排代碼時,我開始出現斷言失敗。

我使用的是自定義的UITableViewCell與IBOutlets在細胞內重新定位的不同元素,因此它可能是一個限制,即移除「檢查電池的返回值」行,你必須堅持使用標準的細胞,並盡一切在故事板和Interface Builder中進行自定義。

有沒有人遇到類似的問題?

回答

3

我想你正在使用ARC。確保您保留AccountStore,例如通過宣佈這樣一個強大的屬性:

// AccountsListViewController.h 
@property (strong, nonatomic) ACAccountStore *accountStore; 

然後,您可以使用此列表到您的設備上獲取帳戶列表:只要用戶選擇其中的一個帳戶

// 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]; 
       }); 
      } 
     }]; 
    } 
} 

,分配它的視圖控制器,你將使用以顯示鳴叫名單:

// 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,你需要堅持到該帳戶在強大的屬性,就像這樣:

// 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恢復主線程 - 這很好!

我張貼可以在這裏找到源的完整論述:http://www.peterfriese.de/the-accounts-and-twitter-framework-on-ios-5/,源可在Github上:https://github.com/peterfriese/TwitterClient

+0

感謝您的答覆。正如我在更新中提到的,問題似乎與故事板不會自動分配新單元格有關。無論如何,我要仔細看看Github上的教程和代碼。再次感謝諾曼 – nsecord