Commit f9e5513da0483c937657063f5aec75d6957ad124
1 parent
00cc8243
no message
Showing
16 changed files
with
0 additions
and
968 deletions
CNLiveImageCache.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveImageCache.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/19. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import <UIKit/UIKit.h> | |
| 11 | -#import "CNLiveWebImageBlock.h" | |
| 12 | - | |
| 13 | -//typedef void(^CNLiveWebImageQueryCompletedBlock)(UIImage *image, CNLiveImageCacheType type); | |
| 14 | -typedef void(^CNLiveCompletedBlock)(); | |
| 15 | - | |
| 16 | -@interface CNLiveImageCache : NSObject | |
| 17 | - | |
| 18 | -+ (CNLiveImageCache *)sharedImageCache; | |
| 19 | - | |
| 20 | -- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; | |
| 21 | - | |
| 22 | -- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key; | |
| 23 | - | |
| 24 | -- (UIImage *)imageFromDiskCacheForKey:(NSString *)key; | |
| 25 | - | |
| 26 | -- (BOOL)queryDiskCacheForKey:(NSString *)key done:(CNLiveWebImageQueryCompletedBlock)doneBlock; | |
| 27 | - | |
| 28 | -- (void)removeCacheForKey:(NSString *)key done:(CNLiveCompletedBlock)completed; | |
| 29 | - | |
| 30 | -- (long long)diskCacheSize; | |
| 31 | - | |
| 32 | -- (void)clearMemory; | |
| 33 | - | |
| 34 | -- (void)clearDisk; | |
| 35 | - | |
| 36 | -@end |
CNLiveImageCache.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveImageCache.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/19. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "CNLiveImageCache.h" | |
| 10 | -#import <CommonCrypto/CommonDigest.h> | |
| 11 | -#import "UIImage+MultiFormat.h" | |
| 12 | - | |
| 13 | -FOUNDATION_STATIC_INLINE NSUInteger CNLiveCacheCostForImage(UIImage *image) { | |
| 14 | - return image.size.height * image.size.width * image.scale * image.scale; | |
| 15 | -} | |
| 16 | - | |
| 17 | -typedef void(^CNLiveWebImageNoParamsBlock)(); | |
| 18 | - | |
| 19 | -@interface CNLiveImageCache () | |
| 20 | - | |
| 21 | -@property (nonatomic, strong) NSCache *memoryCache; | |
| 22 | -@property (nonatomic, copy) NSString *diskCachePath; | |
| 23 | -@property (nonatomic, strong) dispatch_queue_t ioQueue; | |
| 24 | - | |
| 25 | -@end | |
| 26 | - | |
| 27 | -@implementation CNLiveImageCache | |
| 28 | -{ | |
| 29 | - NSFileManager *_fileManager; | |
| 30 | -} | |
| 31 | - | |
| 32 | -+ (CNLiveImageCache *)sharedImageCache | |
| 33 | -{ | |
| 34 | - static dispatch_once_t onceToken; | |
| 35 | - static id instance; | |
| 36 | - dispatch_once(&onceToken, ^{ | |
| 37 | - instance = [self new]; | |
| 38 | - }); | |
| 39 | - return instance; | |
| 40 | -} | |
| 41 | - | |
| 42 | -- (id)init { | |
| 43 | - return [self initWithNamespace:@"default"]; | |
| 44 | -} | |
| 45 | - | |
| 46 | -- (id)initWithNamespace:(NSString *)ns { | |
| 47 | - NSString *path = [self makeDiskCachePath:ns]; | |
| 48 | - return [self initWithNamespace:ns diskCacheDirectory:path]; | |
| 49 | -} | |
| 50 | - | |
| 51 | -- (NSString *)makeDiskCachePath:(NSString *)fullNamespace { | |
| 52 | - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); | |
| 53 | - return [paths[0] stringByAppendingString:fullNamespace]; | |
| 54 | -} | |
| 55 | - | |
| 56 | -- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory { | |
| 57 | - if (self = [super init]) { | |
| 58 | - NSString *fullNameSpace = [@"com.cnlive.CNLiveImageCache." stringByAppendingString:ns]; | |
| 59 | - _ioQueue = dispatch_queue_create("com.cnlive.CNLiveImageCacheQueue", DISPATCH_QUEUE_SERIAL); | |
| 60 | - _memoryCache = [[NSCache alloc] init]; | |
| 61 | - _memoryCache.name = fullNameSpace; | |
| 62 | - | |
| 63 | - if (directory != nil) { | |
| 64 | - _diskCachePath = [directory stringByAppendingPathComponent:fullNameSpace]; | |
| 65 | - } | |
| 66 | - else { | |
| 67 | - _diskCachePath = [[self makeDiskCachePath:ns] stringByAppendingPathComponent:fullNameSpace]; | |
| 68 | - } | |
| 69 | - | |
| 70 | - dispatch_sync(_ioQueue, ^{ | |
| 71 | - _fileManager = [NSFileManager new]; | |
| 72 | - }); | |
| 73 | - | |
| 74 | - [[NSNotificationCenter defaultCenter] addObserver:self | |
| 75 | - selector:@selector(clearMemory) | |
| 76 | - name:UIApplicationDidReceiveMemoryWarningNotification | |
| 77 | - object:nil]; | |
| 78 | - | |
| 79 | -// [[NSNotificationCenter defaultCenter] addObserver:self | |
| 80 | -// selector:@selector(clearDisk) | |
| 81 | -// name:UIApplicationWillTerminateNotification | |
| 82 | -// object:nil]; | |
| 83 | - } | |
| 84 | - return self; | |
| 85 | -} | |
| 86 | - | |
| 87 | -- (void)dealloc | |
| 88 | -{ | |
| 89 | - [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
| 90 | -} | |
| 91 | - | |
| 92 | -- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk | |
| 93 | -{ | |
| 94 | - if (!image || !key) { | |
| 95 | - return; | |
| 96 | - } | |
| 97 | - | |
| 98 | - NSUInteger cost = CNLiveCacheCostForImage(image); | |
| 99 | - [_memoryCache setObject:image forKey:key cost:cost]; | |
| 100 | - | |
| 101 | - if (toDisk) { | |
| 102 | - dispatch_async(_ioQueue, ^{ | |
| 103 | - NSData *data = UIImageJPEGRepresentation(image, 1.0); | |
| 104 | - | |
| 105 | - if (data) { | |
| 106 | - if (![_fileManager fileExistsAtPath:_diskCachePath]) { | |
| 107 | - [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; | |
| 108 | - } | |
| 109 | - NSString *cachePathForKey = [self defaultCachePathForKey:key]; | |
| 110 | - [_fileManager createFileAtPath:cachePathForKey contents:data attributes:nil]; | |
| 111 | - } | |
| 112 | - }); | |
| 113 | - } | |
| 114 | -} | |
| 115 | - | |
| 116 | -- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key | |
| 117 | -{ | |
| 118 | - return [self.memoryCache objectForKey:key]; | |
| 119 | -} | |
| 120 | - | |
| 121 | -- (UIImage *)imageFromDiskCacheForKey:(NSString *)key | |
| 122 | -{ | |
| 123 | - UIImage *memoryImage = [self imageFromMemoryCacheForKey:key]; | |
| 124 | - if (memoryImage) { | |
| 125 | - return memoryImage; | |
| 126 | - } | |
| 127 | - | |
| 128 | - NSData *diskData = [self getDiskImageDataWithKey:key]; | |
| 129 | - if (diskData) { | |
| 130 | - return [UIImage ws_imageWithData:diskData]; | |
| 131 | - } | |
| 132 | - | |
| 133 | - return nil; | |
| 134 | -} | |
| 135 | - | |
| 136 | -- (BOOL)queryDiskCacheForKey:(NSString *)key done:(CNLiveWebImageQueryCompletedBlock)doneBlock | |
| 137 | -{ | |
| 138 | - if (!doneBlock) { | |
| 139 | - return NO; | |
| 140 | - } | |
| 141 | - if (!key) { | |
| 142 | - doneBlock(nil, CNLiveImageCacheTypeNone); | |
| 143 | - return NO; | |
| 144 | - } | |
| 145 | - | |
| 146 | - UIImage *memoryImage = [self imageFromMemoryCacheForKey:key]; | |
| 147 | - if (memoryImage) { | |
| 148 | - doneBlock(memoryImage, CNLiveImageCacheTypeMemory); | |
| 149 | - return YES; | |
| 150 | - } | |
| 151 | - | |
| 152 | - UIImage *diskImage = [self imageFromDiskCacheForKey:key]; | |
| 153 | - if (diskImage) { | |
| 154 | - doneBlock(diskImage, CNLiveImageCacheTypeDisk); | |
| 155 | - return YES; | |
| 156 | - } | |
| 157 | - | |
| 158 | - doneBlock(nil, CNLiveImageCacheTypeNone); | |
| 159 | - return NO; | |
| 160 | - | |
| 161 | -} | |
| 162 | - | |
| 163 | -- (void)removeCacheForKey:(NSString *)key done:(CNLiveCompletedBlock)completed | |
| 164 | -{ | |
| 165 | - if (!key || !completed) { | |
| 166 | - return; | |
| 167 | - } | |
| 168 | - | |
| 169 | - if ([self imageFromMemoryCacheForKey:key]) { | |
| 170 | - [self.memoryCache removeObjectForKey:key]; | |
| 171 | - } | |
| 172 | - | |
| 173 | - if ([self imageFromDiskCacheForKey:key]) { | |
| 174 | - NSString *cachePathForKey = [self defaultCachePathForKey:key]; | |
| 175 | - [_fileManager removeItemAtPath:cachePathForKey error:nil]; | |
| 176 | - } | |
| 177 | - | |
| 178 | - completed(); | |
| 179 | -} | |
| 180 | - | |
| 181 | -- (long long)diskCacheSize | |
| 182 | -{ | |
| 183 | - if ([_fileManager fileExistsAtPath:self.diskCachePath]) { | |
| 184 | - NSArray *subPathArray = [_fileManager subpathsAtPath:self.diskCachePath]; | |
| 185 | - if (subPathArray && subPathArray.count > 0) { | |
| 186 | - long long totalCacheSize = 0; | |
| 187 | - for (NSString *subPath in subPathArray) { | |
| 188 | - NSString *fullPath = [self.diskCachePath stringByAppendingPathComponent:subPath]; | |
| 189 | - NSDictionary *cacheSizeDic = [_fileManager attributesOfItemAtPath:fullPath error:nil]; | |
| 190 | - totalCacheSize += [cacheSizeDic fileSize]; | |
| 191 | - } | |
| 192 | - return totalCacheSize; | |
| 193 | - } | |
| 194 | - } | |
| 195 | - return 0; | |
| 196 | -} | |
| 197 | - | |
| 198 | -- (void)clearMemory | |
| 199 | -{ | |
| 200 | - [self.memoryCache removeAllObjects]; | |
| 201 | -} | |
| 202 | - | |
| 203 | -- (void)clearDisk | |
| 204 | -{ | |
| 205 | - [self clearDiskOnCompletion:nil]; | |
| 206 | -} | |
| 207 | - | |
| 208 | -- (void)clearDiskOnCompletion:(CNLiveWebImageNoParamsBlock)completion | |
| 209 | -{ | |
| 210 | - dispatch_async(self.ioQueue, ^{ | |
| 211 | - [_fileManager removeItemAtPath:self.diskCachePath error:nil]; | |
| 212 | - [_fileManager createDirectoryAtPath:self.diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; | |
| 213 | - | |
| 214 | - if (completion) { | |
| 215 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 216 | - completion(); | |
| 217 | - }); | |
| 218 | - } | |
| 219 | - }); | |
| 220 | -} | |
| 221 | - | |
| 222 | -#pragma mark <PrivateMethod> | |
| 223 | -- (NSData *)getDiskImageDataWithKey:(NSString *)key | |
| 224 | -{ | |
| 225 | - NSString *filePath = [self defaultCachePathForKey:key]; | |
| 226 | - NSData *imageData = [NSData dataWithContentsOfFile:filePath]; | |
| 227 | - return imageData; | |
| 228 | -} | |
| 229 | - | |
| 230 | -- (NSString *)defaultCachePathForKey:(NSString *)key | |
| 231 | -{ | |
| 232 | - return [self cachePathForKey:key inPath:self.diskCachePath]; | |
| 233 | -} | |
| 234 | - | |
| 235 | -- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path | |
| 236 | -{ | |
| 237 | - NSString *fileName = [self cachedFileNameForKey:key]; | |
| 238 | - return [path stringByAppendingPathComponent:fileName]; | |
| 239 | -} | |
| 240 | - | |
| 241 | -- (NSString *)cachedFileNameForKey:(NSString *)key { | |
| 242 | - const char *str = [key UTF8String]; | |
| 243 | - if (str == NULL) { | |
| 244 | - str = ""; | |
| 245 | - } | |
| 246 | - unsigned char r[CC_MD5_DIGEST_LENGTH]; | |
| 247 | - CC_MD5(str, (CC_LONG)strlen(str), r); | |
| 248 | - NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", | |
| 249 | - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; | |
| 250 | - | |
| 251 | - return filename; | |
| 252 | -} | |
| 253 | - | |
| 254 | -@end |
CNLiveWebImageBlock.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageBlock.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/27. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#ifndef CNLiveWebImageBlock_h | |
| 10 | -#define CNLiveWebImageBlock_h | |
| 11 | - | |
| 12 | -typedef NS_ENUM(NSUInteger, CNLiveImageCacheType) { | |
| 13 | - CNLiveImageCacheTypeNone, | |
| 14 | - CNLiveImageCacheTypeMemory, | |
| 15 | - CNLiveImageCacheTypeDisk | |
| 16 | -}; | |
| 17 | - | |
| 18 | -typedef void(^CNLiveDownloadProgressBlock)(NSInteger receivedSize, NSInteger expectedSize); | |
| 19 | -typedef void(^CNLiveDownloadCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished); | |
| 20 | - | |
| 21 | -typedef void(^CNLiveWebImageQueryCompletedBlock)(UIImage *image, CNLiveImageCacheType type); | |
| 22 | -typedef void(^CNLiveCompletedBlock)(); | |
| 23 | -typedef void(^CNLiveWebImageNoParamsBlock)(); | |
| 24 | - | |
| 25 | -#endif /* CNLiveWebImageBlock_h */ |
CNLiveWebImageDownload.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageDownload.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/14. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import <UIKit/UIKit.h> | |
| 11 | -#import "CNLiveWebImageOperation.h" | |
| 12 | -#import "CNLiveWebImageBlock.h" | |
| 13 | - | |
| 14 | -typedef NS_OPTIONS(NSUInteger, CNLiveWebImageDownloadOptions) { | |
| 15 | - CNLiveWebImageDownloadProgressiveDownload = 1 << 0, | |
| 16 | - CNLiveWebImageDownloadContinueInBackground = 1 << 1 | |
| 17 | -}; | |
| 18 | - | |
| 19 | -@interface CNLiveWebImageDownload : NSObject | |
| 20 | - | |
| 21 | -+ (CNLiveWebImageDownload *)sharedDownload; | |
| 22 | - | |
| 23 | -- (id <CNLiveWebImageOperation>)downloadWebImageWithURL:(NSURL *)url options:(CNLiveWebImageDownloadOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed; | |
| 24 | - | |
| 25 | -@end |
CNLiveWebImageDownload.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageDownload.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/14. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "CNLiveWebImageDownload.h" | |
| 10 | -#import "CNLiveWebImageDownloadOperation.h" | |
| 11 | - | |
| 12 | -@interface CNLiveWebImageDownload () | |
| 13 | - | |
| 14 | -@property (nonatomic, strong) NSOperationQueue *downloadQueue; | |
| 15 | - | |
| 16 | -@end | |
| 17 | - | |
| 18 | -@implementation CNLiveWebImageDownload | |
| 19 | - | |
| 20 | -+ (CNLiveWebImageDownload *)sharedDownload | |
| 21 | -{ | |
| 22 | - static dispatch_once_t once; | |
| 23 | - static id instance; | |
| 24 | - dispatch_once(&once, ^{ | |
| 25 | - instance = [self new]; | |
| 26 | - }); | |
| 27 | - return instance; | |
| 28 | -} | |
| 29 | - | |
| 30 | -- (instancetype)init | |
| 31 | -{ | |
| 32 | - if ((self = [super init])) { | |
| 33 | - _downloadQueue = [NSOperationQueue new]; | |
| 34 | - _downloadQueue.maxConcurrentOperationCount = 6; | |
| 35 | - } | |
| 36 | - return self; | |
| 37 | -} | |
| 38 | - | |
| 39 | -- (void)dealloc | |
| 40 | -{ | |
| 41 | - [self.downloadQueue cancelAllOperations]; | |
| 42 | -} | |
| 43 | - | |
| 44 | -- (id<CNLiveWebImageOperation>)downloadWebImageWithURL:(NSURL *)url options:(CNLiveWebImageDownloadOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed | |
| 45 | -{ | |
| 46 | - CNLiveWebImageDownloadOperation *operation; | |
| 47 | - operation = [[CNLiveWebImageDownloadOperation alloc] initWithURL:url | |
| 48 | - options:options | |
| 49 | - progress:progress | |
| 50 | - completed:completed]; | |
| 51 | - [self.downloadQueue addOperation:operation]; | |
| 52 | - return (id <CNLiveWebImageOperation>)operation; | |
| 53 | -} | |
| 54 | -@end |
CNLiveWebImageDownloadOperation.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageDownloadOperation.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/25. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import "CNLiveWebImageDownload.h" | |
| 11 | -#import "CNLiveWebImageBlock.h" | |
| 12 | - | |
| 13 | -@interface CNLiveWebImageDownloadOperation : NSOperation | |
| 14 | - | |
| 15 | -- (id)initWithURL:(NSURL *)url options:(CNLiveWebImageDownloadOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed; | |
| 16 | - | |
| 17 | -@end |
CNLiveWebImageDownloadOperation.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageDownloadOperation.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/25. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "CNLiveWebImageDownloadOperation.h" | |
| 10 | -#import "CNLiveWebImageOperation.h" | |
| 11 | -#import <ImageIO/ImageIO.h> | |
| 12 | -#import "UIImage+MultiFormat.h" | |
| 13 | - | |
| 14 | -#define CNLiveWebImageBackgroundSessionIdentifier @"CNLiveWebImageBackgroundSessionIdentifier" | |
| 15 | - | |
| 16 | -@interface CNLiveWebImageDownloadOperation ()<CNLiveWebImageOperation, NSURLSessionDataDelegate, NSURLSessionTaskDelegate, NSURLSessionDelegate> | |
| 17 | - | |
| 18 | -@property (nonatomic, copy) CNLiveDownloadProgressBlock progressBlock; | |
| 19 | -@property (nonatomic, copy) CNLiveDownloadCompletedBlock completedBlock; | |
| 20 | -@property (nonatomic, assign) CNLiveWebImageDownloadOptions options; | |
| 21 | -@property (nonatomic, strong) NSURL *url; | |
| 22 | - | |
| 23 | -@property (nonatomic, strong) NSURLSessionConfiguration *config; | |
| 24 | -@property (nonatomic, strong) NSURLSession *session; | |
| 25 | -@property (nonatomic, strong) NSURLSessionDataTask *dataTask; | |
| 26 | -@property (nonatomic, assign) NSInteger expectedSize; | |
| 27 | -@property (nonatomic, strong) NSMutableData *imageData; | |
| 28 | -@property (nonatomic, strong) NSURLResponse *response; | |
| 29 | - | |
| 30 | -@end | |
| 31 | - | |
| 32 | -@implementation CNLiveWebImageDownloadOperation | |
| 33 | - | |
| 34 | -- (id)initWithURL:(NSURL *)url options:(CNLiveWebImageDownloadOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed | |
| 35 | -{ | |
| 36 | - if ((self = [super init])) { | |
| 37 | - _url = url; | |
| 38 | - _progressBlock = progress; | |
| 39 | - _completedBlock = completed; | |
| 40 | - _options = options; | |
| 41 | - } | |
| 42 | - return self; | |
| 43 | -} | |
| 44 | - | |
| 45 | -- (void)start | |
| 46 | -{ | |
| 47 | - @synchronized (self) { | |
| 48 | - if (self.isCancelled) { | |
| 49 | - return; | |
| 50 | - } | |
| 51 | - } | |
| 52 | - self.dataTask = [self.session dataTaskWithURL:self.url]; | |
| 53 | - [self.dataTask resume]; | |
| 54 | - [self.session finishTasksAndInvalidate]; | |
| 55 | -} | |
| 56 | - | |
| 57 | -- (NSURLSessionConfiguration *)config | |
| 58 | -{ | |
| 59 | - if (!_config) { | |
| 60 | - if (self.options & CNLiveWebImageDownloadContinueInBackground) { | |
| 61 | - _config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:CNLiveWebImageBackgroundSessionIdentifier]; | |
| 62 | - } | |
| 63 | - else { | |
| 64 | - _config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; | |
| 65 | - } | |
| 66 | - } | |
| 67 | - return _config; | |
| 68 | -} | |
| 69 | - | |
| 70 | -- (NSURLSession *)session | |
| 71 | -{ | |
| 72 | - if (!_session) { | |
| 73 | - _session = [NSURLSession sessionWithConfiguration:self.config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; | |
| 74 | - } | |
| 75 | - return _session; | |
| 76 | -} | |
| 77 | - | |
| 78 | -#pragma mark <NSURLSessionDataDelegate> | |
| 79 | -- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler | |
| 80 | -{ | |
| 81 | - if (![response respondsToSelector:@selector(statusCode)] || ([((NSHTTPURLResponse *)response) statusCode] < 400 && [((NSHTTPURLResponse *)response) statusCode] != 304)) { | |
| 82 | - NSInteger expected = response.expectedContentLength > 0 ? (NSInteger)response.expectedContentLength : 0; | |
| 83 | - self.expectedSize = expected; | |
| 84 | - if (self.progressBlock) { | |
| 85 | - self.progressBlock(0, expected); | |
| 86 | - } | |
| 87 | - | |
| 88 | - self.imageData = [[NSMutableData alloc] initWithCapacity:expected]; | |
| 89 | - self.response = response; | |
| 90 | - completionHandler(NSURLSessionResponseAllow); | |
| 91 | - } | |
| 92 | - else { | |
| 93 | - | |
| 94 | - [self.dataTask cancel]; | |
| 95 | - | |
| 96 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 97 | - if (self.completedBlock) { | |
| 98 | - self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); | |
| 99 | - } | |
| 100 | - }); | |
| 101 | - } | |
| 102 | -} | |
| 103 | - | |
| 104 | -- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data | |
| 105 | -{ | |
| 106 | - [self.imageData appendData:data]; | |
| 107 | - if (self.options & CNLiveWebImageDownloadProgressiveDownload && self.completedBlock) { | |
| 108 | - const NSInteger totalSize = self.imageData.length; | |
| 109 | - CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)self.imageData, NULL); | |
| 110 | - if (totalSize < self.expectedSize) { | |
| 111 | - CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); | |
| 112 | - if (partialImageRef) { | |
| 113 | - UIImage *image = [UIImage imageWithCGImage:partialImageRef]; | |
| 114 | - CGImageRelease(partialImageRef); | |
| 115 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 116 | - if (self.completedBlock) { | |
| 117 | - self.completedBlock(image, self.imageData, nil, NO); | |
| 118 | - } | |
| 119 | - }); | |
| 120 | - } | |
| 121 | - } | |
| 122 | - | |
| 123 | - CFRelease(imageSource); | |
| 124 | - } | |
| 125 | - | |
| 126 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 127 | - if (self.progressBlock) { | |
| 128 | - self.progressBlock(self.imageData.length, self.expectedSize); | |
| 129 | - } | |
| 130 | - }); | |
| 131 | -} | |
| 132 | - | |
| 133 | -- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error | |
| 134 | -{ | |
| 135 | - if (error) { | |
| 136 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 137 | - if (self.completedBlock) { | |
| 138 | - self.completedBlock(nil, nil, error, NO); | |
| 139 | - } | |
| 140 | - }); | |
| 141 | - } | |
| 142 | - else { | |
| 143 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 144 | - if (self.completedBlock) { | |
| 145 | - self.completedBlock([UIImage ws_imageWithData:self.imageData], self.imageData, nil, YES); | |
| 146 | - } | |
| 147 | - }); | |
| 148 | - } | |
| 149 | -} | |
| 150 | - | |
| 151 | -- (void)cancel | |
| 152 | -{ | |
| 153 | - if (self.session) { | |
| 154 | - [self.session invalidateAndCancel]; | |
| 155 | - } | |
| 156 | - self.completedBlock = nil; | |
| 157 | - self.progressBlock = nil; | |
| 158 | - self.session = nil; | |
| 159 | - self.imageData = nil; | |
| 160 | -} | |
| 161 | - | |
| 162 | - | |
| 163 | - | |
| 164 | - | |
| 165 | - | |
| 166 | - | |
| 167 | - | |
| 168 | - | |
| 169 | - | |
| 170 | - | |
| 171 | - | |
| 172 | - | |
| 173 | - | |
| 174 | - | |
| 175 | -@end |
CNLiveWebImageManager.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageManager.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/27. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import <UIKit/UIKit.h> | |
| 11 | -#import "CNLiveWebImageBlock.h" | |
| 12 | -#import "CNLiveWebImageOperation.h" | |
| 13 | - | |
| 14 | -typedef NS_OPTIONS(NSUInteger, CNLiveWebImageOptions) { | |
| 15 | - CNLiveWebImageRetryFailed = 1 << 0, | |
| 16 | - CNLiveWebImageCacheMemoryOnly = 1 << 1, | |
| 17 | - CNLiveWebImageProgressiveDownload = 1 << 2, | |
| 18 | - CNLiveWebImageContinueInBackground = 1 << 3 | |
| 19 | -}; | |
| 20 | - | |
| 21 | -@interface CNLiveWebImageManager : NSObject | |
| 22 | - | |
| 23 | -+ (nonnull id)sharedManager; | |
| 24 | - | |
| 25 | -- (nonnull id <CNLiveWebImageOperation>)downloadWebImageWithURL:(nonnull NSURL *)url options:(CNLiveWebImageOptions)options progress:(nonnull CNLiveDownloadProgressBlock)progress completed:(nonnull CNLiveDownloadCompletedBlock)completed; | |
| 26 | - | |
| 27 | -- (void)storeImage:(nonnull UIImage *)image imageUrl:(nonnull NSURL *)url toDisk:(BOOL)toDisk; | |
| 28 | - | |
| 29 | -- (nullable UIImage *)imageFromMemoryCacheWithImageUrl:(nonnull NSURL *)url; | |
| 30 | - | |
| 31 | -- (nullable UIImage *)imageFromDiskCacheWithImageUrl:(nonnull NSURL *)url; | |
| 32 | - | |
| 33 | -- (BOOL)queryDiskCacheWithImageUrl:(nonnull NSURL *)url done:(nonnull CNLiveWebImageQueryCompletedBlock)doneBlock; | |
| 34 | - | |
| 35 | -- (void)removeCacheWithUrl:(nonnull NSURL *)url done:(nonnull CNLiveCompletedBlock)completed; | |
| 36 | - | |
| 37 | -- (long long)diskCacheSize; | |
| 38 | - | |
| 39 | -- (void)clearMemory; | |
| 40 | - | |
| 41 | -- (void)clearDisk; | |
| 42 | - | |
| 43 | -@end |
CNLiveWebImageManager.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveWebImageManager.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/27. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "CNLiveWebImageManager.h" | |
| 10 | -#import "CNLiveWebImageDownload.h" | |
| 11 | -#import "CNLiveImageCache.h" | |
| 12 | - | |
| 13 | -@interface CNLiveWebImageManager () | |
| 14 | - | |
| 15 | -@property (nonatomic, strong) CNLiveImageCache *imageCache; | |
| 16 | -@property (nonatomic, strong) NSMutableSet *failedURLs; | |
| 17 | - | |
| 18 | -@end | |
| 19 | - | |
| 20 | -@implementation CNLiveWebImageManager | |
| 21 | - | |
| 22 | -+ (id)sharedManager | |
| 23 | -{ | |
| 24 | - static id manager; | |
| 25 | - static dispatch_once_t once; | |
| 26 | - dispatch_once(&once, ^{ | |
| 27 | - manager = [self new]; | |
| 28 | - }); | |
| 29 | - return manager; | |
| 30 | -} | |
| 31 | - | |
| 32 | -- (instancetype)init | |
| 33 | -{ | |
| 34 | - if ((self = [super init])) { | |
| 35 | - _imageCache = [CNLiveImageCache sharedImageCache]; | |
| 36 | - _failedURLs = [NSMutableSet new]; | |
| 37 | - } | |
| 38 | - return self; | |
| 39 | -} | |
| 40 | - | |
| 41 | -- (id<CNLiveWebImageOperation>)downloadWebImageWithURL:(NSURL *)url options:(CNLiveWebImageOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed | |
| 42 | -{ | |
| 43 | - if ([url isKindOfClass:NSString.class]) { | |
| 44 | - url = [NSURL URLWithString:(NSString *)url]; | |
| 45 | - } | |
| 46 | - if (![url isKindOfClass:NSURL.class]) { | |
| 47 | - url = nil; | |
| 48 | - } | |
| 49 | - | |
| 50 | - BOOL isFailedUrl = NO; | |
| 51 | - @synchronized (self.failedURLs) { | |
| 52 | - isFailedUrl = [self.failedURLs containsObject:url]; | |
| 53 | - } | |
| 54 | - if (!url || (!(options & CNLiveWebImageRetryFailed) && isFailedUrl)) { | |
| 55 | - NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; | |
| 56 | - completed(nil, nil, error, YES); | |
| 57 | - } | |
| 58 | - | |
| 59 | - BOOL hasCacheImage = [self.imageCache queryDiskCacheForKey:url.absoluteString done:^(UIImage *image, CNLiveImageCacheType type) { | |
| 60 | - if (image) { | |
| 61 | - completed(image,UIImageJPEGRepresentation(image, 1.0), nil, YES); | |
| 62 | - } | |
| 63 | - }];; | |
| 64 | - | |
| 65 | - if (hasCacheImage) { | |
| 66 | - return nil; | |
| 67 | - } | |
| 68 | - | |
| 69 | - | |
| 70 | - CNLiveWebImageDownloadOptions downloadOptions = 0; | |
| 71 | - if (options & CNLiveWebImageProgressiveDownload) downloadOptions |= CNLiveWebImageDownloadProgressiveDownload; | |
| 72 | - if (options & CNLiveWebImageContinueInBackground) downloadOptions |= CNLiveWebImageDownloadContinueInBackground; | |
| 73 | - id <CNLiveWebImageOperation> operation = [[CNLiveWebImageDownload sharedDownload] downloadWebImageWithURL:url options:downloadOptions progress:progress completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { | |
| 74 | - if (error) { | |
| 75 | - BOOL shouldBeFailedURLAlliOSVersion = (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut); | |
| 76 | - BOOL shouldBeFailedURLiOS7 = (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1 && error.code != NSURLErrorInternationalRoamingOff && error.code != NSURLErrorCallIsActive && error.code != NSURLErrorDataNotAllowed); | |
| 77 | - if (shouldBeFailedURLAlliOSVersion || shouldBeFailedURLiOS7) { | |
| 78 | - @synchronized (self.failedURLs) { | |
| 79 | - [self.failedURLs addObject:url]; | |
| 80 | - } | |
| 81 | - } | |
| 82 | - } | |
| 83 | - else { | |
| 84 | - if ((options & CNLiveWebImageRetryFailed)) { | |
| 85 | - @synchronized (self.failedURLs) { | |
| 86 | - [self.failedURLs removeObject:url]; | |
| 87 | - } | |
| 88 | - } | |
| 89 | - | |
| 90 | - BOOL cacheOnDisk = !(options & CNLiveWebImageCacheMemoryOnly); | |
| 91 | - if (image && finished) { | |
| 92 | - if (cacheOnDisk) { | |
| 93 | - [self.imageCache storeImage:image forKey:[url absoluteString] toDisk:YES]; | |
| 94 | - } | |
| 95 | - else { | |
| 96 | - [self.imageCache storeImage:image forKey:[url absoluteString] toDisk:NO]; | |
| 97 | - } | |
| 98 | - } | |
| 99 | - | |
| 100 | - completed(image, data, error, finished); | |
| 101 | - } | |
| 102 | - | |
| 103 | - }]; | |
| 104 | - return operation; | |
| 105 | -} | |
| 106 | - | |
| 107 | -- (void)storeImage:(UIImage *)image imageUrl:(NSURL *)url toDisk:(BOOL)toDisk | |
| 108 | -{ | |
| 109 | - [self.imageCache storeImage:image forKey:url.absoluteString toDisk:toDisk]; | |
| 110 | -} | |
| 111 | - | |
| 112 | -- (UIImage *)imageFromMemoryCacheWithImageUrl:(NSURL *)url | |
| 113 | -{ | |
| 114 | - return [self.imageCache imageFromMemoryCacheForKey:url.absoluteString]; | |
| 115 | -} | |
| 116 | - | |
| 117 | -- (UIImage *)imageFromDiskCacheWithImageUrl:(NSURL *)url | |
| 118 | -{ | |
| 119 | - return [self.imageCache imageFromDiskCacheForKey:url.absoluteString]; | |
| 120 | -} | |
| 121 | - | |
| 122 | -- (BOOL)queryDiskCacheWithImageUrl:(NSURL *)url done:(CNLiveWebImageQueryCompletedBlock)doneBlock | |
| 123 | -{ | |
| 124 | - return [self.imageCache queryDiskCacheForKey:url.absoluteString done:doneBlock]; | |
| 125 | -} | |
| 126 | - | |
| 127 | -- (void)removeCacheWithUrl:(NSURL *)url done:(CNLiveCompletedBlock)completed | |
| 128 | -{ | |
| 129 | - [self.imageCache removeCacheForKey:url.absoluteString done:completed]; | |
| 130 | -} | |
| 131 | - | |
| 132 | -- (long long)diskCacheSize | |
| 133 | -{ | |
| 134 | - return [self.imageCache diskCacheSize]; | |
| 135 | -} | |
| 136 | - | |
| 137 | -- (void)clearMemory | |
| 138 | -{ | |
| 139 | - [self.imageCache clearMemory]; | |
| 140 | -} | |
| 141 | - | |
| 142 | -- (void)clearDisk | |
| 143 | -{ | |
| 144 | - [self.imageCache clearDisk]; | |
| 145 | -} | |
| 146 | - | |
| 147 | -@end |
CNLiveWebImageOperation.h deleted
100644 → 0
NSData+ImageContentType.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// NSData+ImageContentType.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/21. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -@interface NSData (ImageContentType) | |
| 12 | - | |
| 13 | -+ (NSString *)ws_imageContentTypeWithData:(NSData *)data; | |
| 14 | - | |
| 15 | -@end |
NSData+ImageContentType.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// NSData+ImageContentType.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/21. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "NSData+ImageContentType.h" | |
| 10 | - | |
| 11 | -@implementation NSData (ImageContentType) | |
| 12 | - | |
| 13 | -+ (NSString *)ws_imageContentTypeWithData:(NSData *)data | |
| 14 | -{ | |
| 15 | - uint8_t c; | |
| 16 | - [data getBytes:&c length:1]; | |
| 17 | - switch (c) { | |
| 18 | - case 0xFF: | |
| 19 | - return @"image/jpeg"; | |
| 20 | - case 0x89: | |
| 21 | - return @"image/png"; | |
| 22 | - case 0x47: | |
| 23 | - return @"image/gif"; | |
| 24 | - case 0x49: | |
| 25 | - case 0x4D: | |
| 26 | - return @"image/tiff"; | |
| 27 | - case 0x52: | |
| 28 | - | |
| 29 | - if ([data length] < 12) { | |
| 30 | - return nil; | |
| 31 | - } | |
| 32 | - | |
| 33 | - NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; | |
| 34 | - if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { | |
| 35 | - return @"image/webp"; | |
| 36 | - } | |
| 37 | - | |
| 38 | - return nil; | |
| 39 | - } | |
| 40 | - return nil; | |
| 41 | -} | |
| 42 | - | |
| 43 | -@end |
UIImage+MultiFormat.h deleted
100644 → 0
UIImage+MultiFormat.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// UIImage+MultiFormat.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/21. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "UIImage+MultiFormat.h" | |
| 10 | -#import "NSData+ImageContentType.h" | |
| 11 | - | |
| 12 | -@implementation UIImage (MultiFormat) | |
| 13 | - | |
| 14 | -+ (UIImage *)ws_imageWithData:(NSData *)data | |
| 15 | -{ | |
| 16 | - if (!data) { | |
| 17 | - return nil; | |
| 18 | - } | |
| 19 | - UIImage *image; | |
| 20 | - NSString *imageContentType = [NSData ws_imageContentTypeWithData:data]; | |
| 21 | - | |
| 22 | - if ([imageContentType isEqualToString:@"image/gif"]) { | |
| 23 | - //TODO 处理GIF图片 | |
| 24 | - } | |
| 25 | - else if ([imageContentType isEqualToString:@"image/webp"]) { | |
| 26 | - //TODO 处理WEBP图片 | |
| 27 | - } | |
| 28 | - else { | |
| 29 | - image = [[UIImage alloc] initWithData:data]; | |
| 30 | - } | |
| 31 | - return image; | |
| 32 | -} | |
| 33 | - | |
| 34 | -@end |
UIImageView+WebCache.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// UIImageView+WebCache.h | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/26. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <UIKit/UIKit.h> | |
| 10 | -#import "CNLiveWebImageManager.h" | |
| 11 | - | |
| 12 | -@interface UIImageView (WebCache) | |
| 13 | - | |
| 14 | -- (void)ws_setImageWithUrl:(NSURL *)url; | |
| 15 | - | |
| 16 | -- (void)ws_setImageWithUrl:(NSURL *)url placeholderImage:(UIImage *)placeholder; | |
| 17 | - | |
| 18 | -@end |
UIImageView+WebCache.m deleted
100644 → 0
| 1 | -// | |
| 2 | -// UIImageView+WebCache.m | |
| 3 | -// WSWebImageDemo | |
| 4 | -// | |
| 5 | -// Created by 王帅 on 16/7/26. | |
| 6 | -// Copyright © 2016年 王帅. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import "UIImageView+WebCache.h" | |
| 10 | -#import "CNLiveWebImageBlock.h" | |
| 11 | - | |
| 12 | -@implementation UIImageView (WebCache) | |
| 13 | - | |
| 14 | -- (void)ws_setImageWithUrl:(NSURL *)url | |
| 15 | -{ | |
| 16 | - [self ws_setImageWithUrl:url placeholderImage:nil options:0 progress:nil completed:nil]; | |
| 17 | -} | |
| 18 | - | |
| 19 | -- (void)ws_setImageWithUrl:(NSURL *)url placeholderImage:(UIImage *)placeholder | |
| 20 | -{ | |
| 21 | - [self ws_setImageWithUrl:url placeholderImage:placeholder options:0 progress:nil completed:nil]; | |
| 22 | -} | |
| 23 | - | |
| 24 | -- (void)ws_setImageWithUrl:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(CNLiveWebImageOptions)options progress:(CNLiveDownloadProgressBlock)progress completed:(CNLiveDownloadCompletedBlock)completed | |
| 25 | -{ | |
| 26 | - if (placeholder) { | |
| 27 | - self.image = placeholder; | |
| 28 | - } | |
| 29 | - | |
| 30 | - if (url) { | |
| 31 | - __weak __typeof(self) weakSelf = self; | |
| 32 | - [[CNLiveWebImageManager sharedManager] downloadWebImageWithURL:url | |
| 33 | - options:options | |
| 34 | - progress:progress | |
| 35 | - completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { | |
| 36 | - if (image && !error && finished) { | |
| 37 | - weakSelf.image = image; | |
| 38 | - } | |
| 39 | - }]; | |
| 40 | - } | |
| 41 | - else { | |
| 42 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 43 | - NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; | |
| 44 | - if (completed) { | |
| 45 | - completed(nil, nil, error, NO); | |
| 46 | - } | |
| 47 | - }); | |
| 48 | - } | |
| 49 | - | |
| 50 | -} | |
| 51 | - | |
| 52 | -@end |