截断推文iOS

时间:2012-11-29 09:03:01

标签: ios json twitter truncate truncated

我在我的应用程序中添加了一个Twitter提要,无论我试图做什么来完整地显示推文,我都没有完全成功。大多数推文都很好,但真正很长的推文让我头疼。我以为是因为我在textbabel中没有得到足够的行,但是我注意到如果用户通过多次输入来延长他们的推文,那么推文就会显得很好。这导致我相信它会在一定数量的字符后截断。我不知道我做错了什么,或者这只是twitter的一个问题。如果有人在我的代码中看到任何错误,或者可以更改以解决此问题,请告诉我。谢谢

#import "TwitterFeedTVC.h"
#import "TweetVC.h"
#import <QuartzCore/QuartzCore.h>
#import "GTMNSString+HTML.h"

#define REFRESH_HEADER_HEIGHT 52.0f
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f


@implementation TwitterFeedTVC

@synthesize textPull, textRelease, textLoading, refreshHeaderView, refreshLabel, refreshArrow, refreshSpinner, twitterFeedName, twitterFeedTitle;

- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self != nil) 
{
    [self setupStrings]; 
}
return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self != nil)
{
    [self setupStrings];
}
return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self != nil)
{
    [self setupStrings];
}
return  self;
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];
self.twitterFeedTitle.text = self.twitterFeedName;
self.navigationItem.title = self.twitterFeedName;

[self fetchTweets];
[self addPullToRefreshHeader];
}

- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://api.twitter.com/1/statuses/user_timeline.json?include_rts=true&screen_name=johnnelm9r&count=100"]];

    if (data == nil)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning"
                                                        message:@"Twitter Is Not Responding. Please Try Again Later!"
                                                       delegate:self
                                              cancelButtonTitle:@"Kali Baby" 
                                              otherButtonTitles: nil];

        [alert show];
    }

    else

    {
    NSError *error;

    tweets = [NSJSONSerialization JSONObjectWithData:data
                                             options:kNilOptions
                                               error:&error];
    }

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });

});


}

- (void)viewDidUnload
{
[super viewDidUnload];

textPull = nil;
textRelease = nil;
textLoading = nil;
refreshHeaderView = nil;
refreshLabel = nil;
refreshArrow = nil;
refreshSpinner = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotate
{
return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tweets.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *text = [tweet objectForKey:@"text"];

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), CGFLOAT_MAX);

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

CGFloat height = MAX(size.height, 44.0f);

return height + ((CELL_CONTENT_MARGIN * 2) + 9);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"TweetCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
    {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[dateFormatter setDateFormat:@"EEE MMM dd HH:mm:ss +0000 yyyy"];

NSDate *currentDate = [dateFormatter dateFromString:[tweet objectForKey:@"created_at"]];
NSDate *todayDate = [NSDate date];
NSString *date = [dateFormatter stringFromDate:currentDate];

double timeInterval = [currentDate timeIntervalSinceDate:todayDate];
timeInterval = timeInterval * -1;
if (timeInterval < 1)
{
    date = @"never";
}
else if (timeInterval <60)
{
    date = @"less than a minute ago";
}
else if (timeInterval <3600)
{
    int diff = round(timeInterval / 60);
    date = [NSString stringWithFormat:@"%d minutes ago", diff];
}
else if (timeInterval < 86400)
{
    int diff = round(timeInterval / 60 / 60);
    date = [NSString stringWithFormat:@"%d hours ago", diff];
}
else if (timeInterval < 2629743)
{
    int diff = round(timeInterval / 60 / 60 / 24);
    date = [NSString stringWithFormat:@"%d days ago", diff];
}
else
{
    date = @"never";
}

cell.textLabel.text = [[tweet objectForKey:@"text"] gtm_stringByUnescapingFromHTML];
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", date];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString *imageUrl = [[tweet objectForKey:@"user"] objectForKey:@"profile_image_url"];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];

    dispatch_async(dispatch_get_main_queue(), ^{
        cell.imageView.image = [UIImage imageWithData:data];
        [cell addSubview:cell.imageView];

    });
});

return cell;
}

- (void)setupStrings
{
textPull = @"Pull Down To Be Fresh...";
textRelease = @"Release To Be Fresh...";
textLoading = @"Getting Loaded...";
}

