有没有办法首先加载文本字符串,然后使用AFNetworking加载图像?

时间:2013-10-29 19:45:50

标签: ios ruby-on-rails json afnetworking

我正在使用AFNetworking将JSON解析为我的应用程序(使用Rails作为我的后端)。现在我的应用程序非常慢,所以我想找到一种方法让它更顺畅。当我第一次加载应用程序时,它需要几秒钟才能填充(它显示导航项目和白页,然后几秒钟后我的“帖子”出现)。

集合视图控制器

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.upcomingReleases = [[NSMutableArray alloc] init];

    [self makeReleasesRequests];

    [self.collectionView registerClass:[ReleaseCell class] forCellWithReuseIdentifier:@"ReleaseCell"];
}

-(void)makeReleasesRequests
{
    NSURL *url = [NSURL URLWithString:@"http://www.soleresource.com/upcoming.json"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSLog(@"@");

        self.upcomingReleases = [responseObject objectForKey:@"upcoming_releases"];

        [self.collectionView reloadData];

    } failure:nil];

    [operation start];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return [self.upcomingReleases count];
}

#pragma mark - Show upcoming release shoe

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"Cell";

    ReleaseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    NSDictionary *upcomingReleaseDictionary = [self.upcomingReleases objectAtIndex:indexPath.row];

    NSString *thumbURL = nil;

    cell.release_name.text = [NSString stringWithFormat:@"%@ — $%@",[upcomingReleaseDictionary objectForKey:@"release_name"], [upcomingReleaseDictionary objectForKey:@"release_price"]];

    if ([upcomingReleaseDictionary[@"images"] isKindOfClass:[NSArray class]] && [upcomingReleaseDictionary[@"images"] count]) {
        thumbURL = upcomingReleaseDictionary[@"images"][0][@"image_file"][@"image_file"][@"thumb"][@"url"];
        if (thumbURL)
        {
            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
            UIImage *image = [UIImage imageWithData:imageData];
            cell.thumb.image = image;
        }
    }
    else {
        cell.thumb.image = [UIImage imageNamed:@"air-jordan-5-fear.png"];
    }

    return cell;
}

我的每个帖子都有文字字符串和图片。有没有办法加载文本,以便它立即出现,然后加载我的图像?或者是否有另一种方法来加快我的应用程序加载速度(可能首先加载某些帖子然后加载其余帖子 - 用户在向下滚动之前无法看到的那些)。

感谢。

2 个答案:

答案 0 :(得分:0)

你的问题是:

    if (thumbURL)
    {
        NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
        UIImage *image = [UIImage imageWithData:imageData];
        cell.thumb.image = image;
    }
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
    UIImage *image = [UIImage imageWithData:imageData];

您永远不应该在cellForItemAtIndexPath:获取数据。你应该只显示你已经拥有的东西。您的代码使得在下载缩略图之前不会返回任何单元格。您可以使用仪器中的 Time Profiler 来测量它。

我假设thumb是UIImageView。试试这个:

if (thumb) {
    [thumb setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"]];
}

此方法也包含在AFNetworking中,将下载图像,并在完成下载后在单元格中更新。 Documentation and other similar methods are here

答案 1 :(得分:0)

当你从服务器来时,你应该懒惰和异步地加载你的图像(不要阻止主线程)。 (AFNetworking已经在UIImageView上有缓存类别方法。(查看this了解更多信息)

    if (thumbURL)
    {
        [cell.thumb setImageWithURL:[NSURL URLWithString:thumbURL] placeholderImage:[UIImage imageNamed:@"air-jordan-5-fear.png"]];
    }

编辑 -

确保将 UIKit + AFNetworking 文件夹提取到项目中,并将#import "UIKit+AFNetworking.h"提取到.m文件中。可以找到下载完整AFNetworking的链接here以及特定于此问题的文档here