...
|
...
|
@@ -10,7 +10,11 @@ |
|
|
#import "SDWebImageDownloaderOperation.h"
|
|
|
#import <ImageIO/ImageIO.h>
|
|
|
|
|
|
#define AliCloudHttpDNS
|
|
|
|
|
|
#ifdef AliCloudHttpDNS
|
|
|
#import <AlicloudHttpDNS/AlicloudHttpDNS.h>
|
|
|
#endif
|
|
|
|
|
|
static NSString *const kProgressCallbackKey = @"progress";
|
|
|
static NSString *const kCompletedCallbackKey = @"completed";
|
...
|
...
|
@@ -82,7 +86,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; |
|
|
#if DEBUG
|
|
|
_enableHttpDNS = YES;
|
|
|
#else
|
|
|
_enableHttpDNS = [[[NSUserDefaults standardUserDefaults] stringForKey:@"kUserConfigHttpDNS"] isEqualToString:@"2a90dfa0f37b92aaebf369e9a4d38ba4"];
|
|
|
_enableHttpDNS = YES;//[[[NSUserDefaults standardUserDefaults] stringForKey:@"kUserConfigHttpDNS"] isEqualToString:@"2a90dfa0f37b92aaebf369e9a4d38ba4"];
|
|
|
#endif
|
|
|
}
|
|
|
return self;
|
...
|
...
|
@@ -125,100 +129,101 @@ static NSString *const kCompletedCallbackKey = @"completed"; |
|
|
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
|
|
|
__block SDWebImageDownloaderOperation *operation;
|
|
|
__weak __typeof(self)wself = self;
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
BOOL useAliDNS = NO;
|
|
|
NSString *imageURLHost = url.host;//获取图片URL的host
|
|
|
NSURL *newURL = url;
|
|
|
if (wself.enableHttpDNS && (imageURLHost.length > 0)) {
|
|
|
NSArray *ips = [[HttpDnsService sharedInstance] getIpsByHostAsync:imageURLHost];//同步请求ip地址列表
|
|
|
if ([ips isKindOfClass:[NSArray class]] && [ips respondsToSelector:@selector(count)] && ips.count > 0) {
|
|
|
NSString *ipAdress = [ips objectAtIndex:0];
|
|
|
NSString *urlString = [url absoluteString];
|
|
|
NSRange hostRange = [urlString rangeOfString:imageURLHost];
|
|
|
if ((NSNotFound != hostRange.location) && (ipAdress.length > 0)) {
|
|
|
useAliDNS = YES;
|
|
|
NSString *convertedURLString = [urlString stringByReplacingCharactersInRange:hostRange withString:ipAdress];//host转换之后的urlstring
|
|
|
newURL = [NSURL URLWithString:convertedURLString]; //替换原始url为转换后的值
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
[wself addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{
|
|
|
NSTimeInterval timeoutInterval = wself.downloadTimeout;
|
|
|
if (timeoutInterval == 0.0) {
|
|
|
timeoutInterval = 15.0;
|
|
|
BOOL useAliDNS = NO;
|
|
|
NSString *imageURLHost = url.host;//获取图片URL的host
|
|
|
NSURL *newURL = url;
|
|
|
#ifdef AliCloudHttpDNS
|
|
|
if (self.enableHttpDNS && (imageURLHost.length > 0)) {
|
|
|
NSArray *ips = [[HttpDnsService sharedInstance] getIpsByHostAsync:imageURLHost];//同步请求ip地址列表
|
|
|
if ([ips isKindOfClass:[NSArray class]] && [ips respondsToSelector:@selector(count)] && ips.count > 0) {
|
|
|
NSString *ipAdress = [ips objectAtIndex:0];
|
|
|
NSString *urlString = [url absoluteString];
|
|
|
NSRange hostRange = [urlString rangeOfString:imageURLHost];
|
|
|
if ((NSNotFound != hostRange.location) && (ipAdress.length > 0)) {
|
|
|
useAliDNS = YES;
|
|
|
NSString *convertedURLString = [urlString stringByReplacingCharactersInRange:hostRange withString:ipAdress];//host转换之后的urlstring
|
|
|
newURL = [NSURL URLWithString:convertedURLString]; //替换原始url为转换后的值
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
[self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{
|
|
|
NSTimeInterval timeoutInterval = wself.downloadTimeout;
|
|
|
if (timeoutInterval == 0.0) {
|
|
|
timeoutInterval = 15.0;
|
|
|
}
|
|
|
|
|
|
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise
|
|
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:newURL cachePolicy:(options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeoutInterval];
|
|
|
request.HTTPShouldHandleCookies = (options & SDWebImageDownloaderHandleCookies);
|
|
|
request.HTTPShouldUsePipelining = YES;
|
|
|
if (wself.headersFilter) {
|
|
|
request.allHTTPHeaderFields = wself.headersFilter(newURL, [wself.HTTPHeaders copy]);
|
|
|
}
|
|
|
else {
|
|
|
request.allHTTPHeaderFields = wself.HTTPHeaders;
|
|
|
}
|
|
|
if (useAliDNS) { //如果使用了DNS功能,要设置httpheader的host字段的值,否则请求失败
|
|
|
[request setValue:imageURLHost forHTTPHeaderField:@"Host"];
|
|
|
}
|
|
|
operation = [[wself.operationClass alloc] initWithRequest:request
|
|
|
options:options
|
|
|
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
__block NSArray *callbacksForURL;
|
|
|
dispatch_sync(sself.barrierQueue, ^{
|
|
|
callbacksForURL = [sself.URLCallbacks[url] copy];
|
|
|
});
|
|
|
for (NSDictionary *callbacks in callbacksForURL) {
|
|
|
SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey];
|
|
|
if (callback) callback(receivedSize, expectedSize);
|
|
|
}
|
|
|
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise
|
|
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:newURL cachePolicy:(options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeoutInterval];
|
|
|
request.HTTPShouldHandleCookies = (options & SDWebImageDownloaderHandleCookies);
|
|
|
request.HTTPShouldUsePipelining = YES;
|
|
|
if (wself.headersFilter) {
|
|
|
request.allHTTPHeaderFields = wself.headersFilter(newURL, [wself.HTTPHeaders copy]);
|
|
|
}
|
|
|
else {
|
|
|
request.allHTTPHeaderFields = wself.HTTPHeaders;
|
|
|
}
|
|
|
if (useAliDNS) { //如果使用了DNS功能,要设置httpheader的host字段的值,否则请求失败
|
|
|
[request setValue:imageURLHost forHTTPHeaderField:@"Host"];
|
|
|
}
|
|
|
operation = [[wself.operationClass alloc] initWithRequest:request
|
|
|
options:options
|
|
|
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
__block NSArray *callbacksForURL;
|
|
|
dispatch_sync(sself.barrierQueue, ^{
|
|
|
callbacksForURL = [sself.URLCallbacks[url] copy];
|
|
|
});
|
|
|
for (NSDictionary *callbacks in callbacksForURL) {
|
|
|
SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey];
|
|
|
if (callback) callback(receivedSize, expectedSize);
|
|
|
}
|
|
|
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
|
|
|
// NSLog(@"download image completed:url == %@,\nimage = %@",url,image);
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
__block NSArray *callbacksForURL;
|
|
|
dispatch_barrier_sync(sself.barrierQueue, ^{
|
|
|
callbacksForURL = [sself.URLCallbacks[url] copy];
|
|
|
if (finished) {
|
|
|
[sself.URLCallbacks removeObjectForKey:url];
|
|
|
}
|
|
|
});
|
|
|
for (NSDictionary *callbacks in callbacksForURL) {
|
|
|
SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey];
|
|
|
if (callback) callback(image, data, error, finished);
|
|
|
}
|
|
|
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
|
|
|
// NSLog(@"download image completed:url == %@,\nimage = %@",url,image);
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
__block NSArray *callbacksForURL;
|
|
|
dispatch_barrier_sync(sself.barrierQueue, ^{
|
|
|
callbacksForURL = [sself.URLCallbacks[url] copy];
|
|
|
if (finished) {
|
|
|
[sself.URLCallbacks removeObjectForKey:url];
|
|
|
}
|
|
|
});
|
|
|
for (NSDictionary *callbacks in callbacksForURL) {
|
|
|
SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey];
|
|
|
if (callback) callback(image, data, error, finished);
|
|
|
}
|
|
|
cancelled:^{
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
dispatch_barrier_async(sself.barrierQueue, ^{
|
|
|
[sself.URLCallbacks removeObjectForKey:url];
|
|
|
});
|
|
|
}];
|
|
|
operation.shouldDecompressImages = wself.shouldDecompressImages;
|
|
|
|
|
|
if (wself.username && wself.password) {
|
|
|
operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession];
|
|
|
}
|
|
|
|
|
|
if (options & SDWebImageDownloaderHighPriority) {
|
|
|
operation.queuePriority = NSOperationQueuePriorityHigh;
|
|
|
} else if (options & SDWebImageDownloaderLowPriority) {
|
|
|
operation.queuePriority = NSOperationQueuePriorityLow;
|
|
|
}
|
|
|
}
|
|
|
cancelled:^{
|
|
|
SDWebImageDownloader *sself = wself;
|
|
|
if (!sself) return;
|
|
|
dispatch_barrier_async(sself.barrierQueue, ^{
|
|
|
[sself.URLCallbacks removeObjectForKey:url];
|
|
|
});
|
|
|
}];
|
|
|
operation.shouldDecompressImages = wself.shouldDecompressImages;
|
|
|
|
|
|
if (wself.username && wself.password) {
|
|
|
operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession];
|
|
|
}
|
|
|
|
|
|
if (options & SDWebImageDownloaderHighPriority) {
|
|
|
operation.queuePriority = NSOperationQueuePriorityHigh;
|
|
|
} else if (options & SDWebImageDownloaderLowPriority) {
|
|
|
operation.queuePriority = NSOperationQueuePriorityLow;
|
|
|
}
|
|
|
|
|
|
[wself.downloadQueue addOperation:operation];
|
|
|
if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {
|
|
|
// Emulate LIFO execution order by systematically adding new operations as last operation's dependency
|
|
|
[wself.lastAddedOperation addDependency:operation];
|
|
|
wself.lastAddedOperation = operation;
|
|
|
}
|
|
|
}];
|
|
|
});
|
|
|
[wself.downloadQueue addOperation:operation];
|
|
|
if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {
|
|
|
// Emulate LIFO execution order by systematically adding new operations as last operation's dependency
|
|
|
[wself.lastAddedOperation addDependency:operation];
|
|
|
wself.lastAddedOperation = operation;
|
|
|
}
|
|
|
}];
|
|
|
|
|
|
return operation;
|
|
|
}
|
...
|
...
|
|