将UITableView中的数据与iOS5中的TWRequest同步
我一直在尝试使用TWrequest并检索一块tweet,但在保持数据同步和更新tableview方面遇到了问题 我在TableViewController中有以下相对简单的块来获取用户帐户信息:将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
- (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上的教程和代码。再次感谢你,诺曼