//
|
// UIImageView+EzvizOpenSDK.m
|
// EZOpenSDKDemo
|
//
|
// Created by DeJohn Dong on 15/11/18.
|
// Copyright © 2015年 Ezviz. All rights reserved.
|
//
|
|
#import "UIImageView+EzvizOpenSDK.h"
|
#import <objc/runtime.h>
|
#import "AFHTTPRequestOperation.h"
|
|
@interface EZDataCache : NSCache <EZDataCache>
|
@end
|
|
@interface UIImageView ()
|
@property (readwrite, nonatomic, strong, setter = ez_setImageRequestOperation:) AFHTTPRequestOperation *ez_imageRequestOperation;
|
@end
|
|
@implementation UIImageView (EzvizOpenSDK)
|
|
+ (id <EZDataCache>)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 <EZDataCache>)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
|