2012-11-04 16:50:23 +08:00
|
|
|
|
|
2009-09-21 22:03:45 +08:00
|
|
|
|
Web Image
|
|
|
|
|
=========
|
2009-09-20 02:45:42 +08:00
|
|
|
|
|
2009-09-23 09:05:40 +08:00
|
|
|
|
This library provides a category for UIImageVIew with support for remote images coming from the web.
|
2009-09-20 02:45:42 +08:00
|
|
|
|
|
2009-09-20 03:14:40 +08:00
|
|
|
|
It provides:
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-24 05:22:48 +08:00
|
|
|
|
- An UIImageView category adding web image and cache management to the Cocoa Touch framework
|
2010-06-09 10:09:18 +08:00
|
|
|
|
- An asynchronous image downloader
|
2009-09-24 05:22:48 +08:00
|
|
|
|
- An asynchronous memory + disk image caching with automatic cache expiration handling
|
2012-11-04 16:50:23 +08:00
|
|
|
|
- A background image decompression
|
2011-10-20 21:03:19 +08:00
|
|
|
|
- A guarantee that the same URL won't be downloaded several times
|
|
|
|
|
- A guarantee that bogus URLs won't be retried again and again
|
2012-11-04 16:50:23 +08:00
|
|
|
|
- A guarantee that main thread will never be blocked
|
2009-09-24 05:22:48 +08:00
|
|
|
|
- Performances!
|
2012-11-04 16:50:23 +08:00
|
|
|
|
- Use GCD and ARC
|
|
|
|
|
|
|
|
|
|
NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 1.0 and requires iOS 5.0
|
|
|
|
|
minimum. If you need iOS < 5.0 support, please use the last 2.0 version.
|
2009-09-20 03:14:40 +08:00
|
|
|
|
|
2012-11-04 23:17:01 +08:00
|
|
|
|
[How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F)
|
|
|
|
|
|
2012-11-04 22:17:32 +08:00
|
|
|
|
Who Use It
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
|
|
Find out [who use SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Use-SDWebImage) and add your app to the list.
|
|
|
|
|
|
|
|
|
|
How To Use
|
|
|
|
|
----------
|
2009-09-20 03:14:40 +08:00
|
|
|
|
|
2012-05-10 20:16:10 +08:00
|
|
|
|
API documentation is available at [http://hackemist.com/SDWebImage/doc/](http://hackemist.com/SDWebImage/doc/)
|
|
|
|
|
|
2009-09-23 09:05:40 +08:00
|
|
|
|
### Using UIImageView+WebCache category with UITableView
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-24 05:22:48 +08:00
|
|
|
|
Just #import the UIImageView+WebCache.h header, and call the setImageWithURL:placeholderImage:
|
|
|
|
|
method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be
|
2010-06-09 10:09:18 +08:00
|
|
|
|
handled for you, from async downloads to caching management.
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
2012-05-10 06:30:48 +08:00
|
|
|
|
#import <SDWebImage/UIImageView+WebCache.h>
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
...
|
2009-09-23 09:05:40 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
|
|
|
{
|
|
|
|
|
static NSString *MyIdentifier = @"MyIdentifier";
|
2009-09-23 09:05:40 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
|
2009-09-23 09:05:40 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
if (cell == nil)
|
|
|
|
|
{
|
|
|
|
|
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
|
|
|
|
reuseIdentifier:MyIdentifier] autorelease];
|
|
|
|
|
}
|
2009-09-23 09:05:40 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
// Here we use the new provided setImageWithURL: method to load the web image
|
|
|
|
|
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
|
|
|
|
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
|
2009-09-23 09:05:40 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
cell.textLabel.text = @"My Text";
|
|
|
|
|
return cell;
|
|
|
|
|
}
|
|
|
|
|
```
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-03-11 03:15:06 +08:00
|
|
|
|
### Using blocks
|
|
|
|
|
|
2012-11-04 16:50:23 +08:00
|
|
|
|
With blocks, you can be notified about the image download progress and whenever the image retrival
|
|
|
|
|
has completed with success or not:
|
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
|
|
|
|
// Here we use the new provided setImageWithURL: method to load the web image
|
|
|
|
|
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
|
|
|
|
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
|
2012-11-04 16:50:23 +08:00
|
|
|
|
completed:^(UIImage *image, NSError *error, BOOL fromCache) {... completion code here ...}];
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```
|
2012-03-11 03:15:06 +08:00
|
|
|
|
|
|
|
|
|
Note: neither your success nor failure block will be call if your image request is canceled before completion.
|
|
|
|
|
|
2009-09-24 05:22:48 +08:00
|
|
|
|
### Using SDWebImageManager
|
|
|
|
|
|
|
|
|
|
The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the
|
2011-10-20 21:03:19 +08:00
|
|
|
|
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 a UIView (ie: with Cocoa).
|
2009-09-24 05:22:48 +08:00
|
|
|
|
|
|
|
|
|
Here is a simple example of how to use SDWebImageManager:
|
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
|
|
|
|
SDWebImageManager *manager = [SDWebImageManager sharedManager];
|
2012-05-10 20:07:38 +08:00
|
|
|
|
[manager downloadWithURL:imageURL
|
|
|
|
|
options:0
|
2012-11-04 16:50:23 +08:00
|
|
|
|
progress:^(NSUInteger receivedSize, long long expectedSize)
|
2012-05-10 20:07:38 +08:00
|
|
|
|
{
|
2012-11-04 16:50:23 +08:00
|
|
|
|
// progression tracking code
|
2012-05-10 20:07:38 +08:00
|
|
|
|
}
|
2012-11-04 16:50:23 +08:00
|
|
|
|
completed:^(UIImage *image, NSError *error, BOOL fromCache)
|
|
|
|
|
{
|
|
|
|
|
if (image)
|
|
|
|
|
{
|
|
|
|
|
// do something with image
|
|
|
|
|
}
|
|
|
|
|
}];
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```
|
2009-09-24 05:22:48 +08:00
|
|
|
|
|
|
|
|
|
### Using Asynchronous Image Downloader Independently
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-11-04 16:50:23 +08:00
|
|
|
|
It's also possible to use the async image downloader independently:
|
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
2012-11-04 16:50:23 +08:00
|
|
|
|
[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL
|
|
|
|
|
options:0
|
|
|
|
|
progress:^(NSUInteger receivedSize, long long expectedSize)
|
|
|
|
|
{
|
|
|
|
|
// progression tracking code
|
|
|
|
|
}
|
|
|
|
|
completed:^(UIImage *image, NSError *error, BOOL finished)
|
|
|
|
|
{
|
|
|
|
|
if (image && finished)
|
|
|
|
|
{
|
|
|
|
|
// do something with image
|
|
|
|
|
}
|
|
|
|
|
}];
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-24 05:22:48 +08:00
|
|
|
|
### Using Asynchronous Image Caching Independently
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-11-04 16:50:23 +08:00
|
|
|
|
It is also possible to use the aync based image cache store independently. SDImageCache
|
2009-09-21 22:03:45 +08:00
|
|
|
|
maintains a memory cache and an optional disk cache. Disk cache write operations are performed
|
|
|
|
|
asynchronous so it doesn't add unnecessary latency to the UI.
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-22 01:34:32 +08:00
|
|
|
|
The SDImageCache class provides a singleton instance for convenience but you can create your own
|
2011-10-20 21:03:19 +08:00
|
|
|
|
instance if you want to create separated cache namespace.
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-21 22:03:45 +08:00
|
|
|
|
To lookup the cache, you use the imageForKey: method. If the method returns nil, it means the cache
|
2011-10-20 21:03:19 +08:00
|
|
|
|
doesn't currently own the image. You are thus responsible for generating and caching it. The cache
|
2009-09-21 22:03:45 +08:00
|
|
|
|
key is an application unique identifier for the image to cache. It is generally the absolute URL of
|
|
|
|
|
the image.
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
2012-11-04 16:50:23 +08:00
|
|
|
|
SDImageCache *imageCache = [SDImageCache.alloc initWithNamespace:@"myNamespace"];
|
|
|
|
|
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image)
|
|
|
|
|
{
|
|
|
|
|
// image is not nil if image was found
|
|
|
|
|
}];
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
2009-09-22 01:34:32 +08:00
|
|
|
|
By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache.
|
2009-09-21 22:03:45 +08:00
|
|
|
|
You can prevent this from happening by calling the alternative method imageFromKey:fromDisk: with a
|
|
|
|
|
negative second argument.
|
2009-09-21 10:29:00 +08:00
|
|
|
|
|
|
|
|
|
To store an image into the cache, you use the storeImage:forKey: method:
|
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
|
|
|
|
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
|
|
|
|
|
```
|
2009-09-20 03:14:40 +08:00
|
|
|
|
|
2009-09-21 22:03:45 +08:00
|
|
|
|
By default, the image will be stored in memory cache as well as on disk cache (asynchronously). If
|
|
|
|
|
you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative
|
|
|
|
|
third argument.
|
2009-09-20 03:14:40 +08:00
|
|
|
|
|
2012-05-09 17:04:09 +08:00
|
|
|
|
### Using cache key filter
|
|
|
|
|
|
|
|
|
|
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 that
|
|
|
|
|
takes 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 from
|
|
|
|
|
the URL before to use it as a cache key:
|
|
|
|
|
|
2012-05-09 17:33:38 +08:00
|
|
|
|
```objective-c
|
|
|
|
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
|
|
|
{
|
2012-11-04 16:50:23 +08:00
|
|
|
|
SDWebImageManager.sharedManager.cacheKeyFilter:^(NSURL *url)
|
2012-05-09 17:04:09 +08:00
|
|
|
|
{
|
2012-05-09 17:33:38 +08:00
|
|
|
|
url = [[[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path] autorelease];
|
|
|
|
|
return [url absoluteString];
|
2012-11-04 16:50:23 +08:00
|
|
|
|
};
|
2012-05-09 17:33:38 +08:00
|
|
|
|
|
|
|
|
|
// Your app init code...
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
```
|
2012-05-09 17:04:09 +08:00
|
|
|
|
|
|
|
|
|
|
2012-03-22 17:33:07 +08:00
|
|
|
|
Common Problems
|
|
|
|
|
---------------
|
|
|
|
|
|
|
|
|
|
### Using dynamic image size with UITableViewCell
|
|
|
|
|
|
|
|
|
|
UITableView determins the size of the image by the first image set for a cell. If your remote images
|
|
|
|
|
don't have the same size as your placeholder image, you may experience strange anamorphic scaling issue.
|
|
|
|
|
The following article gives a way to workaround this issue:
|
|
|
|
|
|
|
|
|
|
[http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/](http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/)
|
|
|
|
|
|
2012-03-11 00:40:02 +08:00
|
|
|
|
|
2012-01-28 06:41:43 +08:00
|
|
|
|
Installation
|
|
|
|
|
------------
|
|
|
|
|
|
2012-04-13 06:09:47 +08:00
|
|
|
|
There are two ways to use this in your project: copy all the files into your project, or import the project as a static library.
|
2012-01-28 06:41:43 +08:00
|
|
|
|
|
2012-05-10 06:30:48 +08:00
|
|
|
|
### Add the SDWebImage project to your project
|
2012-01-28 06:41:43 +08:00
|
|
|
|
|
2012-10-19 19:34:17 +08:00
|
|
|
|
- Download and unzip the last version of the framework from the [download page](https://github.com/rs/SDWebImage/downloads)
|
|
|
|
|
- Right-click on the project navigator and select "Add Files to "Your Project":
|
|
|
|
|
- In the dialog, select SDWebImage.framework:
|
|
|
|
|
- Check the "Copy items into destination group's folder (if needed)" checkbox
|
2012-01-28 06:41:43 +08:00
|
|
|
|
|
2012-10-20 10:06:04 +08:00
|
|
|
|
### Add dependencies
|
2012-01-28 06:41:43 +08:00
|
|
|
|
|
2012-10-19 19:34:17 +08:00
|
|
|
|
- In you application project app’s target settings, find the "Build Phases" section and open the "Link Binary With Libraries" block:
|
|
|
|
|
- Click the "+" button again and select the "ImageIO.framework", this is needed by the progressive download feature:
|
2012-05-10 06:30:48 +08:00
|
|
|
|
|
2012-10-20 10:06:04 +08:00
|
|
|
|
### Add Linker Flag
|
|
|
|
|
|
|
|
|
|
Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag:
|
|
|
|
|
|
|
|
|
|
![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg)
|
|
|
|
|
|
2012-05-10 06:30:48 +08:00
|
|
|
|
### Import headers in your source files
|
|
|
|
|
|
2012-09-02 18:40:21 +08:00
|
|
|
|
In the source files where you need to use the library, import the header file:
|
2012-05-10 06:30:48 +08:00
|
|
|
|
|
|
|
|
|
```objective-c
|
|
|
|
|
#import <SDWebImage/UIImageView+WebCache.h>
|
|
|
|
|
```
|
2012-01-28 06:41:43 +08:00
|
|
|
|
|
2012-04-26 06:05:43 +08:00
|
|
|
|
### Build Project
|
2012-05-10 06:30:48 +08:00
|
|
|
|
|
|
|
|
|
At this point your workspace should build without error. If you are having problem, post to the Issue and the
|
|
|
|
|
community can help you solve it.
|
2012-04-26 06:05:43 +08:00
|
|
|
|
|
2009-09-20 03:14:40 +08:00
|
|
|
|
Future Enhancements
|
|
|
|
|
-------------------
|
|
|
|
|
|
2012-11-04 23:17:01 +08:00
|
|
|
|
- LRU memory cache cleanup instead of reset on memory warning
|
2012-11-05 00:47:56 +08:00
|
|
|
|
|
|
|
|
|
## Licenses
|
|
|
|
|
|
2012-11-05 19:20:18 +08:00
|
|
|
|
All source code is licensed under the [MIT License](https://raw.github.com/rs/SDWebImage/master/LICENSE).
|