Merge pull request #2256 from dreampiggy/feature_custom_loader

Feature custom image loader - Supports loader protocol
This commit is contained in:
Bogdan Poplauschi 2018-04-19 10:07:06 +03:00 committed by GitHub
commit 09cb3ec083
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 641 additions and 139 deletions

View File

@ -56,8 +56,10 @@
// HTTP NTLM auth example // HTTP NTLM auth example
// Add your NTLM image url to the array below and replace the credentials // Add your NTLM image url to the array below and replace the credentials
[SDWebImageManager sharedManager].imageDownloader.config.username = @"httpwatch"; [SDWebImageDownloader sharedDownloader].config.username = @"httpwatch";
[SDWebImageManager sharedManager].imageDownloader.config.password = @"httpwatch01"; [SDWebImageDownloader sharedDownloader].config.password = @"httpwatch01";
[[SDWebImageDownloader sharedDownloader] setValue:@"SDWebImage Demo" forHTTPHeaderField:@"AppName"];
[SDWebImageDownloader sharedDownloader].config.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
self.objects = [NSMutableArray arrayWithObjects: self.objects = [NSMutableArray arrayWithObjects:
@"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth @"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth
@ -78,8 +80,6 @@
} }
} }
[SDWebImageManager.sharedManager.imageDownloader setValue:@"SDWebImage Demo" forHTTPHeaderField:@"AppName"];
SDWebImageManager.sharedManager.imageDownloader.config.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
return self; return self;
} }

View File

@ -51,6 +51,30 @@
320CAE1E2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; }; 320CAE1E2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; };
320CAE1F2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; }; 320CAE1F2086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; };
320CAE202086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; }; 320CAE202086F50500CFFC80 /* SDWebImageError.m in Sources */ = {isa = PBXBuildFile; fileRef = 320CAE142086F50500CFFC80 /* SDWebImageError.m */; };
321B37812083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37822083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37832083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37842083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37852083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37862083290E00C0EA77 /* SDWebImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377D2083290D00C0EA77 /* SDWebImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37872083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B37882083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B37892083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B378A2083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B378B2083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B378C2083290E00C0EA77 /* SDWebImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B377E2083290D00C0EA77 /* SDWebImageLoader.m */; };
321B378D2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B378E2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B378F2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37902083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37912083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37922083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
321B37932083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321B37942083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321B37952083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321B37962083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321B37972083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321B37982083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */; };
321DB3612011D4D70015D2CB /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 321DB3612011D4D70015D2CB /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
321DB3622011D4D70015D2CB /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */; }; 321DB3622011D4D70015D2CB /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */; };
321E60861F38E8C800405457 /* SDWebImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 321E60841F38E8C800405457 /* SDWebImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 321E60861F38E8C800405457 /* SDWebImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 321E60841F38E8C800405457 /* SDWebImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -1519,6 +1543,10 @@
320224BA203979BA00E9F285 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDAnimatedImageRep.m; sourceTree = "<group>"; }; 320224BA203979BA00E9F285 /* SDAnimatedImageRep.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDAnimatedImageRep.m; sourceTree = "<group>"; };
320CAE132086F50500CFFC80 /* SDWebImageError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageError.h; sourceTree = "<group>"; }; 320CAE132086F50500CFFC80 /* SDWebImageError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageError.h; sourceTree = "<group>"; };
320CAE142086F50500CFFC80 /* SDWebImageError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageError.m; sourceTree = "<group>"; }; 320CAE142086F50500CFFC80 /* SDWebImageError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageError.m; sourceTree = "<group>"; };
321B377D2083290D00C0EA77 /* SDWebImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageLoader.h; sourceTree = "<group>"; };
321B377E2083290D00C0EA77 /* SDWebImageLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageLoader.m; sourceTree = "<group>"; };
321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageLoadersManager.h; sourceTree = "<group>"; };
321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageLoadersManager.m; sourceTree = "<group>"; };
321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/NSButton+WebCache.h"; sourceTree = "<group>"; }; 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/NSButton+WebCache.h"; sourceTree = "<group>"; };
321DB3602011D4D60015D2CB /* NSButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/NSButton+WebCache.m"; sourceTree = "<group>"; }; 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/NSButton+WebCache.m"; sourceTree = "<group>"; };
321E60841F38E8C800405457 /* SDWebImageCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCoder.h; sourceTree = "<group>"; }; 321E60841F38E8C800405457 /* SDWebImageCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCoder.h; sourceTree = "<group>"; };
@ -2137,6 +2165,10 @@
32B9B536206ED4230026769D /* SDWebImageDownloaderConfig.m */, 32B9B536206ED4230026769D /* SDWebImageDownloaderConfig.m */,
32F21B4F20788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.h */, 32F21B4F20788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.h */,
32F21B5020788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.m */, 32F21B5020788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.m */,
321B377D2083290D00C0EA77 /* SDWebImageLoader.h */,
321B377E2083290D00C0EA77 /* SDWebImageLoader.m */,
321B377F2083290E00C0EA77 /* SDWebImageLoadersManager.h */,
321B37802083290E00C0EA77 /* SDWebImageLoadersManager.m */,
); );
name = Downloader; name = Downloader;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2346,6 +2378,7 @@
32B9B53A206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */, 32B9B53A206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */,
328BB6AD2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */, 328BB6AD2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */,
80377C4A1F2F666300F89830 /* bit_writer_utils.h in Headers */, 80377C4A1F2F666300F89830 /* bit_writer_utils.h in Headers */,
321B37902083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
4397D2F81D0DF44200BB2784 /* MKAnnotationView+WebCache.h in Headers */, 4397D2F81D0DF44200BB2784 /* MKAnnotationView+WebCache.h in Headers */,
323F8BE71F38EF770092B609 /* vp8li_enc.h in Headers */, 323F8BE71F38EF770092B609 /* vp8li_enc.h in Headers */,
329A185C1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */, 329A185C1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */,
@ -2389,6 +2422,7 @@
328BB6D02082581100760D6C /* SDMemoryCache.h in Headers */, 328BB6D02082581100760D6C /* SDMemoryCache.h in Headers */,
321E60891F38E8C800405457 /* SDWebImageCoder.h in Headers */, 321E60891F38E8C800405457 /* SDWebImageCoder.h in Headers */,
00733A721BC4880E00A5A117 /* UIView+WebCacheOperation.h in Headers */, 00733A721BC4880E00A5A117 /* UIView+WebCacheOperation.h in Headers */,
321B37842083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
80377C481F2F666300F89830 /* bit_reader_utils.h in Headers */, 80377C481F2F666300F89830 /* bit_reader_utils.h in Headers */,
80377C511F2F666300F89830 /* huffman_encode_utils.h in Headers */, 80377C511F2F666300F89830 /* huffman_encode_utils.h in Headers */,
32484778201775F600AF9E5A /* SDAnimatedImage.h in Headers */, 32484778201775F600AF9E5A /* SDAnimatedImage.h in Headers */,
@ -2466,6 +2500,7 @@
4314D16F1D0E0E3B004B36C9 /* NSData+ImageContentType.h in Headers */, 4314D16F1D0E0E3B004B36C9 /* NSData+ImageContentType.h in Headers */,
80377C121F2F666300F89830 /* bit_reader_inl_utils.h in Headers */, 80377C121F2F666300F89830 /* bit_reader_inl_utils.h in Headers */,
4314D1701D0E0E3B004B36C9 /* mux.h in Headers */, 4314D1701D0E0E3B004B36C9 /* mux.h in Headers */,
321B378E2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
321E60871F38E8C800405457 /* SDWebImageCoder.h in Headers */, 321E60871F38E8C800405457 /* SDWebImageCoder.h in Headers */,
80377EA21F2F66D400F89830 /* vp8i_dec.h in Headers */, 80377EA21F2F66D400F89830 /* vp8i_dec.h in Headers */,
320CAE162086F50500CFFC80 /* SDWebImageError.h in Headers */, 320CAE162086F50500CFFC80 /* SDWebImageError.h in Headers */,
@ -2474,6 +2509,7 @@
80377C211F2F666300F89830 /* quant_levels_dec_utils.h in Headers */, 80377C211F2F666300F89830 /* quant_levels_dec_utils.h in Headers */,
4314D1721D0E0E3B004B36C9 /* SDWebImageCompat.h in Headers */, 4314D1721D0E0E3B004B36C9 /* SDWebImageCompat.h in Headers */,
32484776201775F600AF9E5A /* SDAnimatedImage.h in Headers */, 32484776201775F600AF9E5A /* SDAnimatedImage.h in Headers */,
321B37822083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
80377C251F2F666300F89830 /* random_utils.h in Headers */, 80377C251F2F666300F89830 /* random_utils.h in Headers */,
80377D4F1F2F66A700F89830 /* lossless.h in Headers */, 80377D4F1F2F66A700F89830 /* lossless.h in Headers */,
80377D511F2F66A700F89830 /* msa_macro.h in Headers */, 80377D511F2F66A700F89830 /* msa_macro.h in Headers */,
@ -2528,6 +2564,7 @@
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
321B37912083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
80377C791F2F666400F89830 /* utils.h in Headers */, 80377C791F2F666400F89830 /* utils.h in Headers */,
328BB6A02081FED200760D6C /* SDWebImageCacheKeyFilter.h in Headers */, 328BB6A02081FED200760D6C /* SDWebImageCacheKeyFilter.h in Headers */,
323F8B721F38EF770092B609 /* delta_palettization_enc.h in Headers */, 323F8B721F38EF770092B609 /* delta_palettization_enc.h in Headers */,
@ -2540,6 +2577,7 @@
321E608A1F38E8C800405457 /* SDWebImageCoder.h in Headers */, 321E608A1F38E8C800405457 /* SDWebImageCoder.h in Headers */,
32484767201775F600AF9E5A /* SDAnimatedImageView+WebCache.h in Headers */, 32484767201775F600AF9E5A /* SDAnimatedImageView+WebCache.h in Headers */,
80377C601F2F666400F89830 /* bit_reader_inl_utils.h in Headers */, 80377C601F2F666400F89830 /* bit_reader_inl_utils.h in Headers */,
321B37852083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
329A185D1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */, 329A185D1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */,
431BB6DC1D06D2C1006A3455 /* UIButton+WebCache.h in Headers */, 431BB6DC1D06D2C1006A3455 /* UIButton+WebCache.h in Headers */,
431BB6E11D06D2C1006A3455 /* SDWebImage.h in Headers */, 431BB6E11D06D2C1006A3455 /* SDWebImage.h in Headers */,
@ -2634,6 +2672,7 @@
32B9B53C206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */, 32B9B53C206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */,
328BB6AF2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */, 328BB6AF2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */,
4397D2BA1D0DDD8C00BB2784 /* demux.h in Headers */, 4397D2BA1D0DDD8C00BB2784 /* demux.h in Headers */,
321B37922083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
80377C8F1F2F666400F89830 /* rescaler_utils.h in Headers */, 80377C8F1F2F666400F89830 /* rescaler_utils.h in Headers */,
4397D2BD1D0DDD8C00BB2784 /* types.h in Headers */, 4397D2BD1D0DDD8C00BB2784 /* types.h in Headers */,
4397D2C01D0DDD8C00BB2784 /* SDWebImage.h in Headers */, 4397D2C01D0DDD8C00BB2784 /* SDWebImage.h in Headers */,
@ -2677,6 +2716,7 @@
328BB6D22082581100760D6C /* SDMemoryCache.h in Headers */, 328BB6D22082581100760D6C /* SDMemoryCache.h in Headers */,
323F8BDD1F38EF770092B609 /* vp8i_enc.h in Headers */, 323F8BDD1F38EF770092B609 /* vp8i_enc.h in Headers */,
323F8B671F38EF770092B609 /* cost_enc.h in Headers */, 323F8B671F38EF770092B609 /* cost_enc.h in Headers */,
321B37862083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
80377EE11F2F66D500F89830 /* vp8_dec.h in Headers */, 80377EE11F2F66D500F89830 /* vp8_dec.h in Headers */,
80377EE41F2F66D500F89830 /* vp8li_dec.h in Headers */, 80377EE41F2F66D500F89830 /* vp8li_dec.h in Headers */,
80377C931F2F666400F89830 /* utils.h in Headers */, 80377C931F2F666400F89830 /* utils.h in Headers */,
@ -2733,6 +2773,7 @@
32B9B539206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */, 32B9B539206ED4230026769D /* SDWebImageDownloaderConfig.h in Headers */,
328BB6AC2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */, 328BB6AC2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */,
80377C301F2F666300F89830 /* bit_writer_utils.h in Headers */, 80377C301F2F666300F89830 /* bit_writer_utils.h in Headers */,
321B378F2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
431739541CDFC8B70008FEB9 /* types.h in Headers */, 431739541CDFC8B70008FEB9 /* types.h in Headers */,
323F8BE61F38EF770092B609 /* vp8li_enc.h in Headers */, 323F8BE61F38EF770092B609 /* vp8li_enc.h in Headers */,
329A185B1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */, 329A185B1FFF5DFD008C9A2F /* UIImage+WebCache.h in Headers */,
@ -2776,6 +2817,7 @@
328BB6CF2082581100760D6C /* SDMemoryCache.h in Headers */, 328BB6CF2082581100760D6C /* SDMemoryCache.h in Headers */,
321E60881F38E8C800405457 /* SDWebImageCoder.h in Headers */, 321E60881F38E8C800405457 /* SDWebImageCoder.h in Headers */,
4A2CAE371AB4BB7500B6BC39 /* UIView+WebCacheOperation.h in Headers */, 4A2CAE371AB4BB7500B6BC39 /* UIView+WebCacheOperation.h in Headers */,
321B37832083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
80377C2E1F2F666300F89830 /* bit_reader_utils.h in Headers */, 80377C2E1F2F666300F89830 /* bit_reader_utils.h in Headers */,
80377C371F2F666300F89830 /* huffman_encode_utils.h in Headers */, 80377C371F2F666300F89830 /* huffman_encode_utils.h in Headers */,
32484777201775F600AF9E5A /* SDAnimatedImage.h in Headers */, 32484777201775F600AF9E5A /* SDAnimatedImage.h in Headers */,
@ -2868,6 +2910,7 @@
321E60BE1F38E91700405457 /* UIImage+ForceDecode.h in Headers */, 321E60BE1F38E91700405457 /* UIImage+ForceDecode.h in Headers */,
5376131E155AD0D5005750A4 /* SDWebImagePrefetcher.h in Headers */, 5376131E155AD0D5005750A4 /* SDWebImagePrefetcher.h in Headers */,
32F7C06F2030114C00873181 /* SDWebImageTransformer.h in Headers */, 32F7C06F2030114C00873181 /* SDWebImageTransformer.h in Headers */,
321B378D2083290E00C0EA77 /* SDWebImageLoadersManager.h in Headers */,
324DF4B4200A14DC008A84CC /* SDWebImageDefine.h in Headers */, 324DF4B4200A14DC008A84CC /* SDWebImageDefine.h in Headers */,
80377CE11F2F66A100F89830 /* common_sse2.h in Headers */, 80377CE11F2F66A100F89830 /* common_sse2.h in Headers */,
80377C0B1F2F665300F89830 /* random_utils.h in Headers */, 80377C0B1F2F665300F89830 /* random_utils.h in Headers */,
@ -2892,6 +2935,7 @@
323F8BE41F38EF770092B609 /* vp8li_enc.h in Headers */, 323F8BE41F38EF770092B609 /* vp8li_enc.h in Headers */,
320CAE152086F50500CFFC80 /* SDWebImageError.h in Headers */, 320CAE152086F50500CFFC80 /* SDWebImageError.h in Headers */,
323F8B861F38EF770092B609 /* histogram_enc.h in Headers */, 323F8B861F38EF770092B609 /* histogram_enc.h in Headers */,
321B37812083290E00C0EA77 /* SDWebImageLoader.h in Headers */,
323F8BF61F38EF770092B609 /* animi.h in Headers */, 323F8BF61F38EF770092B609 /* animi.h in Headers */,
321E60861F38E8C800405457 /* SDWebImageCoder.h in Headers */, 321E60861F38E8C800405457 /* SDWebImageCoder.h in Headers */,
321E60B01F38E90100405457 /* SDWebImageWebPCoder.h in Headers */, 321E60B01F38E90100405457 /* SDWebImageWebPCoder.h in Headers */,
@ -3193,6 +3237,7 @@
80377DD71F2F66A700F89830 /* lossless_sse2.c in Sources */, 80377DD71F2F66A700F89830 /* lossless_sse2.c in Sources */,
80377DA81F2F66A700F89830 /* alpha_processing_mips_dsp_r2.c in Sources */, 80377DA81F2F66A700F89830 /* alpha_processing_mips_dsp_r2.c in Sources */,
80377DB11F2F66A700F89830 /* cost_mips_dsp_r2.c in Sources */, 80377DB11F2F66A700F89830 /* cost_mips_dsp_r2.c in Sources */,
321B37962083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
80377C581F2F666300F89830 /* random_utils.c in Sources */, 80377C581F2F666300F89830 /* random_utils.c in Sources */,
323F8B591F38EF770092B609 /* config_enc.c in Sources */, 323F8B591F38EF770092B609 /* config_enc.c in Sources */,
80377DE91F2F66A700F89830 /* yuv_mips32.c in Sources */, 80377DE91F2F66A700F89830 /* yuv_mips32.c in Sources */,
@ -3252,6 +3297,7 @@
80377C561F2F666300F89830 /* quant_levels_utils.c in Sources */, 80377C561F2F666300F89830 /* quant_levels_utils.c in Sources */,
323F8BCF1F38EF770092B609 /* token_enc.c in Sources */, 323F8BCF1F38EF770092B609 /* token_enc.c in Sources */,
80377DD11F2F66A700F89830 /* lossless_enc_sse2.c in Sources */, 80377DD11F2F66A700F89830 /* lossless_enc_sse2.c in Sources */,
321B378A2083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
32484772201775F600AF9E5A /* SDAnimatedImage.m in Sources */, 32484772201775F600AF9E5A /* SDAnimatedImage.m in Sources */,
323F8C1D1F38EF770092B609 /* muxread.c in Sources */, 323F8C1D1F38EF770092B609 /* muxread.c in Sources */,
807A12311F89636300EC2A9B /* SDWebImageCodersManager.m in Sources */, 807A12311F89636300EC2A9B /* SDWebImageCodersManager.m in Sources */,
@ -3395,6 +3441,7 @@
80377E9C1F2F66D400F89830 /* idec_dec.c in Sources */, 80377E9C1F2F66D400F89830 /* idec_dec.c in Sources */,
323F8B7B1F38EF770092B609 /* frame_enc.c in Sources */, 323F8B7B1F38EF770092B609 /* frame_enc.c in Sources */,
80377D211F2F66A700F89830 /* alpha_processing_sse41.c in Sources */, 80377D211F2F66A700F89830 /* alpha_processing_sse41.c in Sources */,
321B37942083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
323F8B8D1F38EF770092B609 /* iterator_enc.c in Sources */, 323F8B8D1F38EF770092B609 /* iterator_enc.c in Sources */,
3248475E201775F600AF9E5A /* SDAnimatedImageView.m in Sources */, 3248475E201775F600AF9E5A /* SDAnimatedImageView.m in Sources */,
80377D481F2F66A700F89830 /* lossless_enc_sse41.c in Sources */, 80377D481F2F66A700F89830 /* lossless_enc_sse41.c in Sources */,
@ -3455,6 +3502,7 @@
80377E991F2F66D400F89830 /* buffer_dec.c in Sources */, 80377E991F2F66D400F89830 /* buffer_dec.c in Sources */,
80377C201F2F666300F89830 /* quant_levels_dec_utils.c in Sources */, 80377C201F2F666300F89830 /* quant_levels_dec_utils.c in Sources */,
32F7C07F2030719600873181 /* UIImage+Transform.m in Sources */, 32F7C07F2030719600873181 /* UIImage+Transform.m in Sources */,
321B37882083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
80377D471F2F66A700F89830 /* lossless_enc_sse2.c in Sources */, 80377D471F2F66A700F89830 /* lossless_enc_sse2.c in Sources */,
80377C1E1F2F666300F89830 /* huffman_utils.c in Sources */, 80377C1E1F2F666300F89830 /* huffman_utils.c in Sources */,
); );
@ -3559,6 +3607,7 @@
80377DF01F2F66A800F89830 /* alpha_processing_sse41.c in Sources */, 80377DF01F2F66A800F89830 /* alpha_processing_sse41.c in Sources */,
80377ECC1F2F66D500F89830 /* idec_dec.c in Sources */, 80377ECC1F2F66D500F89830 /* idec_dec.c in Sources */,
323F8B7E1F38EF770092B609 /* frame_enc.c in Sources */, 323F8B7E1F38EF770092B609 /* frame_enc.c in Sources */,
321B37972083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
80377E171F2F66A800F89830 /* lossless_enc_sse41.c in Sources */, 80377E171F2F66A800F89830 /* lossless_enc_sse41.c in Sources */,
32484761201775F600AF9E5A /* SDAnimatedImageView.m in Sources */, 32484761201775F600AF9E5A /* SDAnimatedImageView.m in Sources */,
323F8B901F38EF770092B609 /* iterator_enc.c in Sources */, 323F8B901F38EF770092B609 /* iterator_enc.c in Sources */,
@ -3619,6 +3668,7 @@
80377EC91F2F66D500F89830 /* buffer_dec.c in Sources */, 80377EC91F2F66D500F89830 /* buffer_dec.c in Sources */,
80377C6C1F2F666400F89830 /* huffman_utils.c in Sources */, 80377C6C1F2F666400F89830 /* huffman_utils.c in Sources */,
32F7C0822030719600873181 /* UIImage+Transform.m in Sources */, 32F7C0822030719600873181 /* UIImage+Transform.m in Sources */,
321B378B2083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
80377E161F2F66A800F89830 /* lossless_enc_sse2.c in Sources */, 80377E161F2F66A800F89830 /* lossless_enc_sse2.c in Sources */,
431BB6C71D06D2C1006A3455 /* UIImageView+HighlightedWebCache.m in Sources */, 431BB6C71D06D2C1006A3455 /* UIImageView+HighlightedWebCache.m in Sources */,
); );
@ -3707,6 +3757,7 @@
32F21B5C20788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.m in Sources */, 32F21B5C20788D8C0036B1D5 /* SDWebImageDownloaderRequestModifier.m in Sources */,
32D122292080B2EB003685A3 /* SDWebImageCache.m in Sources */, 32D122292080B2EB003685A3 /* SDWebImageCache.m in Sources */,
80377E3B1F2F66A800F89830 /* cost_mips_dsp_r2.c in Sources */, 80377E3B1F2F66A800F89830 /* cost_mips_dsp_r2.c in Sources */,
321B378C2083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
4397D29B1D0DDD8C00BB2784 /* SDWebImageDownloader.m in Sources */, 4397D29B1D0DDD8C00BB2784 /* SDWebImageDownloader.m in Sources */,
80377E711F2F66A800F89830 /* upsampling.c in Sources */, 80377E711F2F66A800F89830 /* upsampling.c in Sources */,
328BB6A72081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */, 328BB6A72081FED200760D6C /* SDWebImageCacheKeyFilter.m in Sources */,
@ -3784,6 +3835,7 @@
323F8B851F38EF770092B609 /* histogram_enc.c in Sources */, 323F8B851F38EF770092B609 /* histogram_enc.c in Sources */,
80377EE51F2F66D500F89830 /* webp_dec.c in Sources */, 80377EE51F2F66D500F89830 /* webp_dec.c in Sources */,
4397D2B01D0DDD8C00BB2784 /* SDImageCache.m in Sources */, 4397D2B01D0DDD8C00BB2784 /* SDImageCache.m in Sources */,
321B37982083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
32F7C07A2030114C00873181 /* SDWebImageTransformer.m in Sources */, 32F7C07A2030114C00873181 /* SDWebImageTransformer.m in Sources */,
80377E4F1F2F66A800F89830 /* enc_sse41.c in Sources */, 80377E4F1F2F66A800F89830 /* enc_sse41.c in Sources */,
80377E701F2F66A800F89830 /* upsampling_sse2.c in Sources */, 80377E701F2F66A800F89830 /* upsampling_sse2.c in Sources */,
@ -3855,6 +3907,7 @@
80377D921F2F66A700F89830 /* lossless_sse2.c in Sources */, 80377D921F2F66A700F89830 /* lossless_sse2.c in Sources */,
80377D631F2F66A700F89830 /* alpha_processing_mips_dsp_r2.c in Sources */, 80377D631F2F66A700F89830 /* alpha_processing_mips_dsp_r2.c in Sources */,
80377D6C1F2F66A700F89830 /* cost_mips_dsp_r2.c in Sources */, 80377D6C1F2F66A700F89830 /* cost_mips_dsp_r2.c in Sources */,
321B37952083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
4A2CAE361AB4BB7500B6BC39 /* UIImageView+WebCache.m in Sources */, 4A2CAE361AB4BB7500B6BC39 /* UIImageView+WebCache.m in Sources */,
323F8B581F38EF770092B609 /* config_enc.c in Sources */, 323F8B581F38EF770092B609 /* config_enc.c in Sources */,
43C892A21D9D6DDD0022038D /* demux.c in Sources */, 43C892A21D9D6DDD0022038D /* demux.c in Sources */,
@ -3914,6 +3967,7 @@
4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */, 4A2CAE191AB4BB6400B6BC39 /* SDWebImageCompat.m in Sources */,
80377DA11F2F66A700F89830 /* upsampling_sse2.c in Sources */, 80377DA11F2F66A700F89830 /* upsampling_sse2.c in Sources */,
323F8BCE1F38EF770092B609 /* token_enc.c in Sources */, 323F8BCE1F38EF770092B609 /* token_enc.c in Sources */,
321B37892083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
32484771201775F600AF9E5A /* SDAnimatedImage.m in Sources */, 32484771201775F600AF9E5A /* SDAnimatedImage.m in Sources */,
80377C3C1F2F666300F89830 /* quant_levels_utils.c in Sources */, 80377C3C1F2F666300F89830 /* quant_levels_utils.c in Sources */,
323F8C1C1F38EF770092B609 /* muxread.c in Sources */, 323F8C1C1F38EF770092B609 /* muxread.c in Sources */,
@ -4023,6 +4077,7 @@
80377CD91F2F66A100F89830 /* alpha_processing_mips_dsp_r2.c in Sources */, 80377CD91F2F66A100F89830 /* alpha_processing_mips_dsp_r2.c in Sources */,
80377CE21F2F66A100F89830 /* cost_mips_dsp_r2.c in Sources */, 80377CE21F2F66A100F89830 /* cost_mips_dsp_r2.c in Sources */,
5376130B155AD0D5005750A4 /* SDWebImageDownloader.m in Sources */, 5376130B155AD0D5005750A4 /* SDWebImageDownloader.m in Sources */,
321B37932083290E00C0EA77 /* SDWebImageLoadersManager.m in Sources */,
323F8B561F38EF770092B609 /* config_enc.c in Sources */, 323F8B561F38EF770092B609 /* config_enc.c in Sources */,
43C8929B1D9D6DD70022038D /* demux.c in Sources */, 43C8929B1D9D6DD70022038D /* demux.c in Sources */,
80377D1A1F2F66A100F89830 /* yuv_mips32.c in Sources */, 80377D1A1F2F66A100F89830 /* yuv_mips32.c in Sources */,
@ -4082,6 +4137,7 @@
80377D171F2F66A100F89830 /* upsampling_sse2.c in Sources */, 80377D171F2F66A100F89830 /* upsampling_sse2.c in Sources */,
323F8BCC1F38EF770092B609 /* token_enc.c in Sources */, 323F8BCC1F38EF770092B609 /* token_enc.c in Sources */,
80377C081F2F665300F89830 /* quant_levels_utils.c in Sources */, 80377C081F2F665300F89830 /* quant_levels_utils.c in Sources */,
321B37872083290E00C0EA77 /* SDWebImageLoader.m in Sources */,
3248476F201775F600AF9E5A /* SDAnimatedImage.m in Sources */, 3248476F201775F600AF9E5A /* SDAnimatedImage.m in Sources */,
323F8C1A1F38EF770092B609 /* muxread.c in Sources */, 323F8C1A1F38EF770092B609 /* muxread.c in Sources */,
807A122E1F89636300EC2A9B /* SDWebImageCodersManager.m in Sources */, 807A122E1F89636300EC2A9B /* SDWebImageCodersManager.m in Sources */,

