转:http://blog.csdn.net/marujunyy/article/details/18424711
由于ASIHTTPRequest 不再更新了,不能使用block感觉不太好用;最后选择了AFNetWorking,并做了进一步的封装。
需要导入的framework:CFNetwork、Security、SystemConfiguration、MobileCoreServices
GitHub:https://github.com/AFNetworking/AFNetworking
最新的版本为2.0支持iOS 6.0以上系统,在iOS 5上可能报错:Property
with 'retain (or strong)' attribute must be of object type
下面是封装的类:
// HttpManager.h
- //
- // HttpManager.h
- // HLMagic
- //
- // Created by marujun on 14-1-17.
- // Copyright (c) 2014年 jizhi. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import <CommonCrypto/CommonDigest.h>
- #import "AFNetworking.h"
- #import "Reachability.h"
- @interface NSString (HttpManager)
- - (NSString *)md5;
- - (NSString *)encode;
- - (NSString *)decode;
- - (NSString *)object;
- @end
- @interface NSObject (HttpManager)
- - (NSString *)json;
- @end
- @interface HttpManager : NSObject
- + (HttpManager *)defaultManager;
- /* -------判断当前的网络类型----------
- 1、NotReachable - 没有网络连接
- 2、ReachableViaWWAN - 移动网络(2G、3G)
- 3、ReachableViaWiFi - WIFI网络
- */
- + (NetworkStatus)networkStatus;
- //GET 请求
- - (void)getRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete;
- - (void)getCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete; //请求失败时使用缓存数据
- //POST 请求
- - (void)postRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete;
- /*
- files : 需要上传的文件数组,数组里为多个字典
- 字典里的key:
- 1、name: 文件名称(如:demo.jpg)
- 2、file: 文件 (支持四种数据类型:NSData、UIImage、NSURL、NSString)NSURL、NSString为文件路径
- 3、type: 文件类型(默认:image/jpeg)
- 示例: @[@{@"file":_headImg.currentBackgroundImage,@"name":@"head.jpg"}];
- */
- //AFHTTPRequestOperation可以暂停、重新开启、取消 [operation pause]、[operation resume];、[operation cancel];
- - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url
- params:(NSDictionary *)params
- files:(NSArray *)files
- complete:(void (^)(BOOL successed, NSDictionary *result))complete;
- //可以查看进度 process_block
- - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url
- params:(NSDictionary *)params
- files:(NSArray *)files
- process:(void (^)(NSInteger writedBytes, NSInteger totalBytes))process
- complete:(void (^)(BOOL successed, NSDictionary *result))complete;
- /*
- filePath : 下载文件的存储路径
- response : 接口返回的不是文件而是json数据
- process : 进度
- */
- - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url
- filePath:(NSString *)filePath
- complete:(void (^)(BOOL successed, NSDictionary *response))complete;
- - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url
- params:(NSDictionary *)params
- filePath:(NSString *)filePath
- process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process
- complete:(void (^)(BOOL successed, NSDictionary *response))complete;
- @end
// "HttpManager.m"
- //
- // HttpManager.m
- // HLMagic
- //
- // Created by marujun on 14-1-17.
- // Copyright (c) 2014年 jizhi. All rights reserved.
- //
- #import "HttpManager.h"
- @implementation NSString (HttpManager)
- - (NSString *)md5
- {
- if(self == nil || [self length] == 0){
- return nil;
- }
- const char *value = [self UTF8String];
- unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
- CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);
- NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
- for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
- [outputString appendFormat:@"%02x",outputBuffer[count]];
- }
- return outputString;
- }
- - (NSString *)encode
- {
- NSString *outputStr = (NSString *)
- CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
- (CFStringRef)self,
- NULL,
- NULL,
- kCFStringEncodingUTF8));
- return outputStr;
- }
- - (NSString *)decode
- {
- NSMutableString *outputStr = [NSMutableString stringWithString:self];
- [outputStr replaceOccurrencesOfString:@"+" withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [outputStr length])];
- return [outputStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- }
- - (id)object
- {
- id object = nil;
- @try {
- NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];;
- object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
- }
- @catch (NSException *exception) {
- NSLog(@"%s [Line %d] JSON字符串转换成对象出错了-->\n%@",__PRETTY_FUNCTION__, __LINE__,exception);
- }
- @finally {
- }
- return object;
- }
- @end
- @implementation NSObject (HttpManager)
- - (NSString *)json
- {
- NSString *jsonStr = @"";
- @try {
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:0 error:nil];
- jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
- }
- @catch (NSException *exception) {
- NSLog(@"%s [Line %d] 对象转换成JSON字符串出错了-->\n%@",__PRETTY_FUNCTION__, __LINE__,exception);
- }
- @finally {
- }
- return jsonStr;
- }
- @end
- @interface HttpManager ()
- {
- AFHTTPRequestOperationManager *operationManager;
- }
- @end
- @implementation HttpManager
- - (id)init{
- self = [super init];
- if (self) {
- operationManager = [AFHTTPRequestOperationManager manager];
- operationManager.responseSerializer.acceptableContentTypes = nil;
- NSURLCache *urlCache = [NSURLCache sharedURLCache];
- [urlCache setMemoryCapacity:5*1024*1024]; /* 设置缓存的大小为5M*/
- [NSURLCache setSharedURLCache:urlCache];
- }
- return self;
- }
- + (HttpManager *)defaultManager
- {
- static dispatch_once_t pred = 0;
- __strong static id defaultHttpManager = nil;
- dispatch_once( &pred, ^{
- defaultHttpManager = [[self alloc] init];
- });
- return defaultHttpManager;
- }
- - (void)getRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- [self requestToUrl:url method:@"GET" useCache:NO params:params complete:complete];
- }
- - (void)getCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- [self requestToUrl:url method:@"GET" useCache:YES params:params complete:complete];
- }
- - (void)postRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- [self requestToUrl:url method:@"POST" useCache:NO params:params complete:complete];
- }
- - (void)requestToUrl:(NSString *)url method:(NSString *)method useCache:(BOOL)useCache
- params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- params = [[HttpManager getRequestBodyWithParams:params] copy];
- AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
- NSMutableURLRequest *request = [serializer requestWithMethod:method URLString:url parameters:params error:nil];
- [request setTimeoutInterval:10];
- if (useCache) {
- [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
- }
- void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {
- [self showMessageWithOperation:operation method:method params:params];
- complete ? complete(true,responseObject) : nil;
- };
- void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {
- [self showMessageWithOperation:operation method:method params:params];
- complete ? complete(false,nil) : nil;
- };
- AFHTTPRequestOperation *operation = nil;
- if (useCache) {
- operation = [self cacheOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];
- }else{
- operation = [operationManager HTTPRequestOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];
- }
- [operationManager.operationQueue addOperation:operation];
- }
- - (AFHTTPRequestOperation *)cacheOperationWithRequest:(NSURLRequest *)urlRequest
- success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
- failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
- {
- AFHTTPRequestOperation *operation = [operationManager HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject){
- NSCachedURLResponse *cachedURLResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];
- //store in cache
- cachedURLResponse = [[NSCachedURLResponse alloc] initWithResponse:operation.response data:operation.responseData userInfo:nil storagePolicy:NSURLCacheStorageAllowed];
- [[NSURLCache sharedURLCache] storeCachedResponse:cachedURLResponse forRequest:urlRequest];
- success(operation,responseObject);
- }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
- if (error.code == kCFURLErrorNotConnectedToInternet) {
- NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];
- if (cachedResponse != nil && [[cachedResponse data] length] > 0) {
- success(operation, cachedResponse.data);
- } else {
- failure(operation, error);
- }
- } else {
- failure(operation, error);
- }
- }];
- return operation;
- }
- - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url
- params:(NSDictionary *)params
- files:(NSArray *)files
- complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- return [self uploadToUrl:url params:params files:files process:nil complete:complete];
- }
- - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url
- params:(NSDictionary *)params
- files:(NSArray *)files
- process:(void (^)(NSInteger writedBytes, NSInteger totalBytes))process
- complete:(void (^)(BOOL successed, NSDictionary *result))complete
- {
- params = [[HttpManager getRequestBodyWithParams:params] copy];
- FLOG(@"post request url: %@ \npost params: %@",url,params);
- AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
- NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
- for (NSDictionary *fileItem in files) {
- id value = [fileItem objectForKey:@"file"]; //支持四种数据类型:NSData、UIImage、NSURL、NSString
- NSString *name = @"file"; //字段名称
- NSString *fileName = [fileItem objectForKey:@"name"]; //文件名称
- NSString *mimeType = [fileItem objectForKey:@"type"]; //文件类型
- mimeType = mimeType ? mimeType : @"image/jpeg";
- if ([value isKindOfClass:[NSData class]]) {
- [formData appendPartWithFileData:value name:name fileName:fileName mimeType:mimeType];
- }else if ([value isKindOfClass:[UIImage class]]) {
- if (UIImagePNGRepresentation(value)) { //返回为png图像。
- [formData appendPartWithFileData:UIImagePNGRepresentation(value) name:name fileName:fileName mimeType:mimeType];
- }else { //返回为JPEG图像。
- [formData appendPartWithFileData:UIImageJPEGRepresentation(value, 0.5) name:name fileName:fileName mimeType:mimeType];
- }
- }else if ([value isKindOfClass:[NSURL class]]) {
- [formData appendPartWithFileURL:value name:name fileName:fileName mimeType:mimeType error:nil];
- }else if ([value isKindOfClass:[NSString class]]) {
- [formData appendPartWithFileURL:[NSURL URLWithString:value] name:name fileName:fileName mimeType:mimeType error:nil];
- }
- }
- } error:nil];
- AFHTTPRequestOperation *operation = nil;
- operation = [operationManager HTTPRequestOperationWithRequest:request
- success:^(AFHTTPRequestOperation *operation, id responseObject) {
- FLOG(@"post responseObject: %@",responseObject);
- if (complete) {
- complete(true,responseObject);
- }
- } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
- FLOG(@"post error : %@",error);
- if (complete) {
- complete(false,nil);
- }
- }];
- [operation setUploadProgressBlock:^(NSUInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
- FLOG(@"upload process: %.2d%% (%ld/%ld)",100*totalBytesWritten/totalBytesExpectedToWrite,(long)totalBytesWritten,(long)totalBytesExpectedToWrite);
- if (process) {
- process(totalBytesWritten,totalBytesExpectedToWrite);
- }
- }];
- [operation start];
- return operation;
- }
- - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url
- filePath:(NSString *)filePath
- complete:(void (^)(BOOL successed, NSDictionary *response))complete
- {
- return [self downloadFromUrl:url params:nil filePath:filePath process:nil complete:complete];
- }
- - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url
- params:(NSDictionary *)params
- filePath:(NSString *)filePath
- process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process
- complete:(void (^)(BOOL successed, NSDictionary *response))complete
- {
- params = [[HttpManager getRequestBodyWithParams:params] copy];
- AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
- NSMutableURLRequest *request = [serializer requestWithMethod:@"GET" URLString:url parameters:params error:nil];
- FLOG(@"get request url: %@",[request.URL.absoluteString decode]);
- AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
- operation.responseSerializer.acceptableContentTypes = nil;
- NSString *tmpPath = [filePath stringByAppendingString:@".tmp"];
- operation.outputStream=[[NSOutputStream alloc] initToFileAtPath:tmpPath append:NO];
- [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
- NSArray *mimeTypeArray = @[@"text/html", @"application/json"];
- NSError *moveError = nil;
- if ([mimeTypeArray containsObject:operation.response.MIMEType]) {
- //返回的是json格式数据
- responseObject = [NSData dataWithContentsOfFile:tmpPath];
- responseObject = [NSJSONSerialization JSONObjectWithData:responseObject options:2 error:nil];
- [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
- FLOG(@"get responseObject: %@",responseObject);
- }else{
- [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
- [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:&moveError];
- }
- if (complete && !moveError) {
- complete(true,responseObject);
- }else{
- complete?complete(false,responseObject):nil;
- }
- } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
- FLOG(@"get error : %@",error);
- [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
- if (complete) {
- complete(false,nil);
- }
- }];
- [operation setDownloadProgressBlock:^(NSUInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) {
- FLOG(@"download process: %.2d%% (%ld/%ld)",100*totalBytesRead/totalBytesExpectedToRead,(long)totalBytesRead,(long)totalBytesExpectedToRead);
- if (process) {
- process(totalBytesRead,totalBytesExpectedToRead);
- }
- }];
- [operation start];
- return operation;
- }
- + (NSMutableDictionary *)getRequestBodyWithParams:(NSDictionary *)params
- {
- NSMutableDictionary *requestBody = params?[params mutableCopy]:[[NSMutableDictionary alloc] init];
- for (NSString *key in [params allKeys]){
- id value = [params objectForKey:key];
- if ([value isKindOfClass:[NSDate class]]) {
- [requestBody setValue:@([value timeIntervalSince1970]*1000) forKey:key];
- }
- if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
- [requestBody setValue:[value json] forKey:key];
- }
- }
- NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"token"];
- if (token){
- [requestBody setObject:token forKey:@"token"];
- }
- [requestBody setObject:@"ios" forKey:@"genus"];
- return requestBody;
- }
- + (NetworkStatus)networkStatus
- {
- Reachability *reachability = [Reachability reachabilityWithHostname:@"www.apple.com"];
- // NotReachable - 没有网络连接
- // ReachableViaWWAN - 移动网络(2G、3G)
- // ReachableViaWiFi - WIFI网络
- return [reachability currentReachabilityStatus];
- }
- - (void)showMessageWithOperation:(AFHTTPRequestOperation *)operation method:(NSString *)method params:(NSDictionary *)params
- {
- NSString *urlAbsoluteString = [operation.request.URL.absoluteString decode];
- if ([[method uppercaseString] isEqualToString:@"GET"]) {
- FLOG(@"get request url: %@ \n",urlAbsoluteString);
- }else{
- FLOG(@"%@ request url: %@ \npost params: %@\n",[method lowercaseString],urlAbsoluteString,params);
- }
- if (operation.error) {
- FLOG(@"%@ error : %@",[method lowercaseString],operation.error);
- }else{
- FLOG(@"%@ responseObject: %@",[method lowercaseString],operation.responseObject);
- }
- // //只显示一部分url
- // NSArray *ignordUrls = @[url_originalDataDownload,url_originalDataUpload,url_originalDataUploadFinished,url_getEarliestOriginalData,url_newVersion,
- // url_saveSyncFailInfo];
- // for (NSString *ignordUrl in ignordUrls) {
- // if ([urlAbsoluteString rangeOfString:ignordUrl].length) {
- // return;
- // }
- // }
- // //弹出网络提示
- // if (!operation.error) {
- // if ([operation.responseObject objectForKey:@"msg"] && [[operation.responseObject objectForKey:@"msg"] length]) {
- // [KeyWindow showAlertMessage:[operation.responseObject objectForKey:@"msg"] callback:nil];
- // }
- // }
- // else {
- // if (operation.error.code == kCFURLErrorNotConnectedToInternet) {
- // [KeyWindow showAlertMessage:@"您已断开网络连接" callback:nil];
- // } else {
- // [KeyWindow showAlertMessage:@"服务器忙,请稍后再试" callback:nil];
- // }
- // }
- }
- @end
图片缓存类,用于缓存图片;并写了UIImageView和UIButton的扩展方法;可直接设置其对应图片的URL。
// ImageCache.h
- //
- // ImageCache.h
- // CoreDataUtil
- //
- // Created by marujun on 14-1-18.
- // Copyright (c) 2014年 jizhi. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- #import <UIKit/UIImageView.h>
- #import <UIKit/UIButton.h>
- #import <objc/runtime.h>
- #define ADD_DYNAMIC_PROPERTY(PROPERTY_TYPE,PROPERTY_NAME,SETTER_NAME) \
- @dynamic PROPERTY_NAME ; \
- static char kProperty##PROPERTY_NAME; \
- - ( PROPERTY_TYPE ) PROPERTY_NAME{ \
- return ( PROPERTY_TYPE ) objc_getAssociatedObject(self, &(kProperty##PROPERTY_NAME ) ); \
- } \
- - (void) SETTER_NAME :( PROPERTY_TYPE ) PROPERTY_NAME{ \
- objc_setAssociatedObject(self, &kProperty##PROPERTY_NAME , PROPERTY_NAME , OBJC_ASSOCIATION_RETAIN); \
- } \
- @interface UIImage (ImageCache)
- @property(nonatomic, strong)NSString *lastCacheUrl;
- /* ********************----------*****************************
- 1、UIImage 的扩展方法,用于缓存图片;如果图片已下载则使用本地图片
- 2、下载完成之后会执行回调,并可查看下载进度
- ********************----------******************************/
- + (void)imageWithURL:(NSString *)url callback:(void(^)(UIImage *image))callback;
- + (void)imageWithURL:(NSString *)url
- process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process
- callback:(void(^)(UIImage *image))callback;
- /*通过URL获取缓存图片在本地对应的路径*/
- + (NSString *)getImagePathWithURL:(NSString *)url;
- @end
- @interface UIImageView (ImageCache)
- @property(nonatomic, strong)NSString *lastCacheUrl;
- /*设置UIImageView的图片的URL,下载失败设置图片为空*/
- - (void)setImageURL:(NSString *)url;
- /*设置UIImageView的图片的URL,下载失败则使用默认图片设置*/
- - (void)setImageURL:(NSString *)url defaultImage:(UIImage *)defaultImage;
- /*设置UIImageView的图片的URL,下载完成之后先设置图片然后执行回调函数*/
- - (void)setImageURL:(NSString *)url callback:(void(^)(UIImage *image))callback;
- @end
- @interface UIButton (ImageCache)
- @property(nonatomic, strong)NSString *lastCacheUrl;
- /*设置按钮的图片的URL,下载失败设置图片为空*/
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state;
- /*设置按钮的图片的URL,下载失败则使用默认图片设置*/
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage;
- /*设置按钮的图片的URL,下载完成之后先设置图片然后执行回调函数*/
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback;
- /*设置按钮的背景图片的URL,下载失败设置图片为空*/
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state;
- /*设置按钮的背景图片的URL,下载失败则使用默认图片设置*/
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage;
- /*设置按钮的背景图片的URL,下载完成之后先设置图片然后执行回调函数*/
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback;
- @end
// ImageCache.m
- //
- // ImageCache.m
- // CoreDataUtil
- //
- // Created by marujun on 14-1-18.
- // Copyright (c) 2014年 jizhi. All rights reserved.
- //
- #import "ImageCache.h"
- #import "HttpManager.h"
- static NSMutableArray *downloadTaskArray_ImageCache;
- static BOOL isDownloading_ImageCache;
- @implementation UIImage (ImageCache)
- ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);
- + (void)imageWithURL:(NSString *)url callback:(void(^)(UIImage *image))callback
- {
- [self imageWithURL:url process:nil callback:callback];
- }
- + (void)imageWithURL:(NSString *)url
- process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process
- callback:(void(^)(UIImage *image))callback
- {
- if (!downloadTaskArray_ImageCache) {
- downloadTaskArray_ImageCache = [[NSMutableArray alloc] init];
- }
- NSString *filePath = [self getImagePathWithURL:url];
- if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
- UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];
- lastImage.lastCacheUrl = url?url:@"";
- callback ? callback(lastImage) : nil;
- }else{
- NSMutableDictionary *task = [[NSMutableDictionary alloc] init];
- url?[task setObject:url forKey:@"url"]:nil;
- process?[task setObject:process forKey:@"process"]:nil;
- callback?[task setObject:callback forKey:@"callback"]:nil;
- [downloadTaskArray_ImageCache addObject:task];
- [self startDownload];
- }
- }
- + (void)startDownload
- {
- if (downloadTaskArray_ImageCache.count && !isDownloading_ImageCache) {
- NSDictionary *lastObj = [downloadTaskArray_ImageCache lastObject];
- [self downloadWithURL:lastObj[@"url"] process:lastObj[@"process"] callback:lastObj[@"callback"]];
- }
- }
- + (void)downloadWithURL:(NSString *)url
- process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process
- callback:(void(^)(UIImage *image))callback
- {
- NSString *filePath = [self getImagePathWithURL:url];
- NSMutableDictionary *task = [[NSMutableDictionary alloc] init];
- url?[task setObject:url forKey:@"url"]:nil;
- process?[task setObject:process forKey:@"process"]:nil;
- callback?[task setObject:callback forKey:@"callback"]:nil;
- isDownloading_ImageCache = true;
- if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
- UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];
- lastImage.lastCacheUrl = url?url:@"";
- callback ? callback(lastImage) : nil;
- [downloadTaskArray_ImageCache removeObject:task];
- isDownloading_ImageCache = false;
- [self startDownload];
- }else{
- [[HttpManager defaultManager] downloadFromUrl:url
- params:nil
- filePath:filePath
- process:process
- complete:^(BOOL successed, NSDictionary *result) {
- if (callback) {
- if (successed && !result) {
- UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];
- lastImage.lastCacheUrl = url?url:@"";
- callback ? callback(lastImage) : nil;
- }else{
- callback(nil);
- }
- }
- [downloadTaskArray_ImageCache removeObject:task];
- isDownloading_ImageCache = false;
- [self startDownload];
- }];
- }
- }
- + (NSString *)getImagePathWithURL:(NSString *)url
- {
- //先创建个缓存文件夹
- NSString *directory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/imgcache"];
- NSFileManager *defaultManager = [NSFileManager defaultManager];
- if (![defaultManager fileExistsAtPath:directory]) {
- [defaultManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];
- }
- return [directory stringByAppendingPathComponent:[url md5]];
- }
- @end
- @implementation UIImageView (ImageCache)
- ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);
- - (void)setImageURL:(NSString *)url
- {
- [self setImageURL:url callback:nil];
- }
- - (void)setImageURL:(NSString *)url defaultImage:(UIImage *)defaultImage
- {
- defaultImage ? self.image=defaultImage : nil;
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? self.image=image : nil;
- }
- }];
- }
- - (void)setImageURL:(NSString *)url callback:(void(^)(UIImage *image))callback
- {
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? self.image=image : nil;
- }
- callback ? callback(image) : nil;
- }];
- }
- @end
- @implementation UIButton (ImageCache)
- ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state
- {
- [self setImageURL:url forState:state defaultImage:nil];
- }
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage
- {
- defaultImage ? [self setImage:defaultImage forState:state] : nil;
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? [self setImage:image forState:state] : nil;
- }
- }];
- }
- - (void)setImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback
- {
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? [self setImage:image forState:state] : nil;
- }
- callback ? callback(image) : nil;
- }];
- }
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state
- {
- [self setBackgroundImageURL:url forState:state defaultImage:nil];
- }
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage
- {
- defaultImage ? [self setBackgroundImage:defaultImage forState:state] : nil;
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? [self setBackgroundImage:image forState:state] : nil;
- }
- }];
- }
- - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback
- {
- self.lastCacheUrl = url;
- [UIImage imageWithURL:url callback:^(UIImage *image) {
- if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {
- image ? [self setBackgroundImage:image forState:state] : nil;
- }
- callback ? callback(image) : nil;
- }];
- }
- @end
- /* 使用示例 */
- NSString *url = @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=4c2a6e019058d109c4e3aeb2e560cdbf/b812c8fcc3cec3fd6d7daa0ad488d43f87942709.jpg";
- //缓存图片
- // [UIImage imageWithURL:url process:^(NSInteger readBytes, NSInteger totalBytes) {
- // NSLog(@"下载进度 : %.0f%%",100*readBytes/totalBytes);
- // } callback:^(UIImage *image) {
- // NSLog(@"图片下载完成!");
- // }];
- //设置UIImageView的图片,下载失败则使用默认图片
- UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
- [imageView setImageURL:url defaultImage:[UIImage imageNamed:@"default.png"]];
- imageView.contentMode = UIViewContentModeScaleAspectFit;
- [self.view addSubview:imageView];
- //设置UIButton的图片,下载失败则使用默认图片
- UIButton *button = [[UIButton alloc] initWithFrame:self.view.bounds];
- [button setImageURL:url forState:UIControlStateNormal defaultImage:[UIImage imageNamed:@"default.png"]];
- [self.view addSubview:button];
GitHub 地址:https://github.com/marujun/DataManager