由于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
// 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