View File

@ -12,6 +12,7 @@
#import "SDWebImageOperation.h" #import "SDWebImageOperation.h"
#import "SDWebImageDownloaderConfig.h" #import "SDWebImageDownloaderConfig.h"
#import "SDWebImageDownloaderRequestModifier.h" #import "SDWebImageDownloaderRequestModifier.h"
#import "SDWebImageLoader.h"
typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) { typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
/** /**
@ -86,9 +87,8 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStartNotification; FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStartNotification;
FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStopNotification; FOUNDATION_EXPORT NSString * _Nonnull const SDWebImageDownloadStopNotification;
typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL); typedef SDWebImageLoaderProgressBlock SDWebImageDownloaderProgressBlock;
typedef SDWebImageLoaderCompletedBlock SDWebImageDownloaderCompletedBlock;
typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished);
/** /**
* A token associated with each download. Can be used to cancel a download * A token associated with each download. Can be used to cancel a download
@ -245,3 +245,13 @@ typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage * _Nullable image, NSD
- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations; - (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations;
@end @end
/**
SDWebImageDownloader is the built-in image loader conform to `SDWebImageLoader`. Which provide the HTTP/HTTPS/FTP download, or local file URL using NSURLSession.
However, this downloader class itself also support customization for advanced users. You can specify `operationClass` in download config to custom download operation, See `SDWebImageDownloaderOperation`.
If you want to provide some image loader which beyond network or local file, consider to create your own custom class conform to `SDWebImageLoader`.
*/
@interface SDWebImageDownloader (SDWebImageLoader) <SDWebImageLoader>
@end

View File

@ -462,3 +462,56 @@ didReceiveResponse:(NSURLResponse *)response
} }
@end @end
@implementation SDWebImageDownloader (SDWebImageLoader)
- (BOOL)canLoadWithURL:(NSURL *)url {
if (!url) {
return NO;
}
Class operationClass = self.config.operationClass;
if (!operationClass || [operationClass isSubclassOfClass:[SDWebImageDownloaderOperation class]]) {
// Built-in download operation class, checking all supported NSURLProtocol
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSArray<Class> *protocolClasses = self.sessionConfiguration.protocolClasses;
for (Class protocolClass in protocolClasses) {
if ([protocolClass isSubclassOfClass:[NSURLProtocol class]]) {
BOOL canLoad = [protocolClass canInitWithRequest:request];
if (canLoad) {
return YES;
}
continue;
}
}
return NO;
}
// Custom download operation class may not dependent on NSURLSession, always pass YES.
return YES;
}
- (id<SDWebImageOperation>)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDWebImageLoaderProgressBlock)progressBlock completed:(SDWebImageLoaderCompletedBlock)completedBlock {
UIImage *cachedImage;
if ([context valueForKey:SDWebImageContextLoaderCachedImage]) {
cachedImage = [context valueForKey:SDWebImageContextLoaderCachedImage];
}
SDWebImageDownloaderOptions downloaderOptions = 0;
if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority;
if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload;
if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;
if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground;
if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies;
if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates;
if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority;
if (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages;
if (cachedImage && options & SDWebImageRefreshCached) {
// force progressive off if image already cached but forced refreshing
downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
// ignore image read from NSURLCache if image if cached but force refreshing
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
}
return [self downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:completedBlock];
}
@end

View File

@ -7,12 +7,7 @@
*/ */
#import "SDWebImageDownloaderOperation.h" #import "SDWebImageDownloaderOperation.h"
#import "SDWebImageManager.h"
#import "NSImage+Additions.h"
#import "UIImage+WebCache.h"
#import "SDWebImageCodersManager.h" #import "SDWebImageCodersManager.h"
#import "SDWebImageCoderHelper.h"
#import "SDAnimatedImage.h"
#import "SDWebImageError.h" #import "SDWebImageError.h"
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); #define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
@ -46,7 +41,6 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
@property (assign, nonatomic, getter = isFinished) BOOL finished; @property (assign, nonatomic, getter = isFinished) BOOL finished;
@property (strong, nonatomic, nullable) NSMutableData *imageData; @property (strong, nonatomic, nullable) NSMutableData *imageData;
@property (copy, nonatomic, nullable) NSData *cachedData; // for `SDWebImageDownloaderIgnoreCachedResponse` @property (copy, nonatomic, nullable) NSData *cachedData; // for `SDWebImageDownloaderIgnoreCachedResponse`
@property (copy, nonatomic, nullable) NSString *cacheKey;
@property (assign, nonatomic, readwrite) NSUInteger expectedSize; @property (assign, nonatomic, readwrite) NSUInteger expectedSize;
@property (strong, nonatomic, nullable, readwrite) NSURLResponse *response; @property (strong, nonatomic, nullable, readwrite) NSURLResponse *response;
@ -356,43 +350,16 @@ didReceiveResponse:(NSURLResponse *)response
break; break;
} }
} }
// If we can't find any progressive coder, disable progressive download
if (!self.progressiveCoder) {
self.options &= ~SDWebImageDownloaderProgressiveDownload;
}
} }
[self.progressiveCoder updateIncrementalData:imageData finished:finished];
// progressive decode the image in coder queue // progressive decode the image in coder queue
dispatch_async(self.coderQueue, ^{ dispatch_async(self.coderQueue, ^{
// check whether we should use `SDAnimatedImage` UIImage *image = SDWebImageLoaderDecodeProgressiveImageData(data, self.request.URL, finished, self.progressiveCoder, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);
UIImage *image;
BOOL decodeFirstFrame = self.options & SDWebImageDownloaderDecodeFirstFrameOnly;
NSNumber *scaleValue = [self.context valueForKey:SDWebImageContextImageScaleFactor];
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(self.cacheKey);
if (!decodeFirstFrame) {
// check whether we should use `SDAnimatedImage`
if ([self.context valueForKey:SDWebImageContextAnimatedImageClass]) {
Class animatedImageClass = [self.context valueForKey:SDWebImageContextAnimatedImageClass];
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [self.progressiveCoder conformsToProtocol:@protocol(SDWebImageAnimatedCoder)]) {
image = [[animatedImageClass alloc] initWithAnimatedCoder:(id<SDWebImageAnimatedCoder>)self.progressiveCoder scale:scale];
}
}
}
if (!image) {
image = [self.progressiveCoder incrementalDecodedImageWithOptions:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
}
if (image) { if (image) {
BOOL shouldDecode = (self.options & SDWebImageDownloaderAvoidDecodeImage) == 0;
if ([image conformsToProtocol:@protocol(SDAnimatedImage)]) {
// `SDAnimatedImage` do not decode
shouldDecode = NO;
} else if (image.sd_isAnimated) {
// animated image do not decode
shouldDecode = NO;
}
if (shouldDecode) {
image = [SDWebImageCoderHelper decodedImageWithImage:image];
}
// mark the image as progressive (completionBlock one are not mark as progressive)
image.sd_isIncremental = YES;
// We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding. // We do not keep the progressive decoding image even when `finished`=YES. Because they are for view rendering but not take full function from downloader options. And some coders implementation may not keep consistent between progressive decoding and normal decoding.
[self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO]; [self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO];
@ -456,46 +423,7 @@ didReceiveResponse:(NSURLResponse *)response
} else { } else {
// decode the image in coder queue // decode the image in coder queue
dispatch_async(self.coderQueue, ^{ dispatch_async(self.coderQueue, ^{
BOOL decodeFirstFrame = self.options & SDWebImageDownloaderDecodeFirstFrameOnly; UIImage *image = SDWebImageLoaderDecodeImageData(imageData, self.request.URL, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);
NSNumber *scaleValue = [self.context valueForKey:SDWebImageContextImageScaleFactor];
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(self.cacheKey);
if (scale < 1) {
scale = 1;
}
UIImage *image;
if (!decodeFirstFrame) {
// check whether we should use `SDAnimatedImage`
if ([self.context valueForKey:SDWebImageContextAnimatedImageClass]) {
Class animatedImageClass = [self.context valueForKey:SDWebImageContextAnimatedImageClass];
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) {
image = [[animatedImageClass alloc] initWithData:imageData scale:scale];
if (self.options & SDWebImageDownloaderPreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) {
[((id<SDAnimatedImage>)image) preloadAllFrames];
}
}
}
}
if (!image) {
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:imageData options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
}
BOOL shouldDecode = (self.options & SDWebImageDownloaderAvoidDecodeImage) == 0;
if ([image conformsToProtocol:@protocol(SDAnimatedImage)]) {
// `SDAnimatedImage` do not decode
shouldDecode = NO;
} else if (image.sd_isAnimated) {
// animated image do not decode
shouldDecode = NO;
}
if (shouldDecode) {
BOOL shouldScaleDown = self.options & SDWebImageDownloaderScaleDownLargeImages;
if (shouldScaleDown) {
image = [SDWebImageCoderHelper decodedAndScaledDownImageWithImage:image limitBytes:0];
} else {
image = [SDWebImageCoderHelper decodedImageWithImage:image];
}
}
CGSize imageSize = image.size; CGSize imageSize = image.size;
if (imageSize.width == 0 || imageSize.height == 0) { if (imageSize.width == 0 || imageSize.height == 0) {
[self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}]]; [self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}]];
@ -546,11 +474,14 @@ didReceiveResponse:(NSURLResponse *)response
} }
#pragma mark Helper methods #pragma mark Helper methods
- (NSString *)cacheKey { + (SDWebImageOptions)imageOptionsFromDownloaderOptions:(SDWebImageDownloaderOptions)downloadOptions {
if (!_cacheKey) { SDWebImageOptions options = 0;
_cacheKey = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; if (downloadOptions & SDWebImageDownloaderScaleDownLargeImages) options |= SDWebImageScaleDownLargeImages;
} if (downloadOptions & SDWebImageDownloaderDecodeFirstFrameOnly) options |= SDWebImageDecodeFirstFrameOnly;
return _cacheKey; if (downloadOptions & SDWebImageDownloaderPreloadAllFrames) options |= SDWebImagePreloadAllFrames;
if (downloadOptions & SDWebImageDownloaderAvoidDecodeImage) options |= SDWebImageAvoidDecodeImage;
return options;
} }
- (BOOL)shouldContinueWhenAppEntersBackground { - (BOOL)shouldContinueWhenAppEntersBackground {

View File

@ -0,0 +1,88 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageCompat.h"
#import "SDWebImageDefine.h"
#import "SDWebImageOperation.h"
@protocol SDWebImageProgressiveCoder;
typedef void(^SDWebImageLoaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL);
typedef void(^SDWebImageLoaderCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished);
#pragma mark - Context
/**
A `UIImage` instance from `SDWebImageManager` when you specify `SDWebImageRefreshCached` and image cache hit.
This can be a hint for image loader to load the image from network and refresh the image from remote location if needed. If the cached image is equal to the remote location one. you should call the completion with all nil args. (UIImage)
*/
FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextLoaderCachedImage;
#pragma mark - Helper method
/**
This is the built-in decoding process for image download from network or local file.
@note If you want to implement your custom loader with `loadImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image.
@param imageData The image data from the network. Should not be nil
@param imageURL The image URL from the input. Should not be nil
@param options The options arg from the input
@param context The context arg from the input
@return The decoded image for current image data load from the network
*/
FOUNDATION_EXPORT UIImage * _Nullable SDWebImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context);
/**
This is the built-in decoding process for image progressive download from network. It's used when `SDWebImageProgressiveDownload` option is set. (It's not required when your loader does not support progressive image loading)
@note If you want to implement your custom loader with `loadImageWithURL:options:context:progress:completed:` API, but also want to keep compatible with SDWebImage's behavior, you'd better use this to produce image.
@param imageData The image data from the network so far. Should not be nil
@param imageURL The image URL from the input. Should not be nil
@param finished Pass NO to specify the download process has not finished. Pass YES when all image data has finished.
@param progressiveCoder The image progressive coder. Should not be nil. You should bind the progressive coder for each of loading operation to avoid conflict. See `SDWebImageProgressiveCoder`.
@param options The options arg from the input
@param context The context arg from the input
@return The decoded progressive image for current image data load from the network
*/
FOUNDATION_EXPORT UIImage * _Nullable SDWebImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished, id<SDWebImageProgressiveCoder> _Nonnull progressiveCoder, SDWebImageOptions options, SDWebImageContext * _Nullable context);
#pragma mark - SDWebImageLoader
// This is the protocol to specify custom image load process. You can create your own class to conform this protocol and use as a image loader to load image from network or any avaiable remote resources defined by yourself.
// If you want to implement custom loader for image download from network or local file, you just need to concentrate on image data download only. After the download finish, call `SDWebImageLoaderDecodeImageData` or `SDWebImageLoaderDecodeProgressiveImageData` to use the built-in decoding process and produce image (Remember to call in the global queue). And finally callback the completion block.
// If you directlly get the image instance using some third-party SDKs, such as image directlly from Photos framework. You can process the image data and image instance by yourself without that built-in decoding process. And finally callback the completion block.
// @note It's your responsibility to load the image in the desired global queue(to avoid block main queue). We do not dispatch these method call in a global queue but just from the call queue (For `SDWebImageManager`, it typically call from the main queue).
@protocol SDWebImageLoader <NSObject>
/**
Whether current image loader supports to load the provide image URL.
This will be checked everytime a new image request come for loader. If this return NO, we will mark this image load as failed. If return YES, we will start to call `loadImageWithURL:options:context:progress:completed:`.
@param url The image URL to be loaded.
@return YES to continue download, NO to stop download.
*/
- (BOOL)canLoadWithURL:(nullable NSURL *)url;
/**
Load the image and image data with the given URL and return the image data. You're responsible for producing the image instance.
@param url The URL represent the image. Note this may not be a HTTP URL
@param options A mask to specify options to use for this request
@param context A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
@param progressBlock A block called while image is downloading
* @note the progress block is executed on a background queue
@param completedBlock A block called when operation has been completed.
@return An operation which allow the user to cancel the current request.
*/
- (nullable id<SDWebImageOperation>)loadImageWithURL:(nullable NSURL *)url
options:(SDWebImageOptions)options
context:(nullable SDWebImageContext *)context
progress:(nullable SDWebImageLoaderProgressBlock)progressBlock
completed:(nullable SDWebImageLoaderCompletedBlock)completedBlock;
@end

View File

@ -0,0 +1,124 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageLoader.h"
#import "SDWebImageCacheKeyFilter.h"
#import "SDWebImageCodersManager.h"
#import "SDWebImageCoderHelper.h"
#import "SDAnimatedImage.h"
#import "UIImage+WebCache.h"
UIImage * _Nullable SDWebImageLoaderDecodeImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
NSCParameterAssert(imageData);
NSCParameterAssert(imageURL);
UIImage *image;
id<SDWebImageCacheKeyFilter> cacheKeyFilter = [context valueForKey:SDWebImageContextCacheKeyFilter];
NSString *cacheKey;
if (cacheKeyFilter) {
cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL];
} else {
cacheKey = imageURL.absoluteString;
}
BOOL decodeFirstFrame = options & SDWebImageDecodeFirstFrameOnly;
NSNumber *scaleValue = [context valueForKey:SDWebImageContextImageScaleFactor];
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey);
if (scale < 1) {
scale = 1;
}
if (!decodeFirstFrame) {
// check whether we should use `SDAnimatedImage`
if ([context valueForKey:SDWebImageContextAnimatedImageClass]) {
Class animatedImageClass = [context valueForKey:SDWebImageContextAnimatedImageClass];
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)]) {
image = [[animatedImageClass alloc] initWithData:imageData scale:scale];
if (options & SDWebImagePreloadAllFrames && [image respondsToSelector:@selector(preloadAllFrames)]) {
[((id<SDAnimatedImage>)image) preloadAllFrames];
}
}
}
}
if (!image) {
image = [[SDWebImageCodersManager sharedManager] decodedImageWithData:imageData options:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
}
if (image) {
BOOL shouldDecode = (options & SDWebImageAvoidDecodeImage) == 0;
if ([image conformsToProtocol:@protocol(SDAnimatedImage)]) {
// `SDAnimatedImage` do not decode
shouldDecode = NO;
} else if (image.sd_isAnimated) {
// animated image do not decode
shouldDecode = NO;
}
if (shouldDecode) {
BOOL shouldScaleDown = options & SDWebImageScaleDownLargeImages;
if (shouldScaleDown) {
image = [SDWebImageCoderHelper decodedAndScaledDownImageWithImage:image limitBytes:0];
} else {
image = [SDWebImageCoderHelper decodedImageWithImage:image];
}
}
}
return image;
}
UIImage * _Nullable SDWebImageLoaderDecodeProgressiveImageData(NSData * _Nonnull imageData, NSURL * _Nonnull imageURL, BOOL finished, id<SDWebImageProgressiveCoder> _Nonnull progressiveCoder, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
NSCParameterAssert(imageData);
NSCParameterAssert(imageURL);
NSCParameterAssert(progressiveCoder);
UIImage *image;
id<SDWebImageCacheKeyFilter> cacheKeyFilter = [context valueForKey:SDWebImageContextCacheKeyFilter];
NSString *cacheKey;
if (cacheKeyFilter) {
cacheKey = [cacheKeyFilter cacheKeyForURL:imageURL];
} else {
cacheKey = imageURL.absoluteString;
}
BOOL decodeFirstFrame = options & SDWebImageDecodeFirstFrameOnly;
NSNumber *scaleValue = [context valueForKey:SDWebImageContextImageScaleFactor];
CGFloat scale = scaleValue.doubleValue >= 1 ? scaleValue.doubleValue : SDImageScaleFactorForKey(cacheKey);
if (scale < 1) {
scale = 1;
}
[progressiveCoder updateIncrementalData:imageData finished:finished];
if (!decodeFirstFrame) {
// check whether we should use `SDAnimatedImage`
if ([context valueForKey:SDWebImageContextAnimatedImageClass]) {
Class animatedImageClass = [context valueForKey:SDWebImageContextAnimatedImageClass];
if ([animatedImageClass isSubclassOfClass:[UIImage class]] && [animatedImageClass conformsToProtocol:@protocol(SDAnimatedImage)] && [progressiveCoder conformsToProtocol:@protocol(SDWebImageAnimatedCoder)]) {
image = [[animatedImageClass alloc] initWithAnimatedCoder:(id<SDWebImageAnimatedCoder>)progressiveCoder scale:scale];
}
}
}
if (!image) {
image = [progressiveCoder incrementalDecodedImageWithOptions:@{SDWebImageCoderDecodeFirstFrameOnly : @(decodeFirstFrame), SDWebImageCoderDecodeScaleFactor : @(scale)}];
}
if (image) {
BOOL shouldDecode = (options & SDWebImageAvoidDecodeImage) == 0;
if ([image conformsToProtocol:@protocol(SDAnimatedImage)]) {
// `SDAnimatedImage` do not decode
shouldDecode = NO;
} else if (image.sd_isAnimated) {
// animated image do not decode
shouldDecode = NO;
}
if (shouldDecode) {
image = [SDWebImageCoderHelper decodedImageWithImage:image];
}
// mark the image as progressive (completionBlock one are not mark as progressive)
image.sd_isIncremental = YES;
}
return image;
}
SDWebImageContextOption const SDWebImageContextLoaderCachedImage = @"loaderCachedImage";

