Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Quick and dirty UIImageView with networking
//
// UIImage+Network.h
// Fireside
//
// Created by Soroush Khanlou on 8/25/12.
//
//
#import <UIKit/UIKit.h>
@interface UIImageView(Network)
@property (nonatomic, copy) NSURL *imageURL;
- (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key;
@end
//
// UIImageView+Network.m
//
// Created by Soroush Khanlou on 8/25/12.
//
//
#import "UIImageView+Network.h"
#import "FTWCache.h"
#import <objc/runtime.h>
static char URL_KEY;
@implementation UIImageView(Network)
@dynamic imageURL;
- (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key {
self.imageURL = url;
self.image = placeholder;
NSData *cachedData = [FTWCache objectForKey:key];
if (cachedData) {
self.imageURL = nil;
self.image = [UIImage imageWithData:cachedData];
return;
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *imageFromData = [UIImage imageWithData:data];
[FTWCache setObject:data forKey:key];
if (imageFromData) {
if ([self.imageURL.absoluteString isEqualToString:url.absoluteString]) {
dispatch_sync(dispatch_get_main_queue(), ^{
self.image = imageFromData;
});
} else {
// NSLog(@"urls are not the same, bailing out!");
}
}
self.imageURL = nil;
});
}
- (void) setImageURL:(NSURL *)newImageURL {
objc_setAssociatedObject(self, &URL_KEY, newImageURL, OBJC_ASSOCIATION_COPY);
}
- (NSURL*) imageURL {
return objc_getAssociatedObject(self, &URL_KEY);
}
@end
@marmor7
Copy link

marmor7 commented Apr 9, 2013

You're only caching in downloaded NSData, but you never use that cached objects to save unneeded downloads.

Try adding this code before the dispatch code:

NSData *cachedData = [FTWCache objectForKey:key];
if (cachedData) {   
    self.imageURL   = nil;
    self.image      = [UIImage imageWithData:cachedData];
} else {
    dispatch ...
}

@khanlou
Copy link
Author

khanlou commented Jul 2, 2013

Ah, good call, my bad. Updated.

@shashankshandilya
Copy link

How to call your code from outside class

@glenrynaldy
Copy link

@shashankshandilya

just call it from your targeted UIImageView
ex:
[cell.imageView loadImageFromURL:(NSURL_)url placeholderImage:(UIImage_)placeholder cachingKey:(NSString*)key ];

@mweidinger
Copy link

I use your image loading and the loading and image replace things are very good - big thx for that.
My problem is that scrolling in uicollectionview is not that smooth. Is there any performance issue with my cellForItemAtIndexPath-Method?

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

VideoCell *cell = (VideoCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"VideoCell" forIndexPath:indexPath];

VideoOnDemandMovie *movie = (VideoOnDemandMovie *)[_displayedMoviesArray objectAtIndex:indexPath.row];

[cell.myImageView loadImageFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",_imagePathSystemValue,movie.image]] placeholderImage:[UIImage imageNamed:@"fallback_movie.png"] cachingKey:movie.movieId];    
    return cell;
}

@mayurssoni2456
Copy link

@khanlou Thanks for sharing. Is there any fix for smooth scrolling in UICollectionView. There is little stuck while scrolling.
@mweidinger

@paulinesme
Copy link

I just googling around and see you code looks pretty good 👍

But I'm just doubt is it the problem if some of my UITableViewCell will going to load the same source of image at the same time right before the first one have been loaded and cache.

It would be nice if you can help clarify what will happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment