转:http://blog.csdn.net/marujunyy/article/details/18424711

由于ASIHTTPRequest 不再更新了,不能使用block感觉不太好用;最后选择了AFNetWorking,并做了进一步的封装。


需要导入的framework:CFNetworkSecuritySystemConfigurationMobileCoreServices


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

  1. //  
  2. //  HttpManager.h  
  3. //  HLMagic  
  4. //  
  5. //  Created by marujun on 14-1-17.  
  6. //  Copyright (c) 2014年 jizhi. All rights reserved.  
  7. //  
  8.   
  9. #import <Foundation/Foundation.h>  
  10. #import <CommonCrypto/CommonDigest.h>  
  11. #import "AFNetworking.h"  
  12. #import "Reachability.h"  
  13.   
  14. @interface NSString (HttpManager)  
  15. - (NSString *)md5;  
  16. - (NSString *)encode;  
  17. - (NSString *)decode;  
  18. - (NSString *)object;  
  19. @end  
  20.   
  21. @interface NSObject (HttpManager)  
  22. - (NSString *)json;  
  23. @end  
  24.   
  25. @interface HttpManager : NSObject  
  26.   
  27. + (HttpManager *)defaultManager;  
  28.   
  29. /*  -------判断当前的网络类型---------- 
  30.  1、NotReachable     - 没有网络连接 
  31.  2、ReachableViaWWAN - 移动网络(2G、3G) 
  32.  3、ReachableViaWiFi - WIFI网络 
  33.  */  
  34. + (NetworkStatus)networkStatus;  
  35.   
  36. //GET 请求  
  37. - (void)getRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete;  
  38. - (void)getCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete;  //请求失败时使用缓存数据  
  39.   
  40. //POST 请求  
  41. - (void)postRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete;  
  42.   
  43. /* 
  44.  files : 需要上传的文件数组,数组里为多个字典 
  45.  字典里的key: 
  46.  1、name: 文件名称(如:demo.jpg) 
  47.  2、file: 文件   (支持四种数据类型:NSData、UIImage、NSURL、NSString)NSURL、NSString为文件路径 
  48.  3、type: 文件类型(默认:image/jpeg) 
  49.  示例: @[@{@"file":_headImg.currentBackgroundImage,@"name":@"head.jpg"}]; 
  50.  */  
  51.   
  52. //AFHTTPRequestOperation可以暂停、重新开启、取消 [operation pause]、[operation resume];、[operation cancel];  
  53. - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url  
  54.                                  params:(NSDictionary *)params  
  55.                                   files:(NSArray *)files  
  56.                                complete:(void (^)(BOOL successed, NSDictionary *result))complete;  
  57.   
  58.   
  59. //可以查看进度 process_block  
  60. - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url  
  61.                                  params:(NSDictionary *)params  
  62.                                   files:(NSArray *)files  
  63.                                 process:(void (^)(NSInteger writedBytes, NSInteger totalBytes))process  
  64.                                complete:(void (^)(BOOL successed, NSDictionary *result))complete;  
  65. /* 
  66.  filePath : 下载文件的存储路径 
  67.  response : 接口返回的不是文件而是json数据 
  68.  process  : 进度 
  69.  */  
  70. - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url  
  71.                                    filePath:(NSString *)filePath  
  72.                                    complete:(void (^)(BOOL successed, NSDictionary *response))complete;  
  73.   
  74. - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url  
  75.                                      params:(NSDictionary *)params  
  76.                                    filePath:(NSString *)filePath  
  77.                                     process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process  
  78.                                    complete:(void (^)(BOOL successed, NSDictionary *response))complete;  
  79.   
  80. @end  


