Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork6k
How to use
Just import theUIImageView+WebCache.h header, and call thesd_setImageWithURL:placeholderImage:method from thetableView:cellForRowAtIndexPath:UITableViewDataSource method. Everything will behandled for you, from async downloads to caching management.
#import<SDWebImage/UIImageView+WebCache.h>...- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {staticNSString *MyIdentifier =@"MyIdentifier"; UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:MyIdentifier];if (cell ==nil) { cell = [[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:MyIdentifier]autorelease]; }// Here we use the new provided sd_setImageWithURL: method to load the web image [cell.imageViewsd_setImageWithURL:[NSURLURLWithString:@"https://www.domain.com/path/to/image.jpg"]placeholderImage:[UIImageimageNamed:@"placeholder"]]; cell.textLabel.text =@"Hello World!";return cell;}
import SDWebImage...func tableView(_ tableView:UITableView, cellForRowAt indexPath:IndexPath)->UITableViewCell{letcell= tableView.dequeueReusableCell(withIdentifier:"Cell", forIndexPath: indexPath)as!UITableViewCell // Here we use the new provided sd_setImageWithURL: method to load the web image cell.imageView?.sd_setImage( with:URL(string:"https://www.domain.com/path/to/image.jpg")!, placeholderImage:UIImage(named:"placeholder")) cell.textLabel?.text="Hello world!"return cell}
With blocks, you can be notified about the image download progress and whenever the image retrieval has completed with success or not:
// Here we use the new provided sd_setImageWithURL: method to load the web image[cell.imageViewsd_setImageWithURL:[NSURLURLWithString:@"http://www.domain.com/path/to/image.jpg"]placeholderImage:[UIImageimageNamed:@"placeholder.png"]completed:^(UIImage *image,NSError *error, SDImageCacheType cacheType,NSURL *imageURL) { ... completion code here ... }];
cell.imageView?.sd_setImage( with:URL(string:"https://website.com/image/img123.jpg")!, placeholderImage:UIImage(named:"placeholderImage"), completed:{[weak self](image:UIImage?, error:Error?, cacheType:SDImageCacheType, url:URL?)in // ... completion code here ...})
Note: neither your success nor failure block will be called if your image request is canceled before completion.
TheSDWebImageManager is the class behind theUIImageView(WebCache) category. It ties the asynchronous downloader with the image cache store. You can use this class directly to benefit from web image downloading with caching in another context than aUIView (ie: with Cocoa).
Note: When the image is from memory cache, it will not contains anyNSData by default. However, if you need image data, you can passSDWebImageQueryDataWhenInMemory in options arg.
Here is a simple example of how to useSDWebImageManager:
SDWebImageManager *manager = [SDWebImageManagersharedManager];[managerloadImageWithURL:imageURLoptions:0progress:^(NSInteger receivedSize,NSInteger expectedSize) {// progression tracking code }completed:^(UIImage *image,NSError *error, SDImageCacheType cacheType,BOOL finished,NSURL *imageURL) {if (image) {// do something with image } }];
SDWebImageManager.shared.loadImage( with: URL(string: imageUrl), options: [.highPriority, .progressiveLoad], progress: { (receivedSize, expectedSize, url) in //Progress tracking code }, completed: { [weak self] (image, data, error, cacheType, finished, url) in guard let self = self else { return } guard error == nil else { return } if let image = image { /// do something with image /// eg. self.imageView.image = image } })SDWebImageManager is used for image query in cache and network. However, sometimes, you don't want to consume the queried image right now, but want to do a prefetching in advance. Here we haveSDWebImagePrefetcher.
SDWebImagePrefetcher can prefetch multiple url list with array. Each url list will bind to single token (which allows cancel on current url list). Don't worry about duplicated urls, the prefetcher is backed bySDWebImageManager, it will check cache firstly, only image not in cache will go through network download.
- Objective-C
NSArray<NSURL> *imageURLs;[SDWebImagePrefetcher.sharedImagePrefetcherprefetchURLs:imageURLsprogress:^(NSUInteger noOfFinishedUrls,NSUInteger noOfTotalUrls) {// prefetch progress changed}completed:^(NSUInteger noOfFinishedUrls,NSUInteger noOfSkippedUrls) {// all provided urls prefetched}];
- Swift
letimageURLs:[URL]SDWebImagePrefetcher.shared.prefetchURLs(imageURLs, progress:{(noOfFinishedUrls, noOfTotalUrls)in // prefetch progress changed}){(noOfFinishedUrls, noOfSkippedUrls)in // all provided urls prefetched}
SDWebImagePrefetcher has a shared instance for convenience, but remember it's light-weight. If you need extra configuration for image urls which share the same options and context, create a new object instead.
SDWebImagePrefetcher supports delegate methods to observe the fetch count changes as well. You can use that for detailed fetching status check.
Notes:
- When you want to prefetch animated image format to used with
SDAnimatedImageView, make sure you pass the.customImageClasscontext option, or we will still use the UIImage animation, which is less performant. - Before 5.0, the cancel method on prefetcher will cancel all previous requests. Which means each prefetcher can prefetch one url lists at the same time. But 5.0 change that to use the
SDWebImagePrefetchTokeninstead. You can just current url list, without effect all other fetching url list.
It's also possible to use the async image downloader independently:
SDWebImageDownloader *downloader = [SDWebImageDownloadersharedDownloader];[downloaderdownloadImageWithURL:imageURLoptions:0progress:^(NSInteger receivedSize,NSInteger expectedSize) {// progression tracking code }completed:^(UIImage *image,NSData *data,NSError *error,BOOL finished) {if (image && finished) {// do something with image } }];
SDWebImageDownloader.shared.downloadImage( with:URL(string: imageUrl), options:[.highPriority], progress:{(receivedSize, expectedSize, url)in /// progress tracking code}, completed:{[weak self](image, data, error, finished)iniflet image= image, finished{ /// do something with image /// eg. self?.imageView.image = image}})
It is also possible to use the async based image cache store independently. SDImageCachemaintains a memory cache and an optional disk cache. Disk cache write operations are performedasynchronous so it doesn't add unnecessary latency to the UI.
The SDImageCache class provides a singleton instance for convenience but you can create your owninstance if you want to create separated cache namespace.
To lookup the cache, you use thequeryDiskCacheForKey:done: method. If the method returns nil, it means the cachedoesn't currently own the image. You are thus responsible for generating and caching it. The cachekey is an application unique identifier for the image to cache. It is generally the absolute URL ofthe image.
SDImageCache *imageCache = [[SDImageCachealloc]initWithNamespace:@"myNamespace"];[imageCachequeryDiskCacheForKey:myCacheKeydone:^(UIImage *image) {// image is not nil if image was found}];
By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache.You can prevent this from happening by calling the alternative methodimageFromMemoryCacheForKey:.
To store an image into the cache, you use the storeImage:forKey:completion: method:
[[SDImageCachesharedImageCache]storeImage:myImageforKey:myCacheKeycompletion:^{// image stored}];
By default, the image will be stored in memory cache as well as on disk cache (asynchronously). Ifyou want only the memory cache, use the alternative method storeImage:forKey:toDisk:completion: with a negativethird argument.
Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter thattakes the NSURL as input, and output a cache key NSString.
The following example sets a filter in the application delegate that will remove any query-string fromthe URL before to use it as a cache key:
- Objective-C
SDWebImageCacheKeyFilter *cacheKeyFilter = [SDWebImageCacheKeyFiltercacheKeyFilterWithBlock:^NSString *_Nullable(NSURL * _Nonnull url) {NSURLComponents *urlComponents = [[NSURLComponentsalloc]initWithURL:urlresolvingAgainstBaseURL:NO]; urlComponents.query =nil;return urlComponents.URL.absoluteString;}];SDWebImageManager.sharedManager.cacheKeyFilter = cacheKeyFilter;
- Swift
letcacheKeyFilter=SDWebImageCacheKeyFilter{(url)->String?invarurlComponents=URLComponents(url: url, resolvingAgainstBaseURL:false) urlComponents?.query=nilreturn urlComponents?.url?.absoluteString}SDWebImageManager.shared.cacheKeyFilter= cacheKeyFilter
Note: In 4.x version, the cache key filter is actual a block. However, in 5.x we wrap the block into a objectSDWebImageCacheKeyFilter. This is because we support the cache key filter as context option. However, Swift is hard to use aNSDictionary<NSString *, id> (bridging as[String: Any]) which contains a Objective-C block object.
Sometime, you want to specify some custom HTTP Header, or modify the download request just beyond the default configuration from SDWebImage. You can use the request modifier, to modify and return a newNSHTTPRequest object for the actual network request.
The following example sets a custom HTTP Header for specify URL on the shared downloader level. You can also use the request modifier as context option to make it work for individual image request level.
- Objective-C
SDWebImageDownloaderRequestModifier *requestModifier = [SDWebImageDownloaderRequestModifierrequestModifierWithBlock:^NSURLRequest *_Nullable(NSURLRequest * _Nonnull request) {if ([request.URL.hostisEqualToString:@"foo"]) {NSMutableURLRequest *mutableRequest = [requestmutableCopy]; [mutableRequestsetValue:@"foo=bar"forHTTPHeaderField:@"Cookie"];return [mutableRequestcopy]; }return request;}];SDWebImageDownloader.sharedDownloader.requestModifier = requestModifier;
- Swift
letrequestModifier=SDWebImageDownloaderRequestModifier{(request)->URLRequest?inif(request.url?.host=="foo"){varmutableRequest= request mutableRequest.setValue("foo=bar", forHTTPHeaderField:"Cookie")return mutableRequest}return request}SDWebImageDownloader.shared.requestModifier= requestModifier
Note: For some special image format like WebP/APNG, image servers may prefer client to send HTTP Accept header. Check wiki here:Coder Accept MIME Type. You can also use the request modifier feature for the same configuration.
Note: Though this feature is introduced in 5.x, in early 4.x version, you can use the Headers Filter to specify custom HTTP Headers. However, you can not custom any other properties insideNSURLRequest likeHTTPBody,cachePolicy, etc.
Like request modifier, SDWebImage provide the response modifier for HTTP response. You can modify the HTTP header, status code if you want to mock the data, or provide custom process logic.
- Objective-C
SDWebImageDownloaderResponseModifier *responseModifier = [SDWebImageDownloaderResponseModifierresponseModifierWithBlock:^NSURLResponse *_Nullable(NSURLResponse * _Nonnull response) {if ([response.URL.hostisEqualToString:@"foo"]) {NSMutableDictionary *mutableHeaderFields = [((NSHTTPURLResponse *)response).allHeaderFieldsmutableCopy]; mutableHeaderFields[@"Foo"] =@"Bar";NSHTTPURLResponse *modifiedResponse = [[NSHTTPURLResponsealloc]initWithURL:response.URLstatusCode:404HTTPVersion:nilheaderFields:[mutableHeaderFieldscopy]];return [modifiedResponsecopy]; }return response;}];SDWebImageDownloader.sharedDownloader.responseModifier = responseModifier;
- Swift
letresponseModifier=SDWebImageDownloaderResponseModifier{(response)->URLResponse?inif(response.url?.host=="foo"){varmutableHeaderFields=(responseas!HTTPURLResponse).allHeaderFieldsas?[String:String]mutableHeaderFields?["Foo"]="Bar"letmodifiedResponse=HTTPURLResponse(url: response.url!, statusCode:404, httpVersion:nil, headerFields: mutableHeaderFields)return modifiedResponse}return response};SDWebImageDownloader.shared.responseModifier= responseModifier
SDWebImage provide an easy and extensible API for image loading indicator. Which will show or animate during image loading from network. All you need to do is to setup the indicator before your image loading start.
Objective-C:
imageView1.sd_imageIndicator = SDWebImageActivityIndicator.grayIndicator;imageView2.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
Swift:
imageView1.sd_imageIndicator=SDWebImageActivityIndicator.grayimageView2.sd_imageIndicator=SDWebImageProgressIndicator.`default`
Then all thing done. Just callsd_setImageWithURL: to start load image, and you'll see the indicator showing during network request and stop automatically after loading finished.
We provide two built-in indicator type, the Activity Indicator and Progress Indicator, for both iOS/tvOS/macOS support. However, all indicator use a protocolSDWebImageIndicator to build, so it allows you to customize and provide your own loading view and start animate. CheckSDWebImageIndicator protocol for all the methods you need to implement.