// // UIImageView+EzvizOpenSDK.m // EZOpenSDKDemo // // Created by DeJohn Dong on 15/11/18. // Copyright © 2015年 Ezviz. All rights reserved. // #import "UIImageView+EzvizOpenSDK.h" #import #import "AFHTTPRequestOperation.h" @interface EZDataCache : NSCache @end @interface UIImageView () @property (readwrite, nonatomic, strong, setter = ez_setImageRequestOperation:) AFHTTPRequestOperation *ez_imageRequestOperation; @end @implementation UIImageView (EzvizOpenSDK) + (id )sharedDataCache { static EZDataCache *_ez_defaultDataCache = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _ez_defaultDataCache = [[EZDataCache alloc] init]; [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * __unused notification) { [_ez_defaultDataCache removeAllObjects]; }]; }); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" return objc_getAssociatedObject(self, @selector(sharedDataCache)) ?: _ez_defaultDataCache; #pragma clang diagnostic pop } + (void)setSharedDataCache:(__nullable id )dataCache { objc_setAssociatedObject(self, @selector(sharedDataCache), dataCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - + (NSOperationQueue *)ez_sharedImageRequestOperationQueue { static NSOperationQueue *_ez_sharedImageRequestOperationQueue = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _ez_sharedImageRequestOperationQueue = [[NSOperationQueue alloc] init]; _ez_sharedImageRequestOperationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; }); return _ez_sharedImageRequestOperationQueue; } - (AFHTTPRequestOperation *)ez_imageRequestOperation { return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(ez_imageRequestOperation)); } - (void)ez_setImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation { objc_setAssociatedObject(self, @selector(ez_imageRequestOperation), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (void)ez_setImageWithURLRequest:(NSURLRequest *)urlRequest placeholderImage:(UIImage *)placeholderImage success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, NSData *data))success failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, NSError *error))failure { [self cancelImageRequestOperation]; NSData *cachedData = [[[self class] sharedDataCache] cachedDataForRequest:urlRequest]; if (cachedData) { if (success) { success(urlRequest, nil, cachedData); } else { self.image = [[UIImage alloc] initWithData:cachedData]; } self.ez_imageRequestOperation = nil; } else { if (placeholderImage) { self.image = placeholderImage; } __weak __typeof(self)weakSelf = self; self.ez_imageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; [self.ez_imageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[urlRequest URL] isEqual:[strongSelf.ez_imageRequestOperation.request URL]]) { if (success) { success(urlRequest, operation.response, responseObject); } else if (responseObject) { strongSelf.image = responseObject; } if (operation == strongSelf.ez_imageRequestOperation){ strongSelf.ez_imageRequestOperation = nil; } } [[[strongSelf class] sharedDataCache] cacheData:responseObject forRequest:urlRequest]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[urlRequest URL] isEqual:[strongSelf.ez_imageRequestOperation.request URL]]) { if (failure) { failure(urlRequest, operation.response, error); } if (operation == strongSelf.ez_imageRequestOperation){ strongSelf.ez_imageRequestOperation = nil; } } }]; } //处理测试环境下证书不合法的情况,正式线上可以注释该代码。 [self.ez_imageRequestOperation setWillSendRequestForAuthenticationChallengeBlock:^(NSURLConnection * _Nonnull connection, NSURLAuthenticationChallenge * _Nonnull challenge) { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { // 证书不认证 全部信任 [[challenge sender] useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; [[challenge sender] continueWithoutCredentialForAuthenticationChallenge: challenge]; } }]; [[[self class] ez_sharedImageRequestOperationQueue] addOperation:self.ez_imageRequestOperation]; } - (void)cancelImageRequestOperation { [self.ez_imageRequestOperation cancel]; self.ez_imageRequestOperation = nil; } @end #pragma mark - static inline NSString * EZDataCacheKeyFromURLRequest(NSURLRequest *request) { return [[request URL] absoluteString]; } @implementation EZDataCache - (NSData *)cachedDataForRequest:(NSURLRequest *)request { switch ([request cachePolicy]) { case NSURLRequestReloadIgnoringCacheData: case NSURLRequestReloadIgnoringLocalAndRemoteCacheData: return nil; default: break; } return [self objectForKey:EZDataCacheKeyFromURLRequest(request)]; } - (void)cacheData:(NSData *)data forRequest:(NSURLRequest *)request { if (data && request) { [self setObject:data forKey:EZDataCacheKeyFromURLRequest(request)]; } } @end