// "HttpManager.m"

  1. //  
  2. //  HttpManager.m  
  3. //  HLMagic  
  4. //  
  5. //  Created by marujun on 14-1-17.  
  6. //  Copyright (c) 2014年 jizhi. All rights reserved.  
  7. //  
  8.   
  9. #import "HttpManager.h"  
  10.   
  11. @implementation NSString (HttpManager)  
  12. - (NSString *)md5  
  13. {  
  14.     if(self == nil || [self length] == 0){  
  15.         return nil;  
  16.     }  
  17.     const char *value = [self UTF8String];  
  18.       
  19.     unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];  
  20.     CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);  
  21.       
  22.     NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];  
  23.     for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){  
  24.         [outputString appendFormat:@"%02x",outputBuffer[count]];  
  25.     }  
  26.       
  27.     return outputString;  
  28. }  
  29. - (NSString *)encode  
  30. {  
  31.     NSString *outputStr = (NSString *)  
  32.     CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,  
  33.                                                               (CFStringRef)self,  
  34.                                                               NULL,  
  35.                                                               NULL,  
  36.                                                               kCFStringEncodingUTF8));  
  37.     return outputStr;  
  38. }  
  39. - (NSString *)decode  
  40. {  
  41.     NSMutableString *outputStr = [NSMutableString stringWithString:self];  
  42.     [outputStr replaceOccurrencesOfString:@"+" withString:@" " options:NSLiteralSearch range:NSMakeRange(0, [outputStr length])];  
  43.     return [outputStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];  
  44. }  
  45. - (id)object  
  46. {  
  47.     id object = nil;  
  48.     @try {  
  49.         NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];;  
  50.         object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];  
  51.     }  
  52.     @catch (NSException *exception) {  
  53.         NSLog(@"%s [Line %d] JSON字符串转换成对象出错了-->\n%@",__PRETTY_FUNCTION__, __LINE__,exception);  
  54.     }  
  55.     @finally {  
  56.     }  
  57.     return object;  
  58. }  
  59. @end  
  60. @implementation NSObject (HttpManager)  
  61. - (NSString *)json  
  62. {  
  63.     NSString *jsonStr = @"";  
  64.     @try {  
  65.         NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:0 error:nil];  
  66.         jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];  
  67.     }  
  68.     @catch (NSException *exception) {  
  69.         NSLog(@"%s [Line %d] 对象转换成JSON字符串出错了-->\n%@",__PRETTY_FUNCTION__, __LINE__,exception);  
  70.     }  
  71.     @finally {  
  72.     }  
  73.     return jsonStr;  
  74. }  
  75. @end  
  76.   
  77. @interface HttpManager ()  
  78. {  
  79.     AFHTTPRequestOperationManager *operationManager;  
  80. }  
  81. @end  
  82.   
  83. @implementation HttpManager  
  84.   
  85. - (id)init{  
  86.     self = [super init];  
  87.     if (self) {  
  88.         operationManager = [AFHTTPRequestOperationManager manager];  
  89.         operationManager.responseSerializer.acceptableContentTypes = nil;  
  90.           
  91.         NSURLCache *urlCache = [NSURLCache sharedURLCache];  
  92.         [urlCache setMemoryCapacity:5*1024*1024];  /* 设置缓存的大小为5M*/  
  93.         [NSURLCache setSharedURLCache:urlCache];  
  94.     }  
  95.     return self;  
  96. }  
  97.   
  98.   
  99. + (HttpManager *)defaultManager  
  100. {  
  101.     static dispatch_once_t pred = 0;  
  102.     __strong static id defaultHttpManager = nil;  
  103.     dispatch_once( &pred, ^{  
  104.         defaultHttpManager = [[self alloc] init];  
  105.     });  
  106.     return defaultHttpManager;  
  107. }  
  108.   
  109. - (void)getRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  110. {  
  111.     [self requestToUrl:url method:@"GET" useCache:NO params:params complete:complete];  
  112. }  
  113.   
  114. - (void)getCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  115. {  
  116.     [self requestToUrl:url method:@"GET" useCache:YES params:params complete:complete];  
  117. }  
  118.   
  119. - (void)postRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  120. {  
  121.     [self requestToUrl:url method:@"POST" useCache:NO params:params complete:complete];  
  122. }  
  123.   
  124. - (void)requestToUrl:(NSString *)url method:(NSString *)method useCache:(BOOL)useCache  
  125.               params:(NSDictionary *)params complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  126. {  
  127.     params = [[HttpManager getRequestBodyWithParams:params] copy];  
  128.       
  129.     AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];  
  130.     NSMutableURLRequest *request = [serializer requestWithMethod:method URLString:url parameters:params error:nil];  
  131.       
  132.     [request setTimeoutInterval:10];  
  133.     if (useCache) {  
  134.         [request setCachePolicy:NSURLRequestReturnCacheDataElseLoad];  
  135.     }  
  136.       
  137.     void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {  
  138.         [self showMessageWithOperation:operation method:method params:params];  
  139.           
  140.         complete ? complete(true,responseObject) : nil;  
  141.     };  
  142.     void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {  
  143.         [self showMessageWithOperation:operation method:method params:params];  
  144.           
  145.         complete ? complete(false,nil) : nil;  
  146.     };  
  147.       
  148.     AFHTTPRequestOperation *operation = nil;  
  149.     if (useCache) {  
  150.         operation = [self cacheOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];  
  151.     }else{  
  152.         operation = [operationManager HTTPRequestOperationWithRequest:request success:requestSuccessBlock failure:requestFailureBlock];  
  153.     }  
  154.     [operationManager.operationQueue addOperation:operation];  
  155. }  
  156.   
  157. - (AFHTTPRequestOperation *)cacheOperationWithRequest:(NSURLRequest *)urlRequest  
  158.                                               success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success  
  159.                                               failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure  
  160. {  
  161.     AFHTTPRequestOperation *operation = [operationManager HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject){  
  162.         NSCachedURLResponse *cachedURLResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];  
  163.           
  164.         //store in cache  
  165.         cachedURLResponse = [[NSCachedURLResponse alloc] initWithResponse:operation.response data:operation.responseData userInfo:nil storagePolicy:NSURLCacheStorageAllowed];  
  166.         [[NSURLCache sharedURLCache] storeCachedResponse:cachedURLResponse forRequest:urlRequest];  
  167.           
  168.         success(operation,responseObject);  
  169.           
  170.     }failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  171.         if (error.code == kCFURLErrorNotConnectedToInternet) {  
  172.             NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];  
  173.             if (cachedResponse != nil && [[cachedResponse data] length] > 0) {  
  174.                 success(operation, cachedResponse.data);  
  175.             } else {  
  176.                 failure(operation, error);  
  177.             }  
  178.         } else {  
  179.             failure(operation, error);  
  180.         }  
  181.     }];  
  182.       
  183.     return operation;  
  184. }  
  185.   
  186. - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url  
  187.                                  params:(NSDictionary *)params  
  188.                                   files:(NSArray *)files  
  189.                                complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  190. {  
  191.     return [self uploadToUrl:url params:params files:files process:nil complete:complete];  
  192. }  
  193.   
  194. - (AFHTTPRequestOperation *)uploadToUrl:(NSString *)url  
  195.                                  params:(NSDictionary *)params  
  196.                                   files:(NSArray *)files  
  197.                                 process:(void (^)(NSInteger writedBytes, NSInteger totalBytes))process  
  198.                                complete:(void (^)(BOOL successed, NSDictionary *result))complete  
  199. {  
  200.     params = [[HttpManager getRequestBodyWithParams:params] copy];  
  201.     FLOG(@"post request url:  %@  \npost params:  %@",url,params);  
  202.       
  203.     AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];  
  204.       
  205.     NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {  
  206.         for (NSDictionary *fileItem in files) {  
  207.             id value = [fileItem objectForKey:@"file"];    //支持四种数据类型:NSData、UIImage、NSURL、NSString  
  208.             NSString *name = @"file";                                   //字段名称  
  209.             NSString *fileName = [fileItem objectForKey:@"name"];       //文件名称  
  210.             NSString *mimeType = [fileItem objectForKey:@"type"];       //文件类型  
  211.             mimeType = mimeType ? mimeType : @"image/jpeg";  
  212.               
  213.             if ([value isKindOfClass:[NSData class]]) {  
  214.                 [formData appendPartWithFileData:value name:name fileName:fileName mimeType:mimeType];  
  215.             }else if ([value isKindOfClass:[UIImage class]]) {  
  216.                 if (UIImagePNGRepresentation(value)) {  //返回为png图像。  
  217.                     [formData appendPartWithFileData:UIImagePNGRepresentation(value) name:name fileName:fileName mimeType:mimeType];  
  218.                 }else {   //返回为JPEG图像。  
  219.                     [formData appendPartWithFileData:UIImageJPEGRepresentation(value, 0.5) name:name fileName:fileName mimeType:mimeType];  
  220.                 }  
  221.             }else if ([value isKindOfClass:[NSURL class]]) {  
  222.                 [formData appendPartWithFileURL:value name:name fileName:fileName mimeType:mimeType error:nil];  
  223.             }else if ([value isKindOfClass:[NSString class]]) {  
  224.                 [formData appendPartWithFileURL:[NSURL URLWithString:value]  name:name fileName:fileName mimeType:mimeType error:nil];  
  225.             }  
  226.         }  
  227.     } error:nil];  
  228.       
  229.     AFHTTPRequestOperation *operation = nil;  
  230.     operation = [operationManager HTTPRequestOperationWithRequest:request  
  231.                                                  success:^(AFHTTPRequestOperation *operation, id responseObject) {  
  232.                                                      FLOG(@"post responseObject:  %@",responseObject);  
  233.                                                      if (complete) {  
  234.                                                          complete(true,responseObject);  
  235.                                                      }  
  236.                                                  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  237.                                                      FLOG(@"post error :  %@",error);  
  238.                                                      if (complete) {  
  239.                                                          complete(false,nil);  
  240.                                                      }  
  241.                                                  }];  
  242.       
  243.     [operation setUploadProgressBlock:^(NSUInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {  
  244.         FLOG(@"upload process: %.2d%% (%ld/%ld)",100*totalBytesWritten/totalBytesExpectedToWrite,(long)totalBytesWritten,(long)totalBytesExpectedToWrite);  
  245.         if (process) {  
  246.             process(totalBytesWritten,totalBytesExpectedToWrite);  
  247.         }  
  248.     }];  
  249.     [operation start];  
  250.       
  251.     return operation;  
  252. }  
  253.   
  254. - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url  
  255.                                    filePath:(NSString *)filePath  
  256.                                    complete:(void (^)(BOOL successed, NSDictionary *response))complete  
  257. {  
  258.     return [self downloadFromUrl:url params:nil filePath:filePath process:nil complete:complete];  
  259. }  
  260.   
  261. - (AFHTTPRequestOperation *)downloadFromUrl:(NSString *)url  
  262.                                      params:(NSDictionary *)params  
  263.                                    filePath:(NSString *)filePath  
  264.                                     process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process  
  265.                                    complete:(void (^)(BOOL successed, NSDictionary *response))complete  
  266. {  
  267.     params = [[HttpManager getRequestBodyWithParams:params] copy];  
  268.       
  269.     AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];  
  270.     NSMutableURLRequest *request = [serializer requestWithMethod:@"GET" URLString:url parameters:params error:nil];  
  271.     FLOG(@"get request url: %@",[request.URL.absoluteString decode]);  
  272.       
  273.     AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];  
  274.     operation.responseSerializer.acceptableContentTypes = nil;  
  275.       
  276.     NSString *tmpPath = [filePath stringByAppendingString:@".tmp"];  
  277.     operation.outputStream=[[NSOutputStream alloc] initToFileAtPath:tmpPath append:NO];  
  278.       
  279.     [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {  
  280.         NSArray *mimeTypeArray = @[@"text/html", @"application/json"];  
  281.         NSError *moveError = nil;  
  282.         if ([mimeTypeArray containsObject:operation.response.MIMEType]) {  
  283.             //返回的是json格式数据  
  284.             responseObject = [NSData dataWithContentsOfFile:tmpPath];  
  285.             responseObject = [NSJSONSerialization JSONObjectWithData:responseObject options:2 error:nil];  
  286.             [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];  
  287.             FLOG(@"get responseObject:  %@",responseObject);  
  288.         }else{  
  289.             [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];  
  290.             [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:&moveError];  
  291.         }  
  292.           
  293.         if (complete && !moveError) {  
  294.             complete(true,responseObject);  
  295.         }else{  
  296.             complete?complete(false,responseObject):nil;  
  297.         }  
  298.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {  
  299.         FLOG(@"get error :  %@",error);  
  300.         [[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];  
  301.         if (complete) {  
  302.             complete(false,nil);  
  303.         }  
  304.     }];  
  305.     [operation setDownloadProgressBlock:^(NSUInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) {  
  306.         FLOG(@"download process: %.2d%% (%ld/%ld)",100*totalBytesRead/totalBytesExpectedToRead,(long)totalBytesRead,(long)totalBytesExpectedToRead);  
  307.         if (process) {  
  308.             process(totalBytesRead,totalBytesExpectedToRead);  
  309.         }  
  310.     }];  
  311.       
  312.     [operation start];  
  313.       
  314.     return operation;  
  315. }  
  316.   
  317. + (NSMutableDictionary *)getRequestBodyWithParams:(NSDictionary *)params  
  318. {  
  319.     NSMutableDictionary *requestBody = params?[params mutableCopy]:[[NSMutableDictionary alloc] init];  
  320.       
  321.     for (NSString *key in [params allKeys]){  
  322.         id value = [params objectForKey:key];  
  323.         if ([value isKindOfClass:[NSDate class]]) {  
  324.             [requestBody setValue:@([value timeIntervalSince1970]*1000) forKey:key];  
  325.         }  
  326.         if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {  
  327.             [requestBody setValue:[value json] forKey:key];  
  328.         }  
  329.     }  
  330.       
  331.     NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"token"];  
  332.     if (token){  
  333.         [requestBody setObject:token forKey:@"token"];  
  334.     }  
  335.     [requestBody setObject:@"ios" forKey:@"genus"];  
  336.       
  337.     return requestBody;  
  338. }  
  339.   
  340. + (NetworkStatus)networkStatus  
  341. {  
  342.     Reachability *reachability = [Reachability reachabilityWithHostname:@"www.apple.com"];  
  343.     // NotReachable     - 没有网络连接  
  344.     // ReachableViaWWAN - 移动网络(2G、3G)  
  345.     // ReachableViaWiFi - WIFI网络  
  346.     return [reachability currentReachabilityStatus];  
  347. }  
  348.   
  349.   
  350. - (void)showMessageWithOperation:(AFHTTPRequestOperation *)operation method:(NSString *)method params:(NSDictionary *)params  
  351. {  
  352.     NSString *urlAbsoluteString = [operation.request.URL.absoluteString decode];  
  353.     if ([[method uppercaseString] isEqualToString:@"GET"]) {  
  354.         FLOG(@"get request url:  %@  \n",urlAbsoluteString);  
  355.     }else{  
  356.         FLOG(@"%@ request url:  %@  \npost params:  %@\n",[method lowercaseString],urlAbsoluteString,params);  
  357.     }  
  358.     if (operation.error) {  
  359.         FLOG(@"%@ error :  %@",[method lowercaseString],operation.error);  
  360.     }else{  
  361.         FLOG(@"%@ responseObject:  %@",[method lowercaseString],operation.responseObject);  
  362.     }  
  363.       
  364. //    //只显示一部分url  
  365. //    NSArray *ignordUrls = @[url_originalDataDownload,url_originalDataUpload,url_originalDataUploadFinished,url_getEarliestOriginalData,url_newVersion,  
  366. //                            url_saveSyncFailInfo];  
  367. //    for (NSString *ignordUrl in ignordUrls) {  
  368. //        if ([urlAbsoluteString rangeOfString:ignordUrl].length) {  
  369. //            return;  
  370. //        }  
  371. //    }  
  372. //    //弹出网络提示  
  373. //  if (!operation.error) {  
  374. //      if ([operation.responseObject objectForKey:@"msg"] && [[operation.responseObject objectForKey:@"msg"] length]) {  
  375. //          [KeyWindow showAlertMessage:[operation.responseObject objectForKey:@"msg"] callback:nil];  
  376. //      }  
  377. //  }  
  378. //  else {  
  379. //        if (operation.error.code == kCFURLErrorNotConnectedToInternet) {  
  380. //            [KeyWindow showAlertMessage:@"您已断开网络连接" callback:nil];  
  381. //        } else {  
  382. //            [KeyWindow showAlertMessage:@"服务器忙,请稍后再试" callback:nil];  
  383. //        }  
  384. //  }  
  385. }  
  386.   
  387. @end  