View File

@ -0,0 +1,34 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageLoader.h"
@interface SDWebImageLoadersManager : NSObject <SDWebImageLoader>
@property (nonatomic, class, readonly, nonnull) SDWebImageLoadersManager *sharedManager;
/**
All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority
*/
@property (nonatomic, copy, readwrite, nullable) NSArray<id<SDWebImageLoader>>* loaders;
/**
Add a new image loader to the end of loaders array. Which has the highest priority.
@param loader loader
*/
- (void)addLoader:(nonnull id<SDWebImageLoader>)loader;
/**
Remove a image loader in the loaders array.
@param loader loader
*/
- (void)removeLoader:(nonnull id<SDWebImageLoader>)loader;
@end

View File

@ -0,0 +1,98 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageLoadersManager.h"
#import "SDWebImageDownloader.h"
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
@interface SDWebImageLoadersManager ()
@property (nonatomic, strong, nonnull) dispatch_semaphore_t loadersLock;
@end
@implementation SDWebImageLoadersManager
+ (SDWebImageLoadersManager *)sharedManager {
static dispatch_once_t onceToken;
static SDWebImageLoadersManager *manager;
dispatch_once(&onceToken, ^{
manager = [[SDWebImageLoadersManager alloc] init];
});
return manager;
}
- (instancetype)init {
self = [super init];
if (self) {
// initialize with default image loaders
self.loaders = @[[SDWebImageDownloader sharedDownloader]];
self.loadersLock = dispatch_semaphore_create(1);
}
return self;
}
#pragma mark - Loader Property
- (void)addLoader:(id<SDWebImageLoader>)loader {
if (![loader conformsToProtocol:@protocol(SDWebImageLoader)]) {
return;
}
LOCK(self.loadersLock);
NSMutableArray<id<SDWebImageLoader>> *mutableLoaders = [self.loaders mutableCopy];
if (!mutableLoaders) {
mutableLoaders = [NSMutableArray array];
}
[mutableLoaders addObject:loader];
self.loaders = [mutableLoaders copy];
UNLOCK(self.loadersLock);
}
- (void)removeLoader:(id<SDWebImageLoader>)loader {
if (![loader conformsToProtocol:@protocol(SDWebImageLoader)]) {
return;
}
LOCK(self.loadersLock);
NSMutableArray<id<SDWebImageLoader>> *mutableLoaders = [self.loaders mutableCopy];
[mutableLoaders removeObject:loader];
self.loaders = [mutableLoaders copy];
UNLOCK(self.loadersLock);
}
#pragma mark - SDWebImageLoader
- (BOOL)canLoadWithURL:(nullable NSURL *)url {
LOCK(self.loadersLock);
NSArray<id<SDWebImageLoader>> *loaders = self.loaders;
UNLOCK(self.loadersLock);
for (id<SDWebImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader canLoadWithURL:url]) {
return YES;
}
}
return NO;
}
- (id<SDWebImageOperation>)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDWebImageLoaderProgressBlock)progressBlock completed:(SDWebImageLoaderCompletedBlock)completedBlock {
if (!url) {
return nil;
}
LOCK(self.loadersLock);
NSArray<id<SDWebImageLoader>> *loaders = self.loaders;
UNLOCK(self.loadersLock);
for (id<SDWebImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader respondsToSelector:@selector(loadImageWithURL:options:context:progress:completed:)]) {
return [loader loadImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock];
}
}
return nil;
}
@end