- (void)addPullToRefreshHeader
{
refreshHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0 - REFRESH_HEADER_HEIGHT, 320, REFRESH_HEADER_HEIGHT)];
refreshHeaderView.backgroundColor = [UIColor clearColor];

refreshLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, REFRESH_HEADER_HEIGHT)];
refreshLabel.backgroundColor = [UIColor clearColor];
refreshLabel.font = [UIFont boldSystemFontOfSize:12.0];
refreshLabel.textAlignment = UITextAlignmentCenter;

refreshArrow = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"KrizzOpener.png"]];
refreshArrow.frame = CGRectMake(floorf((REFRESH_HEADER_HEIGHT - 27) / 2),
                                (floorf(REFRESH_HEADER_HEIGHT - 44) / 2),
                                27, 44);

refreshSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
refreshSpinner.frame = CGRectMake(floorf(floorf(REFRESH_HEADER_HEIGHT - 20) / 2), floorf((REFRESH_HEADER_HEIGHT - 20) / 2), 20, 20);
refreshSpinner.hidesWhenStopped = YES;

[refreshHeaderView addSubview:refreshLabel];
[refreshHeaderView addSubview:refreshArrow];
[refreshHeaderView addSubview:refreshSpinner];
[self.tableView addSubview:refreshHeaderView];

}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (isLoading) return;
isDragging = YES;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (isLoading) {

    if (scrollView.contentOffset.y > 0)
        self.tableView.contentInset = UIEdgeInsetsZero;
    else if (scrollView.contentOffset.y >= -REFRESH_HEADER_HEIGHT)
        self.tableView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (isDragging && scrollView.contentOffset.y < 0) {

    [UIView beginAnimations:nil context:NULL];
    if (scrollView.contentOffset.y < -REFRESH_HEADER_HEIGHT) {

        refreshLabel.text = self.textRelease;
    } else { 
        refreshLabel.text = self.textPull;
    }
    [UIView commitAnimations];
}
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (isLoading) return;
isDragging = NO;
if (scrollView.contentOffset.y <= -REFRESH_HEADER_HEIGHT)
{
    [self startLoading];
}
}

- (void)startLoading {
isLoading = YES;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
self.tableView.contentInset = UIEdgeInsetsMake(REFRESH_HEADER_HEIGHT, 0, 0, 0);
refreshLabel.text = self.textLoading;
refreshArrow.hidden = YES;
[refreshSpinner startAnimating];
[UIView commitAnimations];

[self refresh];
}

- (void)stopLoading {
isLoading = NO;

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDidStopSelector:@selector(stopLoadingComplete:finished:context:)];
self.tableView.contentInset = UIEdgeInsetsZero;
UIEdgeInsets tableContentInset = self.tableView.contentInset;
tableContentInset.top = 0.0;
self.tableView.contentInset = tableContentInset;
[UIView commitAnimations];
}

- (void)stopLoadingComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

refreshLabel.text = self.textPull;
refreshArrow.hidden = NO;
[refreshSpinner stopAnimating];

}

- (void)refresh {

[self fetchTweets];

[self performSelector:@selector(stopLoading) withObject:nil afterDelay:2.7];
}


#pragma mark - Table view delegate

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"tweetVC"])
{
    NSInteger row = [[self tableView].indexPathForSelectedRow row];
    NSDictionary *tweet = [tweets objectAtIndex:row];

    TweetVC *tweetVC = segue.destinationViewController;
    tweetVC.detailItem = tweet;
}
}

2 个答案:

答案 0 :(得分:0)

经过大量调查后,我发现某篇文章说文本键和retweeted_status.text键之间存在差异。事实上,被截断的推文是使用文本密钥从用户转发的。但是,retweeted_status.text键只是被转发的推文,而没有最初发推文的用户。这很糟糕,因为retweeted_status.text键没有被截断。啊,编程的乐趣。希望新的推特API将解决这个问题。我希望这个答案可以帮到某个人。

以下是我发现的任何人感兴趣的链接:http://code.google.com/p/twitter-api/issues/detail?id=2261

答案 1 :(得分:-1)

我没有查看你的代码,但我想提到这一点,Twitter只允许推文140个字符!这是推文的基本规则。所以无论你用什么模式推文都会截断140个字符。

我希望这不是问题吗?