No answer seems to handle this completely, so, to have more info...
First of all, you should include the AFNetworking category for UIImageView
:
#import "UIImageView+AFNetworking.h"
If you're using CocoaPods, this line should be:
#import <AFNetworking/UIImageView+AFNetworking.h>
After that, you should have at least one UIImageView
(I'm going to assume you have an IBOutlet
connected):
@property (weak, nonatomic) IBOutlet UIImageView *myImageView;
Then you can load your image in code:
// Define a placeholder image that will be shown while the remote image
// loads. If you don't want a placeholder image, just set it to nil.
// Note that this placeholder image is local (it should be in your
// asset files/collection).
UIImage *myPlaceholderImage = nil; // Or use [UIImage imageNamed:@"..."];
// First, cancel other tasks that could be downloading images.
// If you only do this once, this is probably not needed, but it's not harmful to
// always have it before loading an image with setImageWithURL: and derivatives.
[self.myImageView cancelImageDownloadTask];
// Set up a NSURL for the image you want.
// I'm gonna use this wonderful owl: https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg
NSURL *imageURL = [NSURL URLWithString:@"https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg"];
// Check if the URL is valid
if ( imageURL ) {
// The URL is valid so we'll use it to load the image asynchronously.
// Pass the placeholder image that will be shown while the
// remote image loads.
[self.myImageView setImageWithURL:imageURL
placeholderImage:myPlaceholderImage];
}
else {
// The imageURL is invalid, just show the placeholder image.
dispatch_async(dispatch_get_main_queue(), ^{
self.myImageView.image = myPlaceholderImage;
});
}
If, for any reason, you need to do something to the remote image before delivering it to the UIImageView
, you can use the setImageWithURLRequest:placeholderImage:success:failure:
method. I'm going to transform the received UIImage
to another UIImage
in template mode, so it will be colored with the tintColor
of the UIImageView
(of course, this image of an owl will not look good, this should be a plain icon with transparency):
UIImage *placeholderImage = nil;
NSURL *imageURL = [NSURL URLWithString:@"https://www.smashingmagazine.com/wp-content/uploads/2015/06/10-dithering-opt.jpg"];
if ( imageURL ) {
// Check NSURLRequestCachePolicy enumeration for other values.
// 60 seconds in timeoutInterval is the default for iOS.
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageURL
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0f];
[self.myImageView cancelImageDownloadTask];
// We'll keep a weak reference to our UIImageView so it won't have
// any possibility of being retained by our success/failure blocks.
__weak typeof(self.myImageView) weakImageView = self.myImageView;
dispatch_async(dispatch_get_main_queue(), ^{
[self.myImageView setImageWithURLRequest:imageRequest
placeholderImage:placeholderImage
success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
UIImage *tintedImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
weakImageView.image = tintedImage;
}
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
weakImageView.image = placeholderImage;
}];
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
self.myImageView.image = placeholderImage;
});
}
And yes, I know this is an old question, but this should serve as reference.