图片缓存类,用于缓存图片;并写了UIImageView和UIButton的扩展方法;可直接设置其对应图片的URL。


//  ImageCache.h

  1. //  
  2. //  ImageCache.h  
  3. //  CoreDataUtil  
  4. //  
  5. //  Created by marujun on 14-1-18.  
  6. //  Copyright (c) 2014年 jizhi. All rights reserved.  
  7. //  
  8.   
  9. #import <UIKit/UIKit.h>  
  10. #import <UIKit/UIImageView.h>  
  11. #import <UIKit/UIButton.h>  
  12. #import <objc/runtime.h>  
  13.   
  14. #define ADD_DYNAMIC_PROPERTY(PROPERTY_TYPE,PROPERTY_NAME,SETTER_NAME) \  
  15. @dynamic PROPERTY_NAME ; \  
  16. static char kProperty##PROPERTY_NAME; \  
  17. - ( PROPERTY_TYPE ) PROPERTY_NAME{ \  
  18. return ( PROPERTY_TYPE ) objc_getAssociatedObject(self, &(kProperty##PROPERTY_NAME ) ); \  
  19. } \  
  20. - (void) SETTER_NAME :( PROPERTY_TYPE ) PROPERTY_NAME{ \  
  21. objc_setAssociatedObject(self, &kProperty##PROPERTY_NAME , PROPERTY_NAME , OBJC_ASSOCIATION_RETAIN); \  
  22. } \  
  23.   
  24. @interface UIImage (ImageCache)  
  25. @property(nonatomic, strong)NSString *lastCacheUrl;  
  26.   
  27. /* ********************----------***************************** 
  28.  1、UIImage 的扩展方法,用于缓存图片;如果图片已下载则使用本地图片 
  29.  2、下载完成之后会执行回调,并可查看下载进度 
  30.  ********************----------******************************/  
  31.   
  32. + (void)imageWithURL:(NSString *)url callback:(void(^)(UIImage *image))callback;  
  33.   
  34. + (void)imageWithURL:(NSString *)url  
  35.              process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process  
  36.             callback:(void(^)(UIImage *image))callback;  
  37.   
  38. /*通过URL获取缓存图片在本地对应的路径*/  
  39. + (NSString *)getImagePathWithURL:(NSString *)url;  
  40.   
  41. @end  
  42.   
  43. @interface UIImageView (ImageCache)  
  44. @property(nonatomic, strong)NSString *lastCacheUrl;  
  45.   
  46. /*设置UIImageView的图片的URL,下载失败设置图片为空*/  
  47. - (void)setImageURL:(NSString *)url;  
  48.   
  49. /*设置UIImageView的图片的URL,下载失败则使用默认图片设置*/  
  50. - (void)setImageURL:(NSString *)url defaultImage:(UIImage *)defaultImage;  
  51.   
  52. /*设置UIImageView的图片的URL,下载完成之后先设置图片然后执行回调函数*/  
  53. - (void)setImageURL:(NSString *)url callback:(void(^)(UIImage *image))callback;  
  54.   
  55. @end  
  56.   
  57. @interface UIButton (ImageCache)  
  58. @property(nonatomic, strong)NSString *lastCacheUrl;  
  59.   
  60. /*设置按钮的图片的URL,下载失败设置图片为空*/  
  61. - (void)setImageURL:(NSString *)url forState:(UIControlState)state;  
  62.   
  63. /*设置按钮的图片的URL,下载失败则使用默认图片设置*/  
  64. - (void)setImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage;  
  65.   
  66. /*设置按钮的图片的URL,下载完成之后先设置图片然后执行回调函数*/  
  67. - (void)setImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback;  
  68.   
  69.   
  70.   
  71. /*设置按钮的背景图片的URL,下载失败设置图片为空*/  
  72. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state;  
  73.   
  74. /*设置按钮的背景图片的URL,下载失败则使用默认图片设置*/  
  75. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage;  
  76.   
  77. /*设置按钮的背景图片的URL,下载完成之后先设置图片然后执行回调函数*/  
  78. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback;  
  79.   
  80. @end  


//  ImageCache.m

  1. //  
  2. //  ImageCache.m  
  3. //  CoreDataUtil  
  4. //  
  5. //  Created by marujun on 14-1-18.  
  6. //  Copyright (c) 2014年 jizhi. All rights reserved.  
  7. //  
  8.   
  9. #import "ImageCache.h"  
  10. #import "HttpManager.h"  
  11.   
  12. static NSMutableArray *downloadTaskArray_ImageCache;  
  13. static BOOL isDownloading_ImageCache;  
  14.   
  15. @implementation UIImage (ImageCache)  
  16. ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);  
  17.   
  18. + (void)imageWithURL:(NSString *)url callback:(void(^)(UIImage *image))callback  
  19. {  
  20.     [self imageWithURL:url process:nil callback:callback];  
  21. }  
  22.   
  23. + (void)imageWithURL:(NSString *)url  
  24.              process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process  
  25.             callback:(void(^)(UIImage *image))callback  
  26. {  
  27.     if (!downloadTaskArray_ImageCache) {  
  28.         downloadTaskArray_ImageCache = [[NSMutableArray alloc] init];  
  29.     }  
  30.       
  31.     NSString *filePath = [self getImagePathWithURL:url];  
  32.       
  33.     if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {  
  34.         UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];  
  35.         lastImage.lastCacheUrl = url?url:@"";  
  36.         callback ? callback(lastImage) : nil;  
  37.     }else{  
  38.         NSMutableDictionary *task = [[NSMutableDictionary alloc] init];  
  39.         url?[task setObject:url forKey:@"url"]:nil;  
  40.         process?[task setObject:process forKey:@"process"]:nil;  
  41.         callback?[task setObject:callback forKey:@"callback"]:nil;  
  42.         [downloadTaskArray_ImageCache addObject:task];  
  43.           
  44.         [self startDownload];  
  45.     }  
  46. }  
  47.   
  48. + (void)startDownload  
  49. {  
  50.     if (downloadTaskArray_ImageCache.count && !isDownloading_ImageCache) {  
  51.         NSDictionary *lastObj = [downloadTaskArray_ImageCache lastObject];  
  52.         [self downloadWithURL:lastObj[@"url"] process:lastObj[@"process"] callback:lastObj[@"callback"]];  
  53.     }  
  54. }  
  55.   
  56. + (void)downloadWithURL:(NSString *)url  
  57.                 process:(void (^)(NSInteger readBytes, NSInteger totalBytes))process  
  58.                callback:(void(^)(UIImage *image))callback  
  59. {  
  60.     NSString *filePath = [self getImagePathWithURL:url];  
  61.     NSMutableDictionary *task = [[NSMutableDictionary alloc] init];  
  62.     url?[task setObject:url forKey:@"url"]:nil;  
  63.     process?[task setObject:process forKey:@"process"]:nil;  
  64.     callback?[task setObject:callback forKey:@"callback"]:nil;  
  65.     isDownloading_ImageCache = true;  
  66.       
  67.     if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {  
  68.         UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];  
  69.         lastImage.lastCacheUrl = url?url:@"";  
  70.         callback ? callback(lastImage) : nil;  
  71.           
  72.         [downloadTaskArray_ImageCache removeObject:task];  
  73.         isDownloading_ImageCache = false;  
  74.         [self startDownload];  
  75.     }else{  
  76.         [[HttpManager defaultManager] downloadFromUrl:url  
  77.                                                params:nil  
  78.                                              filePath:filePath  
  79.                                               process:process  
  80.                                              complete:^(BOOL successed, NSDictionary *result) {  
  81.                                                  if (callback) {  
  82.                                                      if (successed && !result) {  
  83.                                                          UIImage *lastImage = [UIImage imageWithContentsOfFile:filePath];  
  84.                                                          lastImage.lastCacheUrl = url?url:@"";  
  85.                                                          callback ? callback(lastImage) : nil;  
  86.                                                      }else{  
  87.                                                          callback(nil);  
  88.                                                      }  
  89.                                                  }  
  90.                                                  [downloadTaskArray_ImageCache removeObject:task];  
  91.                                                  isDownloading_ImageCache = false;  
  92.                                                  [self startDownload];  
  93.                                              }];  
  94.     }  
  95. }  
  96.   
  97. + (NSString *)getImagePathWithURL:(NSString *)url  
  98. {  
  99.     //先创建个缓存文件夹  
  100.     NSString *directory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches/imgcache"];  
  101.     NSFileManager *defaultManager = [NSFileManager defaultManager];  
  102.     if (![defaultManager fileExistsAtPath:directory]) {  
  103.         [defaultManager createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];  
  104.     }  
  105.       
  106.     return [directory stringByAppendingPathComponent:[url md5]];  
  107. }  
  108.   
  109. @end  
  110.   
  111. @implementation UIImageView (ImageCache)  
  112. ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);  
  113.   
  114. - (void)setImageURL:(NSString *)url  
  115. {  
  116.     [self setImageURL:url callback:nil];  
  117. }  
  118. - (void)setImageURL:(NSString *)url defaultImage:(UIImage *)defaultImage  
  119. {  
  120.     defaultImage ? self.image=defaultImage : nil;  
  121.     self.lastCacheUrl = url;  
  122.       
  123.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  124.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  125.             image ? self.image=image : nil;  
  126.         }  
  127.     }];  
  128. }  
  129. - (void)setImageURL:(NSString *)url callback:(void(^)(UIImage *image))callback  
  130. {  
  131.     self.lastCacheUrl = url;  
  132.       
  133.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  134.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  135.             image ? self.image=image : nil;  
  136.         }  
  137.         callback ? callback(image) : nil;  
  138.     }];  
  139. }  
  140.   
  141. @end  
  142.   
  143. @implementation UIButton (ImageCache)  
  144. ADD_DYNAMIC_PROPERTY(NSString *,lastCacheUrl,setLastCacheUrl);  
  145.   
  146. - (void)setImageURL:(NSString *)url forState:(UIControlState)state  
  147. {  
  148.     [self setImageURL:url forState:state defaultImage:nil];  
  149. }  
  150. - (void)setImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage  
  151. {  
  152.     defaultImage ? [self setImage:defaultImage forState:state] : nil;  
  153.     self.lastCacheUrl = url;  
  154.       
  155.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  156.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  157.             image ? [self setImage:image forState:state] : nil;  
  158.         }  
  159.     }];  
  160. }  
  161. - (void)setImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback  
  162. {  
  163.     self.lastCacheUrl = url;  
  164.       
  165.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  166.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  167.             image ? [self setImage:image forState:state] : nil;  
  168.         }  
  169.         callback ? callback(image) : nil;  
  170.     }];  
  171. }  
  172.   
  173.   
  174. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state  
  175. {  
  176.     [self setBackgroundImageURL:url forState:state defaultImage:nil];  
  177. }  
  178. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state defaultImage:(UIImage *)defaultImage  
  179. {  
  180.     defaultImage ? [self setBackgroundImage:defaultImage forState:state] : nil;  
  181.     self.lastCacheUrl = url;  
  182.       
  183.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  184.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  185.             image ? [self setBackgroundImage:image forState:state] : nil;  
  186.         }  
  187.     }];  
  188. }  
  189. - (void)setBackgroundImageURL:(NSString *)url forState:(UIControlState)state callback:(void(^)(UIImage *image))callback  
  190. {  
  191.     self.lastCacheUrl = url;  
  192.       
  193.     [UIImage imageWithURL:url callback:^(UIImage *image) {  
  194.         if ([image.lastCacheUrl isEqualToString:self.lastCacheUrl]) {  
  195.             image ? [self setBackgroundImage:image forState:state] : nil;  
  196.         }  
  197.         callback ? callback(image) : nil;  
  198.     }];  
  199. }  
  200.   
  201. @end  




  1. /*  使用示例 */  
  2.      NSString *url = @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=4c2a6e019058d109c4e3aeb2e560cdbf/b812c8fcc3cec3fd6d7daa0ad488d43f87942709.jpg";  
  3.       
  4.     //缓存图片  
  5. //    [UIImage imageWithURL:url process:^(NSInteger readBytes, NSInteger totalBytes) {  
  6. //        NSLog(@"下载进度 : %.0f%%",100*readBytes/totalBytes);  
  7. //    } callback:^(UIImage *image) {  
  8. //        NSLog(@"图片下载完成!");  
  9. //    }];  
  10.      
  11.     //设置UIImageView的图片,下载失败则使用默认图片  
  12.     UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];  
  13.     [imageView setImageURL:url defaultImage:[UIImage imageNamed:@"default.png"]];  
  14.     imageView.contentMode = UIViewContentModeScaleAspectFit;  
  15.     [self.view addSubview:imageView];  
  16.       
  17.     //设置UIButton的图片,下载失败则使用默认图片  
  18.     UIButton *button = [[UIButton alloc] initWithFrame:self.view.bounds];  
  19.     [button setImageURL:url forState:UIControlStateNormal defaultImage:[UIImage imageNamed:@"default.png"]];  
  20.     [self.view addSubview:button];  

GitHub 地址:https://github.com/marujun/DataManager



posted on 2014-08-20 20:04  jackljf  阅读(254)  评论(0编辑  收藏  举报