View File

@ -13,6 +13,7 @@
#import "SDWebImageTransformer.h" #import "SDWebImageTransformer.h"
#import "SDWebImageCacheKeyFilter.h" #import "SDWebImageCacheKeyFilter.h"
#import "SDWebImageCacheSerializer.h" #import "SDWebImageCacheSerializer.h"
#import "SDWebImageLoader.h"
typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL); typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
@ -102,10 +103,9 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
@property (strong, nonatomic, readonly, nonnull) id<SDWebImageCache> imageCache; @property (strong, nonatomic, readonly, nonnull) id<SDWebImageCache> imageCache;
/** /**
* The image downloader used by manager to download image. * The image loader used by manager to load image.
* @note If you specify a non-shared downloader, don't forget to call `invalidateSessionAndCancel:` at proper time to avoid memory leak.
*/ */
@property (strong, nonatomic, readonly, nonnull) SDWebImageDownloader *imageDownloader; @property (strong, nonatomic, readonly, nonnull) id<SDWebImageLoader> imageLoader;
/** /**
The image transformer for manager. It's used for image transform after the image load finished and store the transformed image to cache, see `SDWebImageTransformer`. The image transformer for manager. It's used for image transform after the image load finished and store the transformed image to cache, see `SDWebImageTransformer`.
@ -161,10 +161,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
@property (nonatomic, class, nullable) id<SDWebImageCache> defaultImageCache; @property (nonatomic, class, nullable) id<SDWebImageCache> defaultImageCache;
/** /**
The default image downloader for manager which is created with no arguments. Such as shared manager or init. The default image loader for manager which is created with no arguments. Such as shared manager or init.
Defaults to nil. Means using `SDWebImageDownloader.sharedDownloader` Defaults to nil. Means using `SDWebImageDownloader.sharedDownloader`
*/ */
@property (nonatomic, class, nullable) SDWebImageDownloader *defaultImageDownloader; @property (nonatomic, class, nullable) id<SDWebImageLoader> defaultImageLoader;
/** /**
* Returns global shared manager instance. * Returns global shared manager instance.
@ -172,10 +172,10 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
@property (nonatomic, class, readonly, nonnull) SDWebImageManager *sharedManager; @property (nonatomic, class, readonly, nonnull) SDWebImageManager *sharedManager;
/** /**
* Allows to specify instance of cache and image downloader used with image manager. * Allows to specify instance of cache and image loader used with image manager.
* @return new instance of `SDWebImageManager` with specified cache and downloader. * @return new instance of `SDWebImageManager` with specified cache and loader.
*/ */
- (nonnull instancetype)initWithCache:(nonnull id<SDWebImageCache>)cache downloader:(nonnull SDWebImageDownloader *)downloader NS_DESIGNATED_INITIALIZER; - (nonnull instancetype)initWithCache:(nonnull id<SDWebImageCache>)cache loader:(nonnull id<SDWebImageLoader>)loader NS_DESIGNATED_INITIALIZER;
/** /**
* Downloads the image at the given URL if not present in cache or return the cached version otherwise. * Downloads the image at the given URL if not present in cache or return the cached version otherwise.

View File

@ -14,7 +14,7 @@
#import "SDWebImageError.h" #import "SDWebImageError.h"
static id<SDWebImageCache> _defaultImageCache; static id<SDWebImageCache> _defaultImageCache;
static SDWebImageDownloader *_defaultImageDownloader; static id<SDWebImageLoader> _defaultImageLoader;
@interface SDWebImageCombinedOperation () @interface SDWebImageCombinedOperation ()
@ -28,7 +28,7 @@ static SDWebImageDownloader *_defaultImageDownloader;
@interface SDWebImageManager () @interface SDWebImageManager ()
@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache; @property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache;
@property (strong, nonatomic, readwrite, nonnull) SDWebImageDownloader *imageDownloader; @property (strong, nonatomic, readwrite, nonnull) id<SDWebImageLoader> imageLoader;
@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs; @property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;
@property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations; @property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations;
@ -47,15 +47,15 @@ static SDWebImageDownloader *_defaultImageDownloader;
_defaultImageCache = defaultImageCache; _defaultImageCache = defaultImageCache;
} }
+ (SDWebImageDownloader *)defaultImageDownloader { + (id<SDWebImageLoader>)defaultImageLoader {
return _defaultImageDownloader; return _defaultImageLoader;
} }
+ (void)setDefaultImageDownloader:(SDWebImageDownloader *)defaultImageDownloader { + (void)setDefaultImageLoader:(id<SDWebImageLoader>)defaultImageLoader {
if (defaultImageDownloader && ![defaultImageDownloader isKindOfClass:[SDWebImageDownloader class]]) { if (defaultImageLoader && ![defaultImageLoader conformsToProtocol:@protocol(SDWebImageLoader)]) {
return; return;
} }
_defaultImageDownloader = defaultImageDownloader; _defaultImageLoader = defaultImageLoader;
} }
+ (nonnull instancetype)sharedManager { + (nonnull instancetype)sharedManager {
@ -72,17 +72,17 @@ static SDWebImageDownloader *_defaultImageDownloader;
if (!cache) { if (!cache) {
cache = [SDImageCache sharedImageCache]; cache = [SDImageCache sharedImageCache];
} }
SDWebImageDownloader *downloader = [[self class] defaultImageDownloader]; id<SDWebImageLoader> loader = [[self class] defaultImageLoader];
if (!downloader) { if (!loader) {
downloader = [SDWebImageDownloader sharedDownloader]; loader = [SDWebImageDownloader sharedDownloader];
} }
return [self initWithCache:cache downloader:downloader]; return [self initWithCache:cache loader:loader];
} }
- (nonnull instancetype)initWithCache:(nonnull id<SDWebImageCache>)cache downloader:(nonnull SDWebImageDownloader *)downloader { - (nonnull instancetype)initWithCache:(nonnull id<SDWebImageCache>)cache loader:(nonnull id<SDWebImageLoader>)loader {
if ((self = [super init])) { if ((self = [super init])) {
_imageCache = cache; _imageCache = cache;
_imageDownloader = downloader; _imageLoader = loader;
_failedURLs = [NSMutableSet new]; _failedURLs = [NSMutableSet new];
_runningOperations = [NSMutableArray new]; _runningOperations = [NSMutableArray new];
} }
@ -195,36 +195,39 @@ static SDWebImageDownloader *_defaultImageDownloader;
BOOL shouldDownload = (!(options & SDWebImageFromCacheOnly)) BOOL shouldDownload = (!(options & SDWebImageFromCacheOnly))
&& (!cachedImage || options & SDWebImageRefreshCached) && (!cachedImage || options & SDWebImageRefreshCached)
&& (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]); && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url]);
// Check whether image downloader support target URL
shouldDownload &= [self.imageLoader canLoadWithURL:url];
if (shouldDownload) { if (shouldDownload) {
SDWebImageContext *downloadContext = context;
if (cacheKeyFilter) {
// Pass the cache key filter to the image loader.
SDWebImageMutableContext *mutableContext;
if (downloadContext) {
mutableContext = [downloadContext mutableCopy];
} else {
mutableContext = [NSMutableDictionary dictionary];
}
[mutableContext setValue:cacheKeyFilter forKey:SDWebImageContextCacheKeyFilter];
downloadContext = [mutableContext copy];
}
if (cachedImage && options & SDWebImageRefreshCached) { if (cachedImage && options & SDWebImageRefreshCached) {
// If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image // If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image
// AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.
[self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url]; [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
} // Pass the cached image to the image loader. The image loader should check whether the remote image is equal to the cached image.
SDWebImageMutableContext *mutableContext;
// download if no image or requested to refresh anyway, and download allowed by delegate if (downloadContext) {
SDWebImageDownloaderOptions downloaderOptions = 0; mutableContext = [downloadContext mutableCopy];
if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority; } else {
if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload; mutableContext = [NSMutableDictionary dictionary];
if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache; }
if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground; [mutableContext setValue:cachedImage forKey:SDWebImageContextLoaderCachedImage];
if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies; downloadContext = [mutableContext copy];
if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates;
if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority;
if (options & SDWebImageScaleDownLargeImages) downloaderOptions |= SDWebImageDownloaderScaleDownLargeImages;
if (options & SDWebImageDecodeFirstFrameOnly) downloaderOptions |= SDWebImageDownloaderDecodeFirstFrameOnly;
if (options & SDWebImagePreloadAllFrames) downloaderOptions |= SDWebImageDownloaderPreloadAllFrames;
if (cachedImage && options & SDWebImageRefreshCached) {
// force progressive off if image already cached but forced refreshing
downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
// ignore image read from NSURLCache if image if cached but force refreshing
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
} }
// `SDWebImageCombinedOperation` -> `SDWebImageDownloadToken` -> `downloadOperationCancelToken`, which is a `SDCallbacksDictionary` and retain the completed block below, so we need weak-strong again to avoid retain cycle // `SDWebImageCombinedOperation` -> `SDWebImageDownloadToken` -> `downloadOperationCancelToken`, which is a `SDCallbacksDictionary` and retain the completed block below, so we need weak-strong again to avoid retain cycle
__weak typeof(strongOperation) weakSubOperation = strongOperation; __weak typeof(strongOperation) weakSubOperation = strongOperation;
strongOperation.downloadOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions context:context progress:progressBlock completed:^(UIImage *downloadedImage, NSData *downloadedData, NSError *error, BOOL finished) { strongOperation.downloadOperation = [self.imageLoader loadImageWithURL:url options:options context:downloadContext progress:progressBlock completed:^(UIImage *downloadedImage, NSData *downloadedData, NSError *error, BOOL finished) {
__strong typeof(weakSubOperation) strongSubOperation = weakSubOperation; __strong typeof(weakSubOperation) strongSubOperation = weakSubOperation;
if (!strongSubOperation || strongSubOperation.isCancelled) { if (!strongSubOperation || strongSubOperation.isCancelled) {
// Do nothing if the operation was cancelled // Do nothing if the operation was cancelled
@ -264,12 +267,6 @@ static SDWebImageDownloader *_defaultImageDownloader;
if (options & SDWebImageCacheMemoryOnly) { if (options & SDWebImageCacheMemoryOnly) {
storeCacheType = SDImageCacheTypeMemory; storeCacheType = SDImageCacheTypeMemory;
} }
// We've done the scale process in SDWebImageDownloader with the shared manager, this is used for custom manager and avoid extra scale.
if (self != [SDWebImageManager sharedManager] && cacheKeyFilter && downloadedImage && ![downloadedImage conformsToProtocol:@protocol(SDAnimatedImage)]) {
downloadedImage = [self scaledImageForKey:key image:downloadedImage];
}
if (options & SDWebImageRefreshCached && cachedImage && !downloadedImage) { if (options & SDWebImageRefreshCached && cachedImage && !downloadedImage) {
// Image refresh hit the NSURLCache cache, do not call the completion block // Image refresh hit the NSURLCache cache, do not call the completion block
} else if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) { } else if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) {

View File

@ -15,6 +15,8 @@
321259EE1F39E4110096FE0E /* TestImageAnimated.webp in Resources */ = {isa = PBXBuildFile; fileRef = 321259ED1F39E4110096FE0E /* TestImageAnimated.webp */; }; 321259EE1F39E4110096FE0E /* TestImageAnimated.webp in Resources */ = {isa = PBXBuildFile; fileRef = 321259ED1F39E4110096FE0E /* TestImageAnimated.webp */; };
3226ECBB20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */; }; 3226ECBB20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */; };
3226ECBC20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */; }; 3226ECBC20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */; };
323B8E1F20862322008952BE /* SDWebImageTestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 323B8E1E20862322008952BE /* SDWebImageTestLoader.m */; };
323B8E2020862322008952BE /* SDWebImageTestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 323B8E1E20862322008952BE /* SDWebImageTestLoader.m */; };
3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; }; 3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; };
3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; }; 3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; };
3264FF2F205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; }; 3264FF2F205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
@ -70,6 +72,8 @@
321259ED1F39E4110096FE0E /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; }; 321259ED1F39E4110096FE0E /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; };
3226ECB920754F7700FAFACF /* SDWebImageTestDownloadOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestDownloadOperation.h; sourceTree = "<group>"; }; 3226ECB920754F7700FAFACF /* SDWebImageTestDownloadOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestDownloadOperation.h; sourceTree = "<group>"; };
3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestDownloadOperation.m; sourceTree = "<group>"; }; 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestDownloadOperation.m; sourceTree = "<group>"; };
323B8E1D20862322008952BE /* SDWebImageTestLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestLoader.h; sourceTree = "<group>"; };
323B8E1E20862322008952BE /* SDWebImageTestLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestLoader.m; sourceTree = "<group>"; };
3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTransformerTests.m; sourceTree = "<group>"; }; 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTransformerTests.m; sourceTree = "<group>"; };
3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestTransformer.h; sourceTree = "<group>"; }; 3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestTransformer.h; sourceTree = "<group>"; };
3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestTransformer.m; sourceTree = "<group>"; }; 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestTransformer.m; sourceTree = "<group>"; };
@ -223,6 +227,8 @@
32E6F0311F3A1B4700A945E6 /* SDWebImageTestDecoder.m */, 32E6F0311F3A1B4700A945E6 /* SDWebImageTestDecoder.m */,
3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */, 3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */,
3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */, 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */,
323B8E1D20862322008952BE /* SDWebImageTestLoader.h */,
323B8E1E20862322008952BE /* SDWebImageTestLoader.m */,
); );
path = Tests; path = Tests;
sourceTree = "<group>"; sourceTree = "<group>";
@ -470,6 +476,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
323B8E2020862322008952BE /* SDWebImageTestLoader.m in Sources */,
32B99EAC203B36650017FD66 /* SDWebImageDownloaderTests.m in Sources */, 32B99EAC203B36650017FD66 /* SDWebImageDownloaderTests.m in Sources */,
3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */, 3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */,
328BB6DE20825E9800760D6C /* SDWebImageTestCache.m in Sources */, 328BB6DE20825E9800760D6C /* SDWebImageTestCache.m in Sources */,
@ -492,6 +499,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
323B8E1F20862322008952BE /* SDWebImageTestLoader.m in Sources */,
32E6F0321F3A1B4700A945E6 /* SDWebImageTestDecoder.m in Sources */, 32E6F0321F3A1B4700A945E6 /* SDWebImageTestDecoder.m in Sources */,
3226ECBB20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */, 3226ECBB20754F7700FAFACF /* SDWebImageTestDownloadOperation.m in Sources */,
3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */, 3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */,

View File

@ -11,8 +11,10 @@
#import <SDWebImage/SDWebImageDownloader.h> #import <SDWebImage/SDWebImageDownloader.h>
#import <SDWebImage/SDWebImageDownloaderOperation.h> #import <SDWebImage/SDWebImageDownloaderOperation.h>
#import <SDWebImage/SDWebImageCodersManager.h> #import <SDWebImage/SDWebImageCodersManager.h>
#import <SDWebImage/SDWebImageLoadersManager.h>
#import "SDWebImageTestDownloadOperation.h" #import "SDWebImageTestDownloadOperation.h"
#import "SDWebImageTestDecoder.h" #import "SDWebImageTestDecoder.h"
#import "SDWebImageTestLoader.h"
/** /**
* Category for SDWebImageDownloader so we can access the operationClass * Category for SDWebImageDownloader so we can access the operationClass
@ -414,4 +416,34 @@
[self waitForExpectationsWithCommonTimeout]; [self waitForExpectationsWithCommonTimeout];
} }
#pragma mark - SDWebImageLoader
- (void)test30CustomImageLoaderWorks {
XCTestExpectation *expectation = [self expectationWithDescription:@"Custom image not works"];
SDWebImageTestLoader *loader = [[SDWebImageTestLoader alloc] init];
NSURL *imageURL = [NSURL URLWithString:kTestJpegURL];
[loader loadImageWithURL:imageURL options:0 context:nil progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
expect(targetURL).notTo.beNil();
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
expect(error).to.beNil();
expect(image).notTo.beNil();
[expectation fulfill];
}];
[self waitForExpectationsWithCommonTimeout];
}
- (void)test31ThatLoadersManagerWorks {
XCTestExpectation *expectation = [self expectationWithDescription:@"Loaders manager not works"];
NSURL *imageURL = [NSURL URLWithString:kTestJpegURL];
[[SDWebImageLoadersManager sharedManager] loadImageWithURL:imageURL options:0 context:nil progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
expect(targetURL).notTo.beNil();
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
expect(error).to.beNil();
expect(image).notTo.beNil();
[expectation fulfill];
}];
[self waitForExpectationsWithCommonTimeout];
}
@end @end

View File

@ -118,7 +118,7 @@
NSBundle *testBundle = [NSBundle bundleForClass:[self class]]; NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
NSString *testImagePath = [testBundle pathForResource:@"TestImage" ofType:@"jpg"]; NSString *testImagePath = [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
transformer.testImage = [[UIImage alloc] initWithContentsOfFile:testImagePath]; transformer.testImage = [[UIImage alloc] initWithContentsOfFile:testImagePath];
SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:[SDImageCache sharedImageCache] downloader:[SDWebImageDownloader sharedDownloader]]; SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:[SDImageCache sharedImageCache] loader:[SDWebImageDownloader sharedDownloader]];
manager.transformer = transformer; manager.transformer = transformer;
[[SDImageCache sharedImageCache] removeImageForKey:kTestJpegURL withCompletion:^{ [[SDImageCache sharedImageCache] removeImageForKey:kTestJpegURL withCompletion:^{
[manager loadImageWithURL:imageURL options:SDWebImageTransformAnimatedImage progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { [manager loadImageWithURL:imageURL options:SDWebImageTransformAnimatedImage progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {

View File

@ -0,0 +1,16 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
* (c) Matt Galloway
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import <SDWebImage/SDWebImageLoader.h>
// A really naive implementation of custom image loader using `NSURLSession`
@interface SDWebImageTestLoader : NSObject <SDWebImageLoader>
@end

View File

@ -0,0 +1,53 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
* (c) Matt Galloway
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageTestLoader.h"
#import <KVOController/KVOController.h>
@interface NSURLSessionTask (SDWebImageOperation) <SDWebImageOperation>
@end
@implementation SDWebImageTestLoader
- (BOOL)canLoadWithURL:(NSURL *)url {
return YES;
}
- (id<SDWebImageOperation>)loadImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDWebImageLoaderProgressBlock)progressBlock completed:(SDWebImageLoaderCompletedBlock)completedBlock {
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *image = SDWebImageLoaderDecodeImageData(data, url, options, context);
if (completedBlock) {
completedBlock(image, data, nil, YES);
}
});
} else {
if (completedBlock) {
completedBlock(nil, nil, error, YES);
}
}
}];
[self.KVOController observe:task keyPath:NSStringFromSelector(@selector(countOfBytesReceived)) options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSString *,id> * _Nonnull change) {
NSURLSessionTask *sessionTask = object;
NSInteger receivedSize = sessionTask.countOfBytesReceived;
NSInteger expectedSize = sessionTask.countOfBytesExpectedToReceive;
if (progressBlock) {
progressBlock(receivedSize, expectedSize, url);
}
}];
[task resume];
return task;
}
@end

View File

@ -36,6 +36,8 @@ FOUNDATION_EXPORT const unsigned char WebImageVersionString[];
#import <SDWebImage/SDWebImageDownloaderConfig.h> #import <SDWebImage/SDWebImageDownloaderConfig.h>
#import <SDWebImage/SDWebImageDownloaderOperation.h> #import <SDWebImage/SDWebImageDownloaderOperation.h>
#import <SDWebImage/SDWebImageDownloaderRequestModifier.h> #import <SDWebImage/SDWebImageDownloaderRequestModifier.h>
#import <SDWebImage/SDWebImageLoader.h>
#import <SDWebImage/SDWebImageLoadersManager.h>
#import <SDWebImage/UIButton+WebCache.h> #import <SDWebImage/UIButton+WebCache.h>
#import <SDWebImage/SDWebImagePrefetcher.h> #import <SDWebImage/SDWebImagePrefetcher.h>
#import <SDWebImage/UIView+WebCacheOperation.h> #import <SDWebImage/UIView+WebCacheOperation.h>