[
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 吴海超\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# WHCNetWorkKit 网络操作开源库\n\n###咨询QQ:712641411     \n###开发作者：吴海超\n\n###目前封装最好使用最简单的文件下载(支持后台下载)iOS网络开源库 该版本进行了增强包括如下功能:\n###GET/POST网络请求/多文件上传/后台文件下载/网络状态监控/UIButton,UIImageView 设置网络图片等功能模块。\n###封装网络常用工具类json/xml 转模型类对象 json/xml 解析\n###文件下载模块代理可以自由替换代理或者回调块具体详情请参看自带demo\n\n###安装集成方式\n```ruby\nplatform :ios, '7.0'\npod \"WHCNetWorkKit\", \"~> 0.0.3\"\n```\n\n##运行效果\n![](https://github.com/netyouli/WHCNetWorkKit/blob/master/show.gif)\n\n###网络状态监听 Use Example\n```objective-c\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n// Override point for customization after application launch.\n    [[WHC_HttpManager shared] registerNetworkStatusMoniterEvent];\n    return YES;\n}\n\n/// 在其他地方可以这样[WHC_HttpManager shared].networkStatus获取当前网络状态\n   （该网络库每次进行请求都自动处理了网络状态不需要用户进行判断）\nswitch ([WHC_HttpManager shared].networkStatus) {\n    case NotReachable:{\n        [[[UIAlertView alloc]initWithTitle:nil\n        message:@\"当前网络不可用请检查网络设置\"\n        delegate:nil cancelButtonTitle:@\"确定\"\n        otherButtonTitles:nil, nil] show];\n    }\n    break;\n    case ReachableViaWiFi:\n        NSLog(@\"====当前网络状态为Wifi=======\");\n    break;\n    case ReachableViaWWAN:\n        NSLog(@\"====当前网络状态为3G=======\");\n    break;\n}\n\n```\n\n\n###GET请求 Use Example\n```objective-c\n[[WHC_HttpManager shared] get:@\"http://www.baidu.com/\"\n                  didFinished:^(WHC_BaseOperation *operation,\n                                                NSData *data,\n                                                NSError *error,\n                                                BOOL isSuccess) {\n     //处理data数据\n}];\n\n\n```\n\n\n###POST 请求 Use Example\n\n```objective-c\n\n[[WHC_HttpManager shared] post:@\"http://www.baidu.com\"\n                         param:@\"whc\"\n                   didFinished:^(WHC_BaseOperation *operation,\n                                                 NSData *data, \n                                               NSError *error,\n                                               BOOL isSuccess) {\n        //处理data数据\n}];\n```\n\n###多文件上传 Use Example\n```objective-c\n//上传5个文件\nfor (int i = 0; i < 5; i++) {\n    UIImage * image = [UIImage imageNamed:@\"whc\"];\n    NSData * imageData = UIImageJPEGRepresentation(image, 0.5);\n    [[WHC_HttpManager shared] addUploadFileData:imageData withFileName:[NSString stringWithFormat:@\"image%d\",i] mimeType:@\"image/jpep\" forKey:@\"file\"];\n    //最后一个参数key必须和服务端对应\n}\n[[WHC_HttpManager shared] upload:@\"http://www.baidu.com\"\n                           param:@\"param\" didFinished:^(WHC_BaseOperation *operation,\n                                                                            NSData *data,\n                                                                            NSError *error,\n                                                                            BOOL isSuccess) {\n        //处理上传结果数据\n}];\n\n```\n\n###普通文件下载 Use Example\n```objective-c\nWHC_DownloadOperation * downloadTask = nil;\ndownloadTask = [[WHC_HttpManager shared] download:kWHC_DefaultDownloadUrl\n                                         savePath:[WHC_DownloadObject videoDirectory]\n                                     saveFileName:fileName\n                                         response:^(WHC_BaseOperation *operation, NSError *error, BOOL isOK) {\n                                        if (isOK) {\n                                            [weakSelf.view toast:@\"已经添加到下载队列\"];\n                                            WHC_DownloadOperation * downloadOperation = (WHC_DownloadOperation*)operation;\n                                            WHC_DownloadObject * downloadObject = [WHC_DownloadObject new];\n                                            downloadObject.fileName = downloadOperation.saveFileName;\n                                            downloadObject.downloadPath = downloadOperation.strUrl;\n                                            downloadObject.downloadState = WHCDownloading;\n                                            downloadObject.currentDownloadLenght = downloadOperation.recvDataLenght;\n                                            downloadObject.totalLenght = downloadOperation.fileTotalLenght;\n                                            [downloadObject writeDiskCache];\n                                        }else {\n                                            [weakSelf.view toast:error.userInfo[NSLocalizedDescriptionKey]];\n                                        }\n                                    } process:^(WHC_BaseOperation *operation, uint64_t recvLength, uint64_t totalLength, NSString *speed) {\n                                            NSLog(@\"recvLength = %llu totalLength = %llu speed = %@\",recvLength , totalLength , speed);\n                                    } didFinished:^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n                                        if (isSuccess) {\n                                            [weakSelf.view toast:@\"下载成功\"];\n                                            [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                                        }else {\n                                            [weakSelf.view toast:error.userInfo[NSLocalizedDescriptionKey]];\n                                        if (error != nil &&\n                                            error.code == WHCCancelDownloadError) {\n                                            [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                                        }\n                                    }\n}];\n\n```\n\n###后台文件下载 Use Example\n```objective-c\n[[WHC_SessionDownloadManager shared] setBundleIdentifier:@\"com.WHC.WHCNetWorkKit.backgroundsession\"];\nWHC_DownloadSessionTask * downloadTask = [[WHC_SessionDownloadManager shared]\n                                                                    download:kWHC_DefaultDownloadUrl\n                                                                    savePath:[WHC_DownloadObject videoDirectory]\n                                                                saveFileName:fileName\n                                                                    response:^(WHC_BaseOperation *operation, NSError *error, BOOL isOK) {\n                                                                    [weakSelf.view toast:@\"已经添加到下载队列\"];\n                                                                    WHC_DownloadOperation * downloadOperation = (WHC_DownloadOperation*)operation;\n                                                                    WHC_DownloadObject * downloadObject = [WHC_DownloadObject new];\n                                                                    downloadObject.fileName = downloadOperation.saveFileName;\n                                                                    downloadObject.downloadPath = downloadOperation.strUrl;\n                                                                    downloadObject.downloadState = WHCDownloading;\n                                                                    downloadObject.currentDownloadLenght = downloadOperation.recvDataLenght;\n                                                                    downloadObject.totalLenght = downloadOperation.fileTotalLenght;\n                                                                    [downloadObject writeDiskCache];\n                                                                } process:^(WHC_BaseOperation *operation, uint64_t recvLength, uint64_t totalLength, NSString *speed) {\n                                                                    NSLog(@\"recvLength = %llu , totalLength = %llu , speed = %@\",recvLength , totalLength , speed);\n                                                                } didFinished:^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n                                                                    if (isSuccess) {\n                                                                        [weakSelf.view toast:@\"下载成功\"];\n                                                                        [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                                                                    }else {\n                                                                        [weakSelf.view toast:error.userInfo[NSLocalizedDescriptionKey]];\n                                                                        if (error != nil &&\n                                                                            error.code == WHCCancelDownloadError) {\n                                                                            [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                                                                        }\n                                                                    }\n}];\n```\n\n###UIButton设置网络图片  Use Example\n```objective-c\nUIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];\n[button whc_setBackgroundImageWithURL:@\"http://www.baidu.com\" forState:UIControlStateNormal];\n[button whc_setBackgroundImageWithURL:@\"http://www.baidu.com\" forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@\"whc\"]];\n[button whc_setImageWithUrl:@\"http://www.baidu.com\" forState:UIControlStateNormal];\n[button whc_setImageWithUrl:@\"http://www.baidu.com\" forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@\"whc\"]];\n```\n\n####UIImageView设置网络图片  Use Example\n```objective-c\nUIImageView * imageView = [UIImageView new];\n[imageView whc_setImageWithUrl:@\"http://www.baidu.com\"];\n[imageView whc_setImageWithUrl:@\"http://www.baidu.com\" placeholderImage:[UIImage imageNamed:@\"whc\"]];\n```\n\n###Json 转模型类  Use Example\n###支持无限json嵌套解析转换 (开源MAC工具WHC_DataModelFactory 自动把json或者xml字符串生成模型类.m和.h文件\n###省去手工创建模型类繁琐避免出错 开源链接：https://github.com/netyouli/WHC_DataModelFactory)\n```objective-c\ntypedef enum {\n    SexMale,\n    SexFemale\n} sex;\n\n@interface User : NSObject\n@property (copy, nonatomic) NSString *name;\n@property (copy, nonatomic) NSString *icon;\n@property (strong, nonatomic) NSNumber * age;\n@property (strong, nonatomic) NSNumber * height;\n@property (strong, nonatomic) NSNumber *money;\n@property (strong, nonatomic) sex  *sex;\n@end\n\n/***********************************************/\n\n\nNSDictionary *dict = @{\n@\"name\" : @\"Jack\",\n@\"icon\" : @\"lufy.png\",\n@\"age\" : @20,\n@\"height\" : @\"1.55\",\n@\"money\" : @100.9,\n@\"sex\" : @(SexFemale)\n};\n// JSON -> User\nUser * user = [WHC_DataModel dataModelWithDictionary:dict className:[User class]];\n\nNSLog(@\"name=%@, icon=%@, age=%@, height=%@, money=%@, sex=%@\",\nuser.name, user.icon, user.age, user.height, user.money, user.sex);\n// name=Jack, icon=lufy.png, age=20, height=1.550000, money=100.9, sex=1\n```\n\n###XML 转模型类 Use Example\n```objective-c\nNSString  * xml = @\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\\n<ebMobileStartupInqRq >\\\n<REQHDR>\\\n<TrnNum>INHB2015042900000001</TrnNum>\\\n<TrnCode>1957747793</TrnCode>\\\n</REQHDR>\\\n<REQBDY>\\\n<OS>iPhone</OS>\\\n<App>CC</App>\\\n<IconVersion></IconVersion>\\\n</REQBDY>\\\n</ebMobileStartupInqRq>\";\n\n@interface REQBDY :NSObject\n@property (nonatomic , copy) NSString              * OS;\n@property (nonatomic , copy) NSString              * App;\n@property (nonatomic , copy) NSString              * IconVersion;\n\n@end\n\n@interface REQHDR :NSObject\n@property (nonatomic , copy) NSString              * TrnCode;\n@property (nonatomic , copy) NSString              * TrnNum;\n\n@end\n\n@interface ebMobileStartupInqRq :NSObject\n@property (nonatomic , strong) REQBDY              * REQBDY;\n@property (nonatomic , strong) REQHDR              * REQHDR;\n\n@end\n\n@interface User :NSObject\n@property (nonatomic , strong) ebMobileStartupInqRq              * ebMobileStartupInqRq;\n\n@end\n\n\n///上面模型类生成是用开源MAC工具WHC_DataModelFactory 自动生成 \n///开源地址：https://github.com/netyouli/WHC_DataModelFactory\n///首先用开源WHC_XMLParser 把xml转换为字典对象 然后用WHC_DataModel转模型对象\nNSDictionary * xmlDictionary = [WHC_XMLParser dictionaryForXMLString:xml];\nUser * user = [WHC_DataModel dataModelWithDictionary:xmlDictionary\n                                           className:[User class]];\nNSLog(@\"%@\",ebMobile);\n\n```\n### 字典转换Json字符串 Use Example\n```objective-c\nNSDictionary * jsonDictionary = @{@\"whc\":@\"吴海超\"};\nNSString * json = [WHC_Json jsonWithDictionary:jsonDictionary];\n```\n\n### Json字符串/JsonData转NSDictionary对象 Use Example\n```objective-c\nNSString * json = @\"{\"whc\":\"吴海超\"}\";\nNSDictionary * jsonDictionary = [WHC_Json dictionaryWithJson:json];\njsonDictionary = [WHC_Json dictionaryWithJsonData:[json\n                dataUsingEncoding:NSUTF8StringEncoding]];\n```\n\n### Json字符串/JsonData 转NSArray对象 Use Example\n```objective-c\nNSString * json = @\"\"WHC\":{{\"android\":\"资深android开发者\"} , {\"iOS\":\"资深iOS开发者\"}}\";\nNSArray * jsonArray = [WHC_Json arrayWithJson:json];\njsonArray = [WHC_Json arrayWithJsonData:[json\n                    dataUsingEncoding:NSUTF8StringEncoding]];\n```\n\n### NSDictionary/NSArray对象转 Xml字符串\n```objective-c\nNSDictionary * REQHDR = @{@\"TrnNum\":@\"INHB2015042900000001\",@\"TrnCode\":@\"1957747793\"};\nNSDictionary * REQBDY = @{@\"OS\":@\"iPhone\",@\"App\":@\"CC\",@\"IconVersion\":@\"\"};\nNSDictionary * ebMobileStartupInqR = @{@\"REQHDR\":REQHDR,@\"REQBDY\":REQBDY};\nNSDictionary * xmlDic = @{@\"ebMobileStartupInqRq\":ebMobileStartupInqR};\n//use one\nNSString  * xmlStringOne = [WHC_Xml xmlWithDictionary:xmlDic];\n//use two\nNSString  * xmlStringTwo = [WHC_Xml xmlWithDictionary:xmlDic \n            rootAttribute:@\"xmlns = \\\"http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/BSMF/ebMobileStartupInqRq/01\\\"\"];\n\nNSLog(@\"xmlStringOne = %@\",xmlStringOne);\n//xmlStringOne =     NSString  * xml = @\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\\n<ebMobileStartupInqRq >\\\n<REQHDR>\\\n<TrnNum>INHB2015042900000001</TrnNum>\\\n<TrnCode>1957747793</TrnCode>\\\n</REQHDR>\\\n<REQBDY>\\\n<OS>iPhone</OS>\\\n<App>CC</App>\\\n<IconVersion></IconVersion>\\\n</REQBDY>\\\n</ebMobileStartupInqRq>\";\n\n\nNSLog(@\"xmlStringTwo = %@\",xmlStringTwo);\n//xmlStringTwo =     NSString  * xml = @\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\\n<ebMobileStartupInqRq xmlns=\\\"http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/BSMF/ebMobileStartupInqRq/01\\\">\\\n<REQHDR>\\\n<TrnNum>INHB2015042900000001</TrnNum>\\\n<TrnCode>1957747793</TrnCode>\\\n</REQHDR>\\\n<REQBDY>\\\n<OS>iPhone</OS>\\\n<App>CC</App>\\\n<IconVersion></IconVersion>\\\n</REQBDY>\\\n</ebMobileStartupInqRq>\";\n\n```\n\n## License\n\nWHCNetWorkKit is released under the MIT license. See LICENSE for details.\n"
  },
  {
    "path": "WHCNetWorkKit/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSPrincipalClass</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_BaseOperation.h",
    "content": "//\n//  WHC_BaseOperation.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nextern  NSTimeInterval const kWHCRequestTimeout;\nextern  NSTimeInterval const kWHCDownloadSpeedDuring;\nextern  CGFloat   const kWHCWriteSizeLenght;\n\nextern  NSString * const _Nullable kWHCDomain;\nextern  NSString * const _Nullable kWHCInvainUrlError;\nextern  NSString * const _Nullable kWHCCalculateFolderSpaceAvailableFailError;\nextern  NSString * const _Nullable kWHCErrorCode;\nextern  NSString * const _Nullable kWHCFreeDiskSapceError;\nextern  NSString * const _Nullable kWHCRequestRange;\nextern  NSString * const _Nullable kWHCUploadCode;\n\n/**\n * WHCHttpRequestStatus  网络请求状态枚举标识\n */\n\ntypedef NS_OPTIONS(NSUInteger, WHCHttpRequestStatus) {\n    WHCHttpRequestNone = 1 << 0,\n    WHCHttpRequestExecuting = 1 << 1,\n    WHCHttpRequestCanceled = 1 << 2,\n    WHCHttpRequestFinished = 1 << 3\n};\n\n/**\n * WHCHttpRequestStatus  网络请求类型枚举标识\n */\n\ntypedef NS_OPTIONS(NSUInteger, WHCHttpRequestType) {\n    WHCHttpRequestGet = 1 << 4,\n    WHCHttpRequestPost = 1 << 5,\n    WHCHttpRequestFileDownload = 1 << 6,\n    WHCHttpRequestFileUpload = 1 << 7\n};\n\n\n/**\n * WHCHttpRequestStatus  网络请求错误枚举标识\n */\n\ntypedef NS_OPTIONS(NSUInteger, WHCHttpErrorType) {\n    WHCFreeDiskSpaceLack = 2 << 0,\n    WHCGeneralError = 2 << 1,\n    WHCCancelDownloadError = 2 << 2,\n    WHCNetWorkError = 2 << 3\n};\n\n@class WHC_BaseOperation;\n@class WHC_DownloadOperation;\n\n/**\n * WHC_DownloadDelegate  网络下载回调代理\n */\n\n@protocol  WHC_DownloadDelegate<NSObject>\n\n@optional\n\n/**\n * 下载应答回调方法\n * @param: operation 当前下载操作对象\n * @param: error 响应错误对象\n * @param: isOK 是否可以下载\n */\n\n- (void)WHCDownloadResponse:(nonnull WHC_DownloadOperation *)operation\n                      error:(nullable NSError *)error\n                         ok:(BOOL)isOK;\n\n/**\n * 下载过程回调方法\n * @param: operation 当前下载操作对象\n * @param: recvLength 当前接收下载字节数\n * @param: totalLength 总字节数\n * @param: speed 下载速度\n */\n\n- (void)WHCDownloadProgress:(nonnull WHC_DownloadOperation *)operation\n                       recv:(uint64_t)recvLength\n                      total:(uint64_t)totalLength\n                      speed:(nullable NSString *)speed;\n\n/**\n * 下载结束回调方法\n * @param: operation 当前下载操作对象\n * @param: data 当前接收数据 （在requestType = WHCHttpRequestGet 该参数才有用 否则为nil）\n * @param: error 下载错误对象\n * @param: success 下载是否成功\n */\n\n- (void)WHCDownloadDidFinished:(nonnull WHC_DownloadOperation *)operation\n                          data:(nullable NSData *)data\n                         error:(nullable NSError *)error\n                       success:(BOOL)isSuccess;\n\n@end\n\n\n/**\n * 下载结束回调块\n * @param: operation 当前下载操作对象\n * @param: data 当前接收数据 （在requestType = WHCHttpRequestGet 该参数才有用 否则为nil）\n * @param: error 下载错误对象\n * @param: success 下载是否成功\n */\n\ntypedef void (^WHCDidFinished) (WHC_BaseOperation * _Nullable operation ,NSData * _Nullable data ,  NSError * _Nullable  error , BOOL isSuccess);\n\n/**\n * 下载应答回调块\n * @param: operation 当前下载操作对象\n * @param: error 响应错误对象\n * @param: isOK 是否可以下载\n */\n\ntypedef void (^WHCResponse)(WHC_BaseOperation * _Nullable operation , NSError * _Nullable error ,BOOL isOK);\n\n/**\n * 下载过程回调块\n * @param: operation 当前下载操作对象\n * @param: recvLength 当前接收下载字节数\n * @param: totalLength 总字节数\n * @param: speed 下载速度\n */\n\ntypedef void (^WHCProgress) (WHC_BaseOperation * _Nullable operation ,uint64_t recvLength , uint64_t totalLength , NSString * _Nullable speed);\n\n\n/**\n * 说明: WHC_BaseOperation http网络操作对象基类,封装了底层通用操作细节共上层网络操作服务\n */\n@interface WHC_BaseOperation : NSOperation <NSURLConnectionDataDelegate , NSURLConnectionDelegate>\n\n/**\n * 网络参数编码类型\n */\n@property (nonatomic , assign) NSUInteger     encoderType;\n\n/**\n * 网络请求超时时长\n */\n@property (nonatomic , assign) NSTimeInterval timeoutInterval;\n\n/**\n * 网络请求缓存策略\n */\n@property (nonatomic , assign) NSURLRequestCachePolicy cachePolicy;\n\n/**\n * 网络请求Url\n */\n@property (nonatomic , copy , nonnull) NSString * strUrl;\n\n/**\n * 网络请求内容类型\n */\n@property (nonatomic , copy , nonnull) NSString * contentType;\n\n/**\n * POST网络请求参数\n */\n@property (nonatomic , copy , nonnull) NSObject * postParam;\n\n/**\n * http网络请求类型\n */\n@property (nonatomic , assign) WHCHttpRequestType requestType;\n\n/**\n * http网络请求对象\n */\n@property (nonatomic , strong , nullable)NSMutableURLRequest     * urlRequest;\n\n/**\n * http网络请求连接对象\n */\n@property (nonatomic , strong , nullable)NSURLConnection         * urlConnection;\n\n/**\n * http网络请求状态\n */\n@property (nonatomic , assign)WHCHttpRequestStatus      requestStatus;\n\n/**\n * http网络请求应答数据对象\n */\n@property (nonatomic , strong , nullable)NSMutableData           * responseData;\n\n/**\n * http网络请求应答数据对象长度\n */\n@property (nonatomic , assign)uint64_t    responseDataLenght;\n\n/**\n * http网络请求定时获取的数据长度\n */\n@property (nonatomic , assign)uint64_t    orderTimeDataLenght;\n\n/**\n * http网络请求接收的数据长度\n */\n@property (nonatomic , assign)uint64_t    recvDataLenght;\n\n/**\n * http网络下载时下载速度\n */\n\n@property (nonatomic , strong , nullable)NSString  * networkSpeed;\n\n/**\n * 下载完成回调块对象\n */\n@property (nonatomic , copy , nullable )WHCDidFinished didFinishedBlock;\n\n/**\n * 下载过程回调块对象\n */\n@property (nonatomic , copy , nullable)WHCProgress progressBlock;\n\n/**\n * 下载应答回调块对象\n */\n@property (nonatomic, copy , nullable)WHCResponse responseBlock;\n\n/**\n * 下载操作代理对象\n */\n@property (nonatomic , weak, nullable)id<WHC_DownloadDelegate> delegate;\n\n/**\n * 说明: 清空http 应答数据\n */\n- (void)clearResponseData;\n\n\n/**\n * 说明: 开始http请求\n */\n- (void)startRequest;\n\n/**\n * 说明: 开始http请求开启网速监控时钟\n */\n- (void)startSpeedTimer;\n\n/**\n * 说明: 结束http请求\n */\n- (void)endRequest;\n\n/**\n * 说明: 取消http请求\n */\n- (void)cancelledRequest;\n\n/**\n * 通用处理http应答错误\n * @param: response 当前网络操作应答对象\n */\n- (BOOL)handleResponseError:(nullable NSURLResponse * )response;\n\n/**\n * 添加依赖下载队列\n * @param: downloadOperation 将要添加的下载队列对象\n */\n- (void)addDependOperation:(nonnull WHC_BaseOperation *)operation;\n\n/**\n * 通用处理http请求过程错误\n * @param: error 当前网络错误对象\n * @param: code  错误代码\n */\n- (void)handleReqeustError:(nullable NSError *)error code:(NSInteger)code;\n\n/**\n * 说明: 计算网络速度\n */\n- (void)calculateNetworkSpeed;\n\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_BaseOperation.m",
    "content": "//\n//  WHC_BaseOperation.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_BaseOperation.h\"\n#import \"WHC_HttpManager.h\"\n\nNSTimeInterval const kWHCRequestTimeout = 60;\nNSTimeInterval const kWHCDownloadSpeedDuring = 1.5;\nCGFloat        const kWHCWriteSizeLenght = 1024 * 1024;\nNSString  * const  kWHCDomain = @\"WHC_HTTP_OPERATION\";\nNSString  * const  kWHCInvainUrlError = @\"无效的url:%@\";\nNSString  * const  kWHCCalculateFolderSpaceAvailableFailError = @\"计算文件夹存储空间失败\";\nNSString  * const  kWHCErrorCode = @\"错误码:%ld\";\nNSString  * const  kWHCFreeDiskSapceError = @\"磁盘可用空间不足需要存储空间:%llu\";\nNSString  * const  kWHCRequestRange = @\"bytes=%lld-\";\nNSString  * const  kWHCUploadCode = @\"WHC\";\n\n@interface WHC_BaseOperation () {\n    NSTimer * _speedTimer;\n    NSThread * _thread;\n}\n\n@end\n\n@implementation WHC_BaseOperation\n\n#pragma mark - 重写属性方法 -\n- (void)setStrUrl:(NSString *)strUrl {\n    _strUrl = nil;\n    _strUrl = strUrl.copy;\n    NSString * newUrl = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,\n                                                                                              (CFStringRef)_strUrl,\n                                                                                              (CFStringRef)@\"!$&'()*-,-./:;=?@_~%#[]\",\n                                                                                              NULL,\n                                                                                              kCFStringEncodingUTF8));\n    _urlRequest = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:newUrl]];\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _timeoutInterval = kWHCRequestTimeout;\n        _requestType = WHCHttpRequestGet;\n        _requestStatus = WHCHttpRequestNone;\n        _cachePolicy = NSURLRequestUseProtocolCachePolicy;\n        _responseData = [NSMutableData data];\n    }\n    return self;\n}\n\n- (void)dealloc{\n    [self cancelledRequest];\n}\n\n\n#pragma mark - 重写队列操作方法 -\n\n- (void)start {\n    @autoreleasepool {\n        if ([NSURLConnection canHandleRequest:self.urlRequest]) {\n            self.urlRequest.timeoutInterval = self.timeoutInterval;\n            self.urlRequest.cachePolicy = self.cachePolicy;\n            [_urlRequest setValue:self.contentType forHTTPHeaderField: @\"Content-Type\"];\n            switch (self.requestType) {\n                case WHCHttpRequestGet:\n                case WHCHttpRequestFileDownload:{\n                    [_urlRequest setHTTPMethod:@\"GET\"];\n                }\n                    break;\n                case WHCHttpRequestPost:\n                case WHCHttpRequestFileUpload:{\n                    [_urlRequest setHTTPMethod:@\"POST\"];\n                    if([WHC_HttpManager shared].cookie && [WHC_HttpManager shared].cookie.length > 0) {\n                        [_urlRequest setValue:[WHC_HttpManager shared].cookie forHTTPHeaderField:@\"Cookie\"];\n                    }\n                    if (self.postParam != nil) {\n                        NSData * paramData = nil;\n                        if ([self.postParam isKindOfClass:[NSData class]]) {\n                            paramData = (NSData *)self.postParam;\n                        }else if ([self.postParam isKindOfClass:[NSString class]]) {\n                            paramData = [((NSString *)self.postParam) dataUsingEncoding:self.encoderType allowLossyConversion:YES];\n                        }\n                        if (paramData) {\n                            [_urlRequest setHTTPBody:paramData];\n                            [_urlRequest setValue:[NSString stringWithFormat:@\"%zd\", paramData.length] forHTTPHeaderField: @\"Content-Length\"];\n                        }\n                    }\n                }\n                    break;\n                default:\n                    break;\n            }\n            if(self.urlConnection == nil){\n                [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;\n                self.urlConnection = [[NSURLConnection alloc]initWithRequest:_urlRequest delegate:self startImmediately:NO];\n            }\n        }else {\n            [self handleReqeustError:nil code:WHCGeneralError];\n        }\n    }\n}\n\n- (BOOL)isExecuting {\n    return _requestStatus == WHCHttpRequestExecuting;\n}\n\n- (BOOL)isCancelled {\n    BOOL isCancelled = _requestStatus == WHCHttpRequestCanceled ||\n    _requestStatus == WHCHttpRequestFinished;\n    if (isCancelled) {\n        CFRunLoopStop(CFRunLoopGetCurrent());\n        _thread = nil;\n    }\n    return isCancelled;\n}\n\n- (BOOL)isFinished {\n    BOOL isFinished = _requestStatus == WHCHttpRequestFinished;\n    if (isFinished) {\n        CFRunLoopStop(CFRunLoopGetCurrent());\n        _thread = nil;\n    }\n    return isFinished;\n}\n\n- (BOOL)isConcurrent{\n    return YES;\n}\n\n\n#pragma mark - 公共方法 -\n\n- (void)calculateNetworkSpeed {\n    float downloadSpeed = (float)_orderTimeDataLenght / (kWHCDownloadSpeedDuring * 1024.0);\n    _networkSpeed = [NSString stringWithFormat:@\"%.1fKB/s\", downloadSpeed];\n    if (downloadSpeed >= 1024.0) {\n        downloadSpeed = ((float)_orderTimeDataLenght / 1024.0) / (kWHCDownloadSpeedDuring * 1024.0);\n        _networkSpeed = [NSString stringWithFormat:@\"%.1fMB/s\",downloadSpeed];\n    }\n    _orderTimeDataLenght = 0;\n}\n\n\n- (void)clearResponseData {\n    [self.responseData resetBytesInRange:NSMakeRange(0, self.responseData.length)];\n    [self.responseData setLength:0];\n}\n\n- (void)startRequest {\n    [self willChangeValueForKey:@\"isExecuting\"];\n    _requestStatus = WHCHttpRequestExecuting;\n    [self didChangeValueForKey:@\"isExecuting\"];\n    _thread = [NSThread currentThread];\n    [_urlConnection start];\n    CFRunLoopRun();\n}\n\n- (void)addDependOperation:(WHC_BaseOperation *)operation {\n    [self addDependency:operation];\n}\n\n- (void)startSpeedTimer {\n    if (!_speedTimer && (_requestType == WHCHttpRequestFileUpload ||\n                         _requestType == WHCHttpRequestFileDownload ||\n                         _requestType == WHCHttpRequestGet)) {\n        _speedTimer = [NSTimer scheduledTimerWithTimeInterval:kWHCDownloadSpeedDuring\n                                                       target:self\n                                                     selector:@selector(calculateNetworkSpeed)\n                                                     userInfo:nil\n                                                      repeats:YES];\n        [self calculateNetworkSpeed];\n    }\n}\n\n- (BOOL)handleResponseError:(NSURLResponse * )response {\n    BOOL isError = NO;\n    NSHTTPURLResponse  *  headerResponse = (NSHTTPURLResponse *)response;\n    if(headerResponse.statusCode >= 400){\n        isError = YES;\n        self.requestStatus = WHCHttpRequestFinished;\n        if (self.requestType != WHCHttpRequestFileDownload) {\n            [self cancelledRequest];\n            NSError * error = [NSError errorWithDomain:kWHCDomain\n                                                  code:WHCGeneralError\n                                              userInfo:@{NSLocalizedDescriptionKey:\n                                                             [NSString stringWithFormat:kWHCErrorCode,\n                                                              (long)headerResponse.statusCode]}];\n            dispatch_async(dispatch_get_main_queue(), ^{\n                if (self.didFinishedBlock) {\n                    self.didFinishedBlock(self, nil , error , NO);\n                    self.didFinishedBlock = nil;\n                }else if (self.delegate &&\n                          [self.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n                    if (headerResponse.statusCode == 404) {\n                        [[WHC_HttpManager shared].failedUrls addObject: self.strUrl];\n                    }\n                    [self.delegate WHCDownloadDidFinished:(WHC_DownloadOperation *)self data:nil error:error success:NO];\n                }\n            });\n        }\n    }else {\n        _responseDataLenght = headerResponse.expectedContentLength;\n        [self startSpeedTimer];\n    }\n    return isError;\n}\n\n- (void)endRequest {\n    self.didFinishedBlock = nil;\n    self.progressBlock = nil;\n    [self cancelledRequest];\n}\n\n- (void)cancelledRequest{\n    if (_urlConnection) {\n        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;\n        [_urlConnection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];\n        [_urlConnection cancel];\n        _urlConnection = nil;\n        [self willChangeValueForKey:@\"isCancelled\"];\n        [self willChangeValueForKey:@\"isFinished\"];\n        _requestStatus = WHCHttpRequestFinished;\n        [self didChangeValueForKey:@\"isFinished\"];\n        [self didChangeValueForKey:@\"isCancelled\"];\n        if (_requestType == WHCHttpRequestFileUpload ||\n            _requestType == WHCHttpRequestFileDownload) {\n            if (_speedTimer) {\n                [_speedTimer invalidate];\n                [_speedTimer fire];\n                _speedTimer = nil;\n            }\n        }\n    }\n}\n\n- (void)handleReqeustError:(NSError *)error code:(NSInteger)code {\n    if(error == nil){\n        error = [[NSError alloc]initWithDomain:kWHCDomain\n                                          code:code\n                                      userInfo:@{NSLocalizedDescriptionKey:\n                                                     [NSString stringWithFormat:kWHCInvainUrlError,self.strUrl]}];\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (self.didFinishedBlock) {\n            self.didFinishedBlock (self, nil, error , NO);\n            self.didFinishedBlock = nil;\n        }else if (self.delegate &&\n                  [self.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n            [self.delegate WHCDownloadDidFinished:(WHC_DownloadOperation *)self data:nil error:error success:NO];\n        }\n    });\n    \n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_DownloadOperation.h",
    "content": "//\n//  WHC_DownloadOperation.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_BaseOperation.h\"\n\n\n@interface WHC_DownloadOperation : WHC_BaseOperation\n\n/**\n * 下载操作下标\n */\n\n@property (nonatomic , assign)NSInteger index;\n/**\n * 保存文件路径\n */\n@property (nonatomic , copy)NSString       *   saveFilePath;\n\n/**\n * 保存文件名\n */\n@property (nonatomic , copy)NSString       *   saveFileName;\n/**\n * 下载是否完成标记\n */\n@property (nonatomic , assign , readonly)BOOL               isDownloadCompleted;\n/**\n * 文件实际总长度\n */\n@property (nonatomic , assign , readonly)uint64_t           fileTotalLenght;\n/**\n * 文件实际总长度\n */\n@property (nonatomic , assign)uint64_t                      actualFileSizeLenght;\n/**\n * 本地缓存文件总长度\n */\n@property (nonatomic , assign)uint64_t                      localFileLenght;\n\n/**\n * 下载任务是否删除\n */\n@property (nonatomic , assign)BOOL isDeleted;\n\n/**\n * 函数说明: 取消当前下载任务\n * @param: isDelete 取消下载任务的同时是否删除下载缓存的文件\n */\n\n- (void)cancelDownloadTaskAndDeleteFile:(BOOL)isDelete;\n\n/**\n * 函数说明: 下载请求响应\n * @param: response 下载请求应答对象\n */\n\n- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_DownloadOperation.m",
    "content": "//\n//  WHC_DownloadOperation.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_DownloadOperation.h\"\n\n@interface WHC_DownloadOperation () {\n    uint64_t                  _localFileSizeLenght;   //文件尺寸大小\n    NSFileHandle            * _fileHandle;         //文件句柄\n}\n\n@end\n\n@implementation WHC_DownloadOperation\n\n- (void)dealloc {\n}\n\n#pragma mark - 重写属性方法 -\n\n- (NSString *)saveFileName {\n    if (_saveFileName) {\n        return _saveFileName;\n    }else{\n        return [self.strUrl lastPathComponent];\n    }\n}\n\n- (NSString *)saveFilePath {\n    return [_saveFilePath stringByAppendingString:self.saveFileName];\n}\n\n- (uint64_t)downloadLenght {\n    return self.recvDataLenght;\n}\n\n- (uint64_t)fileTotalLenght {\n    return _actualFileSizeLenght;\n}\n\n- (void)start {\n    __autoreleasing  NSError  * error = nil;\n    NSFileManager  * fm = [NSFileManager defaultManager];\n    if(![fm fileExistsAtPath:self.saveFilePath]) {\n        [fm createFileAtPath:self.saveFilePath contents:nil attributes:nil];\n    }else {\n        _localFileSizeLenght = [[fm attributesOfItemAtPath:self.saveFilePath error:&error] fileSize];\n        NSString  * strRange = [NSString stringWithFormat:kWHCRequestRange ,_localFileSizeLenght];\n        [self.urlRequest setValue:strRange forHTTPHeaderField:@\"Range\"];\n    }\n    \n    if(error == nil) {\n        _fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.saveFilePath];\n        [_fileHandle seekToEndOfFile];\n    }else {\n        NSLog(@\"%@\",kWHCCalculateFolderSpaceAvailableFailError);\n    }\n    [super start];\n    [self startRequest];\n}\n\n#pragma mark - 私有方法\n\n- (uint64_t)calculateFreeDiskSpace{\n    uint64_t  freeDiskLen = 0;\n    NSString * docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];\n    NSFileManager  * fm   = [NSFileManager defaultManager];\n    NSDictionary   * dict = [fm attributesOfFileSystemForPath:docPath error:nil];\n    if(dict){\n        freeDiskLen = [dict[NSFileSystemFreeSize] unsignedLongLongValue];\n    }\n    return freeDiskLen;\n}\n\n- (NSInteger)getCode {\n    NSInteger code = WHCGeneralError;\n    NSFileManager * fm = [NSFileManager defaultManager];\n    if (self.recvDataLenght > 0 ||\n        [[fm attributesOfItemAtPath:self.saveFilePath error:nil] fileSize] > 100) {\n        code = WHCCancelDownloadError;\n    }\n    return code;\n}\n\n- (void)removeDownloadFile {\n    NSFileManager  * fm = [NSFileManager defaultManager];\n    if([fm fileExistsAtPath:self.saveFilePath]){\n        [fm removeItemAtPath:self.saveFilePath error:nil];\n    }\n}\n\n#pragma mark - 公共处理方法 -\n\n- (void)cancelDownloadTaskAndDeleteFile:(BOOL)isDelete {\n    _isDeleted = isDelete;\n    if(self.responseData.length > 0 && _fileHandle){\n        [_fileHandle writeData:self.responseData];\n        [self clearResponseData];\n    }\n    self.requestStatus = WHCHttpRequestFinished;\n    [self cancelledRequest];\n    if(isDelete){\n        [self removeDownloadFile];\n    }\n    NSError * error = nil;\n    if (!isDelete) {\n        error = [NSError errorWithDomain:kWHCDomain\n                            code:[self getCode]\n                        userInfo:@{NSLocalizedDescriptionKey:@\"下载已取消\"}];\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (self.didFinishedBlock) {\n            self.didFinishedBlock(self, nil , error , NO);\n            self.didFinishedBlock = nil;\n        }else if (self.delegate &&\n                  [self.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n            [self.delegate WHCDownloadDidFinished:self data:nil error:error success:NO];\n        }\n    });\n    \n}\n\n- (void)appExitHandleDownloadFile:(NSNotification *)notify {\n    if (self.urlConnection) {\n        [self connectionDidFinishLoading:self.urlConnection];\n    }\n}\n\n- (void)cancelledRequest{\n    [super cancelledRequest];\n    if (_fileHandle) {\n        [_fileHandle synchronizeFile];\n        [_fileHandle closeFile];\n        _fileHandle = nil;\n    }\n}\n\n- (void)handleReqeustError:(NSError *)error code:(NSInteger)code {\n    if (code != WHCCancelDownloadError) {\n        [self removeDownloadFile];\n    }\n    [super handleReqeustError:error code:code];\n}\n\n#pragma mark - 实现网络代理方法 -\n\n- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {\n    BOOL  isCancel = YES;\n    NSError  * error = nil;\n    NSInteger code = WHCGeneralError;\n    if (![self handleResponseError:response]){\n        isCancel = NO;\n        _actualFileSizeLenght = response.expectedContentLength + _localFileSizeLenght;\n        \n        if([self calculateFreeDiskSpace] < _actualFileSizeLenght){\n            error = [[NSError alloc]initWithDomain:kWHCDomain\n                                              code:WHCFreeDiskSpaceLack\n                                          userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:kWHCFreeDiskSapceError,_actualFileSizeLenght]}];\n            [self removeDownloadFile];\n            code = WHCFreeDiskSpaceLack;\n            isCancel = YES;\n            goto WHC1;\n        }else{\n            [[NSNotificationCenter defaultCenter] addObserver:self\n                                                     selector:@selector(appExitHandleDownloadFile:)\n                                                         name:UIApplicationWillTerminateNotification\n                                                       object:nil];\n            self.recvDataLenght = _localFileSizeLenght;\n            [self clearResponseData];\n            goto WHC2;\n        }\n    }else {\n    WHC1:\n        [self cancelDownloadTaskAndDeleteFile:NO];\n        error = [NSError errorWithDomain:kWHCDomain code:code userInfo:@{NSLocalizedDescriptionKey:response.description}];\n        \n    WHC2:\n        dispatch_async(dispatch_get_main_queue() , ^{\n            if (self.responseBlock) {\n                self.responseBlock(self, error ,!isCancel);\n                self.responseBlock = nil;\n            }else if (self.delegate &&\n                      [self.delegate respondsToSelector:@selector(WHCDownloadResponse:error:ok:)]) {\n                [self.delegate WHCDownloadResponse:self error:error ok:!isCancel];\n            }\n        });\n    }\n}\n\n- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {\n    [self.responseData appendData:data];\n    self.recvDataLenght += data.length;\n    self.orderTimeDataLenght += data.length;\n    if(self.responseData.length > kWHCWriteSizeLenght && _fileHandle){\n        [_fileHandle writeData:self.responseData];\n        [self clearResponseData];\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (self.progressBlock) {\n            self.progressBlock(self ,self.recvDataLenght , _actualFileSizeLenght , self.networkSpeed);\n        }else if (self.delegate &&\n                  [self.delegate respondsToSelector:@selector(WHCDownloadProgress:recv:total:speed:)]) {\n            [self.delegate WHCDownloadProgress:self recv:self.recvDataLenght total:_actualFileSizeLenght speed:self.networkSpeed];\n        }\n    });\n}\n\n- (void)connectionDidFinishLoading:(NSURLConnection *)connection {\n    if(_fileHandle){\n        [_fileHandle writeData:self.responseData];\n        [self clearResponseData];\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (self.didFinishedBlock) {\n            self.didFinishedBlock(self, nil , nil, YES);\n            self.didFinishedBlock = nil;\n        }else if (self.delegate &&\n                  [self.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n            [self.delegate WHCDownloadDidFinished:self data:nil error:nil success:YES];\n        }\n    });\n    \n    [self cancelledRequest];\n}\n\n- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {\n    [self cancelledRequest];\n    [self handleReqeustError:error code:[self getCode]];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_HttpManager.h",
    "content": "//\n//  WHC_HttpManager.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <Foundation/Foundation.h>\n#import \"WHC_HttpOperation.h\"\n#import \"WHC_DownloadOperation.h\"\n#import \"Reachability.h\"\n\n/**\n * 默认下载并发数量\n */\n\nextern const NSInteger kWHCDefaultDownloadNumber;\n\n/**\n * 说明: WHC_HttpManager http请求管理类 (单例设计模式 支持POST/GET 请求 文件上传 文件下载)\n */\n\n@interface WHC_HttpManager : NSObject\n\n/**\n * 说明: 当前是否是等待下载状态\n */\n- (BOOL)waitingDownload;\n\n/**\n * 网络管理单例对象\n */\n+ (nonnull instancetype)shared;\n\n/**\n * 网络参数编码类型\n */\n\n@property (nonatomic , assign) NSUInteger     encoderType;\n\n/**\n * 网络请求缓存策略\n */\n\n@property (nonatomic , assign) NSURLRequestCachePolicy cachePolicy;\n\n/**\n * 网络请求超时时长\n */\n\n@property (nonatomic , assign) NSTimeInterval timeoutInterval;\n\n/**\n * 网络请求内容类型\n */\n@property (nonatomic , copy , nonnull)  NSString *  contentType;\n\n/**\n * 网络请求404错误集合(下次再遇到则不请求)\n */\n\n@property (nonatomic , strong , nullable) NSMutableSet * failedUrls;\n\n/**\n * 网络请求会话id对象\n */\n@property (nonatomic , strong , nullable) NSString * cookie;\n\n/**\n * 创建文件保存路径\n * @param: savePath 文件路径\n */\n- (BOOL)createFileSavePath:(nonnull NSString *)savePath;\n\n/**\n * 生成通用错误对象\n * @param: message 错误信息\n */\n\n- (nonnull NSError *)error:(nonnull NSString *)message;\n\n/**\n * 自动处理生成正确文件名\n * @param: saveFileName 保存文件名\n * @param: strUrl 下载地址\n */\n\n- (nullable NSString *)handleFileName:(nonnull NSString *)saveFileName url:(nonnull NSString *)strUrl;\n\n/**\n * 当前网络状态\n */\n\n@property (nonatomic , assign)NetworkStatus        networkStatus;\n\n\n/**\n * 注册监听设备网络状态\n */\n- (void)registerNetworkStatusMoniterEvent;\n\n/**\n * GET 请求操作\n * @param: strUrl 请求地址\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)get:(nonnull NSString *)strUrl\n               didFinished:(nullable WHCDidFinished)finishedBlock;\n\n\n/**\n * GET 请求操作\n * @param: strUrl 请求地址\n * @param: processBlock 请求过程块\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)get:(nonnull NSString *)strUrl\n                            process:(nullable WHCProgress) processBlock\n                        didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * POST 请求操作\n * @param: strUrl 请求地址\n * @param: param 请求参数\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)post:(nonnull NSString *)strUrl\n                               param:(nullable NSString *)param\n                         didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * POST 请求操作\n * @param: strUrl 请求地址\n * @param: param 请求参数\n * @param: processBlock 请求过程块\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)post:(nonnull NSString *)strUrl\n                               param:(nullable NSString *)param\n                             process:(nullable WHCProgress)processBlock\n                         didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * 文件上传 请求操作\n * @param: strUrl 请求地址\n * @param: param 请求参数\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)upload:(nonnull NSString *)strUrl\n                                 param:(nullable NSDictionary *)paramDict\n                           didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * 文件上传 请求操作\n * @param: strUrl 请求地址\n * @param: param 请求参数\n * @param: processBlock 请求过程块\n * @param: finishedBlock 完成块\n */\n\n- (nullable WHC_HttpOperation *)upload:(nonnull NSString *)strUrl\n                                 param:(nullable NSDictionary *)paramDict\n                               process:(nullable WHCProgress)processBlock\n                           didFinished:(nullable WHCDidFinished)finishedBlock;\n\n\n\n/**\n * 说明: 执行下载任务 (存储时使用默认文件名)\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param delegate 下载响应代理\n */\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n/**\n * 说明: 执行下载任务\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param saveFileName 下载保存文件名\n * @param delegate 下载响应代理\n */\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n/**\n * 说明: 执行下载任务 (存储时使用默认文件名)\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                    response:(nullable WHCResponse)responseBlock\n                                     process:(nullable WHCProgress)processBlock\n                                 didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * 说明: 执行下载任务\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param saveFileName 下载保存文件名\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    response:(nullable WHCResponse) responseBlock\n                                     process:(nullable WHCProgress) processBlock\n                                 didFinished:(nullable WHCDidFinished) finishedBlock;\n\n\n\n\n/**\n * 说明: 添加上传文件数据\n * @param: data 文件数据\n * @param: fileName 文件名\n * @param: mimeType 文件类型\n * @param: key 上传标识 (这个必须和服务端对应)\n */\n\n- (void)addUploadFileData:(nonnull NSObject *)data\n             withFileName:(nonnull NSString *)fileName\n                 mimeType:(nonnull NSString *)mimeType\n                   forKey:(nonnull NSString *)key;\n\n/**\n * 说明: 添加上传文件\n * @param: filePath 本地文件路径\n * @param: key 上传标识 (这个必须和服务端对应)\n */\n\n- (void)addUploadFile:(nonnull NSString *)filePath\n               forKey:(nonnull NSString *)key;\n\n\n/**\n * 说明: 取消http请求\n * @param: url http 地址\n */\n\n- (void)cancelHttpRequestWithUrl:(nonnull NSString *)url ;\n\n/**\n * 说明: 返回指定文件名下载对象\n * @param: fileName 下载文件名\n */\n\n- (nullable WHC_DownloadOperation *)downloadOperationWithFileName:(nonnull NSString *)fileName;\n\n/**\n * 说明:设置最大下载数量（该方法必须在开始下载之前调用）\n * @param: count 下载并发数量\n */\n\n- (void)setMaxDownloadQueueCount:(NSUInteger)count;\n\n/**\n * 说明:返回下载中心最大同时下载操作个数\n */\n\n- (NSInteger)currentDownloadCount;\n\n/**\n * 说明：取消所有当前下载任务\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelAllDownloadTaskAndDelFile:(BOOL)isDelete;\n\n/**\n * 说明：取消指定正下载url的下载\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelDownloadWithDownloadUrl:(nonnull NSString *)strUrl\n                           deleteFile:(BOOL)isDelete;\n/**\n * 说明：取消指定正下载文件名的下载\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelDownloadWithFileName:(nonnull NSString *)fileName\n                        deleteFile:(BOOL)isDelete;\n\n\n/**\n * 说明：替换当前回调通过传递要下载的文件名(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n * @param fileName 文件名\n */\n\n- (nullable WHC_DownloadOperation *)replaceCurrentDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                             process:(nullable WHCProgress)processBlock\n                                         didFinished:(nullable WHCDidFinished)didFinishedBlock\n                                            fileName:(nonnull NSString *)fileName;\n\n/**\n * 说明：替换当前回调通过传递要下载的文件名(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param delegate 下载回调新代理\n * @param fileName 文件名\n */\n\n- (nullable WHC_DownloadOperation *)replaceCurrentDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate\n                                       fileName:(nonnull NSString *)fileName;\n\n/**\n * 说明：替换当前所有下载代理(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n- (nullable WHC_DownloadOperation *)replaceAllDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                         process:(nullable WHCProgress)processBlock\n                                     didFinished:(nullable WHCDidFinished)didFinishedBlock;\n\n/**\n * 说明：替换当前所有下载代理(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param delegate 下载回调新代理\n */\n\n- (nullable WHC_DownloadOperation *)replaceAllDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n/**\n * 说明：通过要下载的文件名来判断当前是否在进行下载任务\n * @param fileName 正在下载的文件名\n */\n\n- (BOOL)existDownloadOperationTaskWithUrl:(nonnull NSString *)strUrl;\n\n\n/**\n * 说明：通过要下载的文件名来判断当前是否在进行下载任务\n * @param strUrl 正在下载的url\n */\n\n- (BOOL)existDownloadOperationTaskWithFileName:(nonnull NSString *)fileName;\n\n/**\n * 获取文件名格式通过Url\n * @param: downloadUrl 下载路径\n */\n\n- (nullable NSString *)fileFormatWithUrl:(nonnull NSString *)downloadUrl;\n\n/**\n * 生成http请求原始参数对象\n * @param: paramDictionary 参数字典\n */\n\n- (nonnull NSString*)createHttpParam:(nonnull NSDictionary *)paramDictionary;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_HttpManager.m",
    "content": "//\n//  WHC_HttpManager.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_HttpManager.h\"\n#import <MobileCoreServices/MobileCoreServices.h>\n\nconst NSInteger kWHCDefaultDownloadNumber = 3;\n\n@interface WHC_HttpManager () {\n    NSOperationQueue     * _httpOperationQueue;\n    NSOperationQueue     * _fileDownloadOperationQueue;\n    Reachability         * _internetReachability;\n    \n    NSMutableArray       * _fileDataArr;\n    NSMutableArray       * _uploadParamArr;\n    NSMutableData        * _uploadPostData;\n}\n\n\n@end\n\n@implementation WHC_HttpManager\n\n+ (nonnull instancetype)shared {\n    static  WHC_HttpManager * WHCHttpManager;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        WHCHttpManager = [WHC_HttpManager new];\n    });\n    return WHCHttpManager;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _httpOperationQueue = [NSOperationQueue new];\n        _httpOperationQueue.maxConcurrentOperationCount = 20;\n        _failedUrls = [NSMutableSet set];\n        _encoderType = NSUTF8StringEncoding;\n        _cachePolicy = NSURLRequestUseProtocolCachePolicy;\n        _contentType = @\"application/x-www-form-urlencoded\";\n    }\n    return self;\n}\n\n\n\n#pragma mark - 网络状态监听 -\n- (void)registerNetworkStatusMoniterEvent {\n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(reachabilityChanged:)\n                                                 name:kReachabilityChangedNotification\n                                               object:nil];\n    \n    _internetReachability = [Reachability reachabilityForInternetConnection];\n    [_internetReachability startNotifier];\n    [self updateInterfaceWithReachability:_internetReachability];\n}\n\n- (void)updateInterfaceWithReachability:(Reachability*)internetReachability{\n    NetworkStatus netStatus = [internetReachability currentReachabilityStatus];\n    self.networkStatus = netStatus;\n    switch (netStatus) {\n        case NotReachable:{\n            for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n                [downloadOperation cancelDownloadTaskAndDeleteFile:NO];\n            }\n            for (WHC_BaseOperation * httpOperation in _httpOperationQueue.operations) {\n                [httpOperation cancelledRequest];\n            }\n            [[[UIAlertView alloc]initWithTitle:nil\n                                       message:@\"当前网络不可用请检查网络设置\"\n                                      delegate:nil cancelButtonTitle:@\"确定\"\n                             otherButtonTitles:nil, nil] show];\n        }\n            break;\n        case ReachableViaWiFi:\n            NSLog(@\"====当前网络状态为Wifi=======\");\n            break;\n        case ReachableViaWWAN:\n            NSLog(@\"====当前网络状态为3G=======\");\n            break;\n    }\n}\n\n- (void)reachabilityChanged:(NSNotification *)notifiy{\n    Reachability* curReach = [notifiy object];\n    NSParameterAssert([curReach isKindOfClass:[Reachability class]]);\n    [self updateInterfaceWithReachability:curReach];\n}\n\n#pragma mark - get请求 -\n\n- (nullable WHC_HttpOperation *)get:(nonnull NSString *)strUrl\n               didFinished:(nullable WHCDidFinished)finishedBlock {\n    return [self get:strUrl process:nil didFinished:finishedBlock];\n}\n\n- (nullable WHC_HttpOperation *)get:(nonnull NSString *)strUrl\n                   process:(nullable WHCProgress) processBlock\n               didFinished:(nullable WHCDidFinished)finishedBlock {\n    WHC_HttpOperation * getOperation = nil;\n    if (strUrl != nil && ![_failedUrls containsObject:strUrl]) {\n        getOperation = [WHC_HttpOperation new];\n        getOperation.requestType = WHCHttpRequestGet;\n        getOperation.progressBlock = processBlock;\n        getOperation.strUrl = strUrl;\n        __weak typeof(self) weakSelf = self;\n        getOperation.didFinishedBlock = ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n            if (!isSuccess && error.code == 404) {\n                [weakSelf.failedUrls addObject:strUrl];\n            }\n            if (finishedBlock) {\n                finishedBlock(operation , data , error , isSuccess);\n            }\n        };\n        [self setHttpOperation:getOperation];\n        [_httpOperationQueue addOperation:getOperation];\n    }else {\n        if (finishedBlock) {\n            __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n            finishedBlock(nil , nil , error , NO);\n        }\n    }\n    return getOperation;\n}\n\n#pragma mark - post请求 -\n\n- (nullable WHC_HttpOperation *)post:(nonnull NSString *)strUrl\n                      param:(nullable NSString *)param\n                didFinished:(nullable WHCDidFinished)finishedBlock {\n    return [self post:strUrl param:param process:nil didFinished:finishedBlock];\n}\n\n- (nullable WHC_HttpOperation *)post:(nonnull NSString *)strUrl\n                      param:(nullable NSString *)param\n                    process:(nullable WHCProgress) processBlock\n                didFinished:(nullable WHCDidFinished)finishedBlock {\n    WHC_HttpOperation * postOperation = nil ;\n    if (strUrl != nil && ![_failedUrls containsObject:strUrl]) {\n        postOperation = [WHC_HttpOperation new];\n        postOperation.requestType = WHCHttpRequestPost;\n        postOperation.progressBlock = processBlock;\n        postOperation.postParam = param;\n        postOperation.strUrl = strUrl;\n        __weak typeof(self) weakSelf = self;\n        postOperation.didFinishedBlock = ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n            if (!isSuccess && error.code == 404) {\n                [weakSelf.failedUrls addObject:strUrl];\n            }\n            if (finishedBlock) {\n                finishedBlock(operation , data , error , isSuccess);\n            }\n        };\n        [self setHttpOperation:postOperation];\n        [_httpOperationQueue addOperation:postOperation];\n    }else {\n        if (finishedBlock) {\n            __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n            finishedBlock(nil , nil , error , NO);\n        }\n    }\n\n    return postOperation;\n}\n\n#pragma mark - 文件上传 -\n\n- (nullable WHC_HttpOperation *)upload:(nonnull NSString *)strUrl\n                        param:(nullable NSDictionary *)paramDict\n                  didFinished:(nullable WHCDidFinished)finishedBlock {\n    return [self upload:strUrl\n                  param:paramDict\n                process:nil\n            didFinished:finishedBlock];\n}\n/**\n 说明:文件上传开始\n strUrl:上传路径\n param:上传附带参数\n callBack：上传结束回调\n */\n- (nullable WHC_HttpOperation *)upload:(nonnull NSString *)strUrl\n                        param:(nullable NSDictionary *)paramDict\n                      process:(nullable WHCProgress) processBlock\n                  didFinished:(nullable WHCDidFinished)finishedBlock {\n    [self setPostParamDict:paramDict];\n    [self buildMultipartFormDataPostBody];\n    WHC_HttpOperation * uploadOperation = nil ;\n    if (strUrl != nil && ![_failedUrls containsObject:strUrl]) {\n        uploadOperation = [WHC_HttpOperation new];\n        [self setHttpOperation:uploadOperation];\n        uploadOperation.requestType = WHCHttpRequestFileUpload;\n        uploadOperation.progressBlock = processBlock;\n        uploadOperation.strUrl = strUrl;\n        uploadOperation.postParam = _uploadPostData;\n        __weak typeof(self) weakSelf = self;\n        uploadOperation.didFinishedBlock = ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n            [_uploadParamArr removeAllObjects];\n            [_fileDataArr removeAllObjects];\n            [_uploadPostData resetBytesInRange:NSMakeRange(0, _uploadPostData.length)];\n            [_uploadPostData setLength:0];\n            if (!isSuccess && error.code == 404) {\n                [weakSelf.failedUrls addObject:strUrl];\n            }\n            if (finishedBlock) {\n                finishedBlock(operation , data , error , isSuccess);\n            }\n        };\n        NSString * charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));\n        uploadOperation.contentType = [NSString stringWithFormat:@\"multipart/form-data; charset=%@; boundary=%@\", charset, kWHCUploadCode];\n        [_httpOperationQueue addOperation:uploadOperation];\n    }else {\n        if (finishedBlock) {\n            __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n            finishedBlock(nil , nil , error , NO);\n        }\n    }\n    return uploadOperation;\n}\n\n#pragma mark - 文件下载 -\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    return [self download:strUrl savePath:savePath saveFileName:nil delegate:delegate];\n}\n\n\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    \n    WHC_DownloadOperation  * downloadOperation = nil;\n    NSString * fileName = nil;\n    if (strUrl != nil && ![_failedUrls containsObject:strUrl]) {\n        fileName = [self handleFileName:saveFileName url:strUrl];\n        for (WHC_DownloadOperation * tempDownloadOperation in _fileDownloadOperationQueue.operations) {\n            if ([fileName isEqualToString:tempDownloadOperation.saveFileName]){\n                __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:已经在下载中\",fileName]];\n                if (delegate && [delegate respondsToSelector:@selector(WHCDownloadResponse:error:ok:)]) {\n                    [delegate WHCDownloadResponse:tempDownloadOperation error:error ok:NO];\n                } else if (delegate && [delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n                    [delegate WHCDownloadDidFinished:tempDownloadOperation data:nil error:error success:NO];\n                }\n                return tempDownloadOperation;\n            }\n        }\n        if([self createFileSavePath:savePath]) {\n            downloadOperation = [WHC_DownloadOperation new];\n            downloadOperation.requestType = WHCHttpRequestGet;\n            downloadOperation.saveFileName = fileName;\n            downloadOperation.saveFilePath = savePath;\n            downloadOperation.delegate = delegate;\n            downloadOperation.strUrl = strUrl;\n            [self setHttpOperation:downloadOperation];\n            [_fileDownloadOperationQueue addOperation:downloadOperation];\n        }\n    }else {\n        __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n        if (delegate &&\n            [delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n            [delegate WHCDownloadDidFinished:downloadOperation data:nil error:error success:NO];\n        }\n    }\n    return downloadOperation;\n}\n\n/**\n 参数说明：\n url:下载路径\n savePath:文件本地存储路径\n delegate:下载状态监控代理\n */\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                           savePath:(nonnull NSString *)savePath\n                            response:(nullable WHCResponse) responseBlock\n                            process:(nullable WHCProgress) processBlock\n                        didFinished:(nullable WHCDidFinished) finishedBlock {\n    \n    return [self download:strUrl\n                 savePath:savePath\n             saveFileName:nil\n                 response:responseBlock\n                  process:processBlock\n              didFinished:finishedBlock];\n}\n\n/**\n 参数说明：\n url:下载路径\n savePath:文件本地存储路径\n savefileName:下载要存储的文件名\n delegate:下载状态监控代理\n */\n- (nullable WHC_DownloadOperation *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    response:(nullable WHCResponse) responseBlock\n                                     process:(nullable WHCProgress) processBlock\n                                 didFinished:(nullable WHCDidFinished) finishedBlock {\nNSLog(@\"_fileDownloadOperationQueue.operations = %d\",_fileDownloadOperationQueue.operations.count);\n    WHC_DownloadOperation  * downloadOperation = nil;\n    NSString * fileName = nil;\n    if (strUrl != nil && ![_failedUrls containsObject:strUrl]) {\n        fileName = [self handleFileName:saveFileName url:strUrl];\n        for (WHC_DownloadOperation * tempDownloadOperation in _fileDownloadOperationQueue.operations) {\n            if ([fileName isEqualToString:tempDownloadOperation.saveFileName]){\n                __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:已经在下载中\",fileName]];\n                if (responseBlock) {\n                    responseBlock(tempDownloadOperation, error, NO);\n                } else if (finishedBlock) {\n                    finishedBlock(tempDownloadOperation ,nil, error, NO);\n                }\n                return tempDownloadOperation;\n            }\n        }\n        if([self createFileSavePath:savePath]) {\n            downloadOperation = [WHC_DownloadOperation new];\n            downloadOperation.requestType = WHCHttpRequestGet;\n            downloadOperation.saveFileName = fileName;\n            downloadOperation.saveFilePath = savePath;\n            downloadOperation.progressBlock = processBlock;\n            downloadOperation.responseBlock = responseBlock;\n            downloadOperation.strUrl = strUrl;\n            __weak typeof(self) weakSelf = self;\n            downloadOperation.didFinishedBlock = ^(WHC_BaseOperation *operation,\n                                                   NSData *data,\n                                                   NSError *error,\n                                                   BOOL isSuccess) {\n                if (!isSuccess && error.code == 404) {\n                    [weakSelf.failedUrls addObject:strUrl];\n                }\n                if (finishedBlock) {\n                    finishedBlock(operation , data , error , isSuccess);\n                }\n            };\n            [self setHttpOperation:downloadOperation];\n            [_fileDownloadOperationQueue addOperation:downloadOperation];\n        }\n    }else {\n        __autoreleasing NSError * error = [self error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n        if (responseBlock) {\n            responseBlock(downloadOperation , error , NO);\n        }else if (finishedBlock) {\n            finishedBlock(downloadOperation , nil , error , NO);\n        }\n    }\n    return downloadOperation;\n}\n\n\n\n#pragma mark - 文件上传工具方法 -\n\n/*\n 说明:添加上传文件数据,可多次调用添加上传多个文件\n data:可以是二进制数据也可以是本地文件路径\n fileName:文件名称\n mimeType:文件类型如图片(image/jpeg)\n key：关键字名称这个必须和服务端对应\n */\n- (void)addUploadFileData:(nonnull NSObject *)data\n             withFileName:(nonnull NSString *)fileName\n                 mimeType:(nonnull NSString *)mimeType\n                   forKey:(nonnull NSString *)key {\n    \n    if (_fileDataArr == nil) {\n        _fileDataArr = [NSMutableArray array];\n    }\n    if (!mimeType) {\n        mimeType = @\"application/octet-stream\";\n    }\n    \n    NSMutableDictionary *fileInfo = [NSMutableDictionary dictionaryWithCapacity:4];\n    [fileInfo setValue:key forKey:@\"key\"];\n    [fileInfo setValue:fileName forKey:@\"fileName\"];\n    [fileInfo setValue:mimeType forKey:@\"contentType\"];\n    [fileInfo setValue:data forKey:@\"data\"];\n    \n    [_fileDataArr addObject:fileInfo];\n}\n\n/**\n 说明:添加上传文件路径，可多次调用添加上传多个文件\n filePath：文件路径\n key：关键字名称这个必须和服务端对应\n */\n- (void)addUploadFile:(nonnull NSString *)filePath\n               forKey:(nonnull NSString *)key {\n    NSFileManager  * fm = [NSFileManager defaultManager];\n    if([fm fileExistsAtPath:filePath]){\n        NSString  * fileName = filePath.lastPathComponent;\n        NSString  * mimeType = [self mimeTypeForFileAtPath:filePath];\n        [self addUploadFileData:filePath withFileName:fileName mimeType:mimeType forKey:key];\n    }\n}\n\n#pragma mark - 文件下载工具方法 -\n\n- (BOOL)waitingDownload {\n    return _fileDownloadOperationQueue.operations.count > kWHCDefaultDownloadNumber;\n}\n\n- (nullable NSString *)handleFileName:(NSString *)saveFileName url:(NSString *)strUrl {\n    if (!_fileDownloadOperationQueue) {\n        _fileDownloadOperationQueue = [NSOperationQueue new];\n        _fileDownloadOperationQueue.maxConcurrentOperationCount = kWHCDefaultDownloadNumber;\n    }\n    NSString * fileName = saveFileName;\n    if(saveFileName){\n        NSString * format = [self fileFormatWithUrl:strUrl];\n        if(format && ![format isEqualToString:[NSString stringWithFormat:@\".%@\",\n                                    [[saveFileName componentsSeparatedByString:@\".\"] lastObject]]]){\n            fileName = [NSString stringWithFormat:@\"%@%@\",saveFileName,format];\n        }\n    }\n    return fileName;\n}\n\n//返回指定文件名下载对象\n- (nullable WHC_DownloadOperation *)downloadOperationWithFileName:(nonnull NSString *)fileName {\n    WHC_DownloadOperation * downloadOperation = nil;\n    for (WHC_DownloadOperation * tempDownloadOperation in _fileDownloadOperationQueue.operations) {\n        if([tempDownloadOperation.saveFileName isEqualToString:fileName]){\n            downloadOperation = tempDownloadOperation;\n            break;\n        }\n    }\n    return downloadOperation;\n}\n\n/**\n note:该方法必须在开始下载之前调用\n 说明：\n 设置最大下载数量\n */\n- (void)setMaxDownloadQueueCount:(NSUInteger)count {\n    _fileDownloadOperationQueue.maxConcurrentOperationCount = count;\n}\n\n/**\n 说明:返回下载中心最大同时下载操作个数\n */\n- (NSInteger)currentDownloadCount {\n    return _fileDownloadOperationQueue.maxConcurrentOperationCount;\n}\n\n/**\n 说明：\n 取消所有正下载并是否取消删除文件\n */\n- (void)cancelAllDownloadTaskAndDelFile:(BOOL)isDelete {\n    for (WHC_DownloadOperation * operation in _fileDownloadOperationQueue.operations) {\n        [operation cancelDownloadTaskAndDeleteFile:isDelete];\n    }\n}\n\n/**\n 说明：\n 取消指定正下载url的下载\n */\n- (void)cancelDownloadWithDownloadUrl:(nonnull NSString *)strUrl deleteFile:(BOOL)isDelete {\n    for(WHC_DownloadOperation * operation in _fileDownloadOperationQueue.operations){\n        if ([operation.strUrl isEqualToString:strUrl]) {\n            [operation cancelDownloadTaskAndDeleteFile:isDelete];\n            break;\n        }\n    }\n}\n\n/**\n 说明：\n 取消指定正下载文件名的下载\n */\n- (void)cancelDownloadWithFileName:(nonnull NSString *)fileName deleteFile:(BOOL)isDelete {\n    for(WHC_DownloadOperation * operation in _fileDownloadOperationQueue.operations){\n        if([operation.saveFileName isEqualToString:fileName]){\n            [operation cancelDownloadTaskAndDeleteFile:isDelete];\n            break;\n        }\n    }\n}\n\n\n/**\n 说明：\n 替换当前代理通过要下载的文件名\n 使用情景:(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，\n 在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n */\n\n\n- (WHC_DownloadOperation *)replaceCurrentDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                             process:(nullable WHCProgress)processBlock\n                                         didFinished:(nullable WHCDidFinished)didFinishedBlock\n                                            fileName:(nonnull NSString *)fileName {\n    for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n        if([downloadOperation.saveFileName isEqualToString:fileName]){\n            downloadOperation.delegate = nil;\n            downloadOperation.progressBlock = processBlock;\n            downloadOperation.responseBlock = responseBlock;\n            downloadOperation.didFinishedBlock = didFinishedBlock;\n            return downloadOperation;\n        }\n    }\n    return nil;\n}\n\n- (WHC_DownloadOperation *)replaceCurrentDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate\n                                       fileName:(nonnull NSString *)fileName {\n    for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n        if([downloadOperation.saveFileName isEqualToString:fileName]){\n            downloadOperation.progressBlock = nil;\n            downloadOperation.responseBlock = nil;\n            downloadOperation.didFinishedBlock = nil;\n            downloadOperation.delegate = delegate;\n            return downloadOperation;\n        }\n    }\n    return nil;\n}\n\n//替换所有当前下载代理\n- (WHC_DownloadOperation *)replaceAllDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                         process:(nullable WHCProgress)processBlock\n                                     didFinished:(nullable WHCDidFinished)didFinishedBlock {\n    if (_fileDownloadOperationQueue.operations.count > 0) {\n        for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n            downloadOperation.delegate = nil;\n            downloadOperation.progressBlock = processBlock;\n            downloadOperation.responseBlock = responseBlock;\n            downloadOperation.didFinishedBlock = didFinishedBlock;\n        }\n        return nil;\n    }\n    return nil;\n}\n\n- (WHC_DownloadOperation *)replaceAllDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    if (_fileDownloadOperationQueue.operations.count > 0) {\n        for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n            downloadOperation.progressBlock = nil;\n            downloadOperation.responseBlock = nil;\n            downloadOperation.didFinishedBlock = nil;\n            downloadOperation.delegate = delegate;\n        }\n        return nil;\n    }\n    return nil;\n}\n\n\n/**\n 说明：\n 通过要下载的文件名来判断当前是否在进行下载任务\n */\n- (BOOL)existDownloadOperationTaskWithFileName:(nonnull NSString *)fileName {\n    BOOL  result = NO;\n    for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n        if([downloadOperation.saveFileName isEqualToString:fileName]){\n            result = YES;\n            break;\n        }\n    }\n    return result;\n}\n\n- (BOOL)existDownloadOperationTaskWithUrl:(nonnull NSString *)strUrl {\n    BOOL  result = NO;\n    for (WHC_DownloadOperation * downloadOperation in _fileDownloadOperationQueue.operations) {\n        if([downloadOperation.strUrl isEqualToString:strUrl]){\n            result = YES;\n            break;\n        }\n    }\n    return result;\n}\n\n#pragma mark - 公共方法 -\n\n- (void)cancelHttpRequestWithUrl:(nonnull NSString *)url {\n    for (WHC_BaseOperation * operation in _httpOperationQueue.operations) {\n        if ([operation.strUrl isEqualToString:url]) {\n            [operation endRequest];\n        }\n    }\n}\n\n- (nullable NSString *)fileFormatWithUrl:(nonnull NSString *)downloadUrl {\n    NSArray  * strArr = [downloadUrl componentsSeparatedByString:@\".\"];\n    if(strArr && strArr.count > 0){\n        NSString * suffix = strArr.lastObject;\n        if (suffix.length > 7) {\n            return nil;\n        }\n        return [NSString stringWithFormat:@\".%@\",strArr.lastObject].lowercaseString;\n    }else{\n        return nil;\n    }\n}\n\n- (nonnull NSString*)createHttpParam:(nonnull NSDictionary *)paramDictionary {\n    NSString *postString=@\"\";\n    for(NSString *key in [paramDictionary allKeys]){\n        NSString *value = [paramDictionary objectForKey:key];\n        postString = [postString stringByAppendingFormat:@\"%@=%@&\",key,value];\n    }\n    if([postString length] > 1){\n        postString = [postString substringToIndex:[postString length]-1];\n    }\n    return postString;\n}\n\n#pragma mark - 私有方法 -\n\n- (__autoreleasing NSError *)error:(nonnull NSString *)message {\n    __autoreleasing NSError  * error = [[NSError alloc]initWithDomain:kWHCDomain\n                                                                 code:WHCGeneralError\n                                                             userInfo:@{NSLocalizedDescriptionKey:\n                                                                            message}];\n    return error;\n}\n\n- (void)setHttpOperation:(WHC_BaseOperation *)httpOperation {\n    httpOperation.encoderType = _encoderType;\n    httpOperation.cachePolicy = _cachePolicy;\n    httpOperation.contentType = _contentType;\n    httpOperation.timeoutInterval = _timeoutInterval;\n}\n\n- (BOOL)createFileSavePath:(nonnull NSString *)savePath {\n    BOOL  result = YES;\n    if(savePath != nil && savePath.length > 0){\n        NSFileManager  * fm = [NSFileManager defaultManager];\n        if(![fm fileExistsAtPath:savePath]){\n            __autoreleasing NSError *error = nil;\n            [fm createDirectoryAtPath:savePath\n          withIntermediateDirectories:YES\n                           attributes:@{NSFileProtectionKey : NSFileProtectionNone}\n                                error:&error];\n            if(error){\n                result = NO;\n            }\n        }\n    }else{\n        result = NO;\n    }\n    return result;\n}\n\n#pragma mark - 上传文件私有方法\n\n- (nullable NSString *)mimeTypeForFileAtPath:(nullable NSString *)path{\n    if (![[NSFileManager defaultManager]fileExistsAtPath:path]) {\n        return nil;\n    }\n    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);\n    CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);\n    CFRelease(UTI);\n    if (!MIMEType) {\n        return @\"application/octet-stream\";\n    }\n    return  (__bridge NSString *)MIMEType;\n}\n\n\n- (void)appendPostString:(nullable NSString *)string{\n    if(_uploadPostData == nil){\n        _uploadPostData = [NSMutableData data];\n    }\n    [_uploadPostData appendData:[string dataUsingEncoding:NSUTF8StringEncoding]];\n}\n\n\n- (void)setPostParamDict:(nullable NSDictionary *)paramDict{\n    \n    if (paramDict == nil) {\n        return;\n    }\n    if (_uploadParamArr == nil) {\n        _uploadParamArr = [NSMutableArray array];\n    }else{\n        [_uploadParamArr removeAllObjects];\n    }\n    NSArray  * keyArr = paramDict.allKeys;\n    if(keyArr){\n        for (NSString * strKey in keyArr) {\n            NSMutableDictionary *keyValuePair = [NSMutableDictionary dictionaryWithCapacity:2];\n            [keyValuePair setValue:strKey forKey:@\"key\"];\n            [keyValuePair setValue:[[paramDict objectForKey:strKey] description] forKey:@\"value\"];\n            [_uploadParamArr addObject:keyValuePair];\n        }\n    }\n}\n\n- (void)appendPostData:(nullable NSData *)data{\n    if ([data length] == 0) {\n        return;\n    }\n    if(_uploadPostData == nil){\n        _uploadPostData = [NSMutableData data];\n    }\n    [_uploadPostData appendData:data];\n}\n\n- (void)appendPostDataFromFile:(nullable NSString *)file {\n    if(_uploadPostData == nil){\n        _uploadPostData = [NSMutableData data];\n    }\n    NSFileManager  * fm = [NSFileManager defaultManager];\n    if([fm fileExistsAtPath:file]){\n        NSInputStream *stream = [[NSInputStream alloc] initWithFileAtPath:file];\n        [stream open];\n        NSUInteger bytesRead;\n        while ([stream hasBytesAvailable]) {\n            unsigned char buffer[1024 * 256];\n            bytesRead = [stream read:buffer maxLength:sizeof(buffer)];\n            if (bytesRead == 0) {\n                break;\n            }\n            [_uploadPostData appendData:[NSData dataWithBytes:buffer length:bytesRead]];\n        }\n        [stream close];\n    }\n}\n\n- (void)buildMultipartFormDataPostBody {\n    if(_uploadParamArr == nil){\n        _uploadParamArr = [NSMutableArray array];\n    }\n    NSString *stringBoundary = kWHCUploadCode;\n    [self appendPostString:[NSString stringWithFormat:@\"--%@\\r\\n\",stringBoundary]];\n    NSUInteger i = 0;\n    NSString *endItemBoundary = [NSString stringWithFormat:@\"\\r\\n--%@\\r\\n\",stringBoundary];\n    // 设置文件数据\n    for (NSDictionary *val in _fileDataArr) {\n        \n        [self appendPostString:[NSString stringWithFormat:@\"Content-Disposition: form-data; name=\\\"%@\\\"; filename=\\\"%@\\\"\\r\\n\", val[@\"key\"], val[@\"fileName\"]]];\n        [self appendPostString:[NSString stringWithFormat:@\"Content-Type: %@\\r\\n\\r\\n\", val[@\"contentType\"]]];\n        \n        id data = val[@\"data\"];\n        if ([data isKindOfClass:[NSString class]]) {\n            [self appendPostDataFromFile:data];\n        } else {\n            [self appendPostData:data];\n        }\n        [self appendPostString:@\"\\r\\n\"];\n        i++;\n        //添加分隔符在边界除了最后一个元素\n        if (i != [_fileDataArr count]) {\n            [self appendPostString:endItemBoundary];\n        }\n    }\n    [self appendPostString:endItemBoundary];\n    //设置普通参数\n    i = 0;\n    for (NSDictionary *val in _uploadParamArr) {\n        [self appendPostString:[NSString stringWithFormat:@\"Content-Disposition: form-data; name=\\\"%@\\\"\\r\\n\\r\\n\",val[@\"key\"]]];\n        [self appendPostString:val[@\"value\"]];\n        [self appendPostString:@\"\\r\\n\"];\n        i++;\n        //添加分隔符在边界除了最后一个元素\n        if (i != _uploadParamArr.count) {\n            [self appendPostString:endItemBoundary];\n        }\n    }\n    [self appendPostString:[NSString stringWithFormat:@\"\\r\\n--%@--\\r\\n\",stringBoundary]];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_HttpOperation.h",
    "content": "//\n//  WHC_HttpOperation.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_BaseOperation.h\"\n\n\n@interface WHC_HttpOperation : WHC_BaseOperation\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLConnection/WHC_HttpOperation.m",
    "content": "//\n//  WHC_HttpOperation.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import \"WHC_HttpOperation.h\"\n#import \"WHC_HttpManager.h\"\n@interface WHC_HttpOperation ()  {\n    \n}\n\n@end\n\n@implementation WHC_HttpOperation\n\n#pragma mark - 重写操作方法 -\n\n- (void)start {\n    [super start];\n    [self startRequest];\n}\n\n- (void)cancelledRequest{\n    [super cancelledRequest];\n}\n\n#pragma mark - 实现网络代理方法 -\n\n- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {\n    if (![self handleResponseError:response]) {\n        NSHTTPURLResponse  *  headerResponse = (NSHTTPURLResponse *)response;\n        NSDictionary * fields = [headerResponse allHeaderFields];\n        NSString * newCookie = fields[@\"Set-Cookie\"];\n        if (newCookie) {\n            if([WHC_HttpManager shared].cookie == nil){\n                [WHC_HttpManager shared].cookie = newCookie.copy;\n            }else if ([WHC_HttpManager shared].cookie != newCookie){\n                [WHC_HttpManager shared].cookie = nil;\n                [WHC_HttpManager shared].cookie = newCookie.copy;\n            }\n        }\n    }\n}\n\n- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {\n    [self.responseData appendData:data];\n    if (self.requestType == WHCHttpRequestGet) {\n        self.recvDataLenght += data.length;\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (self.progressBlock) {\n                self.progressBlock(self, self.recvDataLenght , self.responseDataLenght , self.networkSpeed);\n            }\n        });\n    }\n}\n\n- (void)connection:(NSURLConnection *)connection\n           didSendBodyData:(NSInteger)bytesWritten\n         totalBytesWritten:(NSInteger)totalBytesWritten\n        totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {\n    \n    if (self.requestType == WHCHttpRequestFileUpload) {\n        [self startSpeedTimer];\n        self.orderTimeDataLenght += bytesWritten;\n        self.recvDataLenght += bytesWritten;\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (self.progressBlock) {\n                self.progressBlock(self, self.recvDataLenght , totalBytesWritten , self.networkSpeed);\n            }\n        });\n    }\n}\n\n- (void)connectionDidFinishLoading:(NSURLConnection *)connection {\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (self.didFinishedBlock) {\n            self.didFinishedBlock(self ,self.responseData , nil, YES);\n         }\n        self.didFinishedBlock = nil;\n    });\n    [self cancelledRequest];\n}\n\n- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {\n    self.delegate = nil;\n    [self cancelledRequest];\n    [self handleReqeustError:error code:WHCGeneralError];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLSession/WHC_DownloadSessionTask.h",
    "content": "//\n//  WHC_DownloadSessionTask.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/12/7.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_DownloadOperation.h\"\n\n/**\n * 说明: WHC_DownloadSessionTask  单个后台下载任务类\n */\n\n@interface WHC_DownloadSessionTask : WHC_DownloadOperation\n\n/**\n * 当前后台下载任务对象\n */\n@property (nonatomic , strong)NSURLSessionDownloadTask * downloadTask;\n\n/**\n * 函数说明: 取消当前下载任务\n * @param: isDelete 取消下载任务的同时是否删除下载缓存的文件\n */\n\n- (void)cancelDownloadTaskAndDeleteFile:(BOOL)isDelete;\n\n/**\n * 函数说明: 处理下载应答\n * @param: response 下载应答对象\n */\n\n- (void)handleResponse:(NSURLResponse *)response;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLSession/WHC_DownloadSessionTask.m",
    "content": "//\n//  WHC_DownloadSessionTask.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/12/7.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_DownloadSessionTask.h\"\n\n@implementation WHC_DownloadSessionTask\n\n- (void)cancelDownloadTaskAndDeleteFile:(BOOL)isDelete {\n    if (isDelete) {\n        [_downloadTask cancel];\n    }\n}\n\n- (void)handleResponse:(NSURLResponse *)response {\n    [self connection:nil didReceiveResponse:response];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLSession/WHC_SessionDownloadManager.h",
    "content": "//\n//  WHC_SessionDownloadOperation.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/30.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import <Foundation/Foundation.h>\n#import \"WHC_DownloadSessionTask.h\"\n\n/**\n * 说明: WHC_SessionDownloadManager 后台下载管理类 单例设计模式\n */\n\n@interface WHC_SessionDownloadManager : NSObject\n\n/**\n * 说明: 当前是否是等待下载状态\n */\n- (BOOL)waitingDownload;\n\n/**\n * 后台下载配置字符\n */\n@property (nonnull ,nonatomic , copy)NSString * bundleIdentifier;\n\n/**\n * 下载对象单例\n */\n+ (nonnull instancetype)shared;\n\n/**\n * 说明: 执行下载任务 (存储时使用默认文件名)\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param delegate 下载响应代理\n */\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                      savePath:(nonnull NSString *)savePath\n                                      delegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n/**\n * 说明: 执行下载任务\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param saveFileName 下载保存文件名\n * @param delegate 下载响应代理\n */\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                      savePath:(nonnull NSString *)savePath\n                                  saveFileName:(nullable NSString *)saveFileName\n                                      delegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n/**\n * 说明: 执行下载任务 (存储时使用默认文件名)\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                      savePath:(nonnull NSString *)savePath\n                                      response:(nullable WHCResponse)responseBlock\n                                       process:(nullable WHCProgress)processBlock\n                                   didFinished:(nullable WHCDidFinished)finishedBlock;\n\n/**\n * 说明: 执行下载任务\n * @param strUrl 下载地址\n * @param savePath 下载缓存路径\n * @param saveFileName 下载保存文件名\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                      savePath:(nonnull NSString *)savePath\n                                  saveFileName:(nullable NSString *)saveFileName\n                                      response:(nullable WHCResponse) responseBlock\n                                       process:(nullable WHCProgress) processBlock\n                                   didFinished:(nullable WHCDidFinished) finishedBlock;\n\n/**\n * 说明：取消所有当前下载任务\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelAllDownloadTaskAndDelFile:(BOOL)isDelete;\n\n/**\n * 说明：取消指定正下载url的下载\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelDownloadWithDownloadUrl:(nonnull NSString *)strUrl deleteFile:(BOOL)isDelete;\n\n/**\n * 说明：取消指定正下载文件名的下载\n * @param isDelete 是否删除缓存文件\n */\n\n- (void)cancelDownloadWithFileName:(nonnull NSString *)fileName deleteFile:(BOOL)isDelete;\n\n\n/**\n * 说明：替换当前回调通过传递要下载的文件名(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n * @param fileName 文件名\n */\n\n\n- (nullable WHC_DownloadSessionTask *)replaceCurrentDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                             process:(nullable WHCProgress)processBlock\n                                         didFinished:(nullable WHCDidFinished)didFinishedBlock\n                                            fileName:(nonnull NSString *)fileName;\n\n/**\n * 说明：替换当前回调通过传递要下载的文件名(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param delegate 下载回调新代理\n * @param fileName 文件名\n */\n\n- (nullable WHC_DownloadSessionTask *)replaceCurrentDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate\n                                       fileName:(nonnull NSString *)fileName;\n\n/**\n * 说明：替换当前所有下载代理(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param responseBlock 下载响应回调\n * @param processBlock 下载过程回调\n * @param didFinishedBlock 下载完成回调\n */\n\n- (nullable WHC_DownloadSessionTask *)replaceAllDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                         process:(nullable WHCProgress)processBlock\n                                     didFinished:(nullable WHCDidFinished)didFinishedBlock;\n\n/**\n * 说明：替换当前所有下载代理(当从控制器B进入到控制器C然后在控制器C中进行下载，然后下载过程中突然退出到控制器B，在又进入到控制器C，这个时候还是在下载但是代理对象和之前的那个控制器C不是一个对象所以要替换)\n * @param delegate 下载回调新代理\n */\n\n- (nullable WHC_DownloadSessionTask *)replaceAllDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate;\n\n\n/**\n * 说明：通过要下载的文件名来判断当前是否在进行下载任务\n * @param fileName 正在下载的文件名\n */\n\n- (BOOL)existDownloadOperationTaskWithFileName:(nonnull NSString *)fileName;\n\n/**\n * 说明：通过要下载的文件名来判断当前是否在进行下载任务\n * @param strUrl 正在下载的url\n */\n\n- (BOOL)existDownloadOperationTaskWithUrl:(nonnull NSString *)strUrl;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/NSURLSession/WHC_SessionDownloadManager.m",
    "content": "//\n//  WHC_SessionDownloadOperation.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/30.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import \"WHC_SessionDownloadManager.h\"\n#import \"WHC_DownloadSessionTask.h\"\n#import \"WHC_HttpManager.h\"\n\n\n@interface WHC_SessionDownloadManager () <NSURLSessionDataDelegate , NSURLSessionDelegate>{\n    NSOperationQueue *  _asynQueue;\n    NSURLSession     *  _downloadSession;\n    NSMutableArray   *  _downloadTaskArr;\n    NSMutableDictionary * _resumeDataDictionary;\n    NSFileManager    *  _fileManager;\n    NSMutableDictionary * _etagDictionary;\n    NSString * _resumeDataPath;\n}\n\n@end\n\n@implementation WHC_SessionDownloadManager\n\n+ (instancetype)shared {\n    static WHC_SessionDownloadManager * downloadManager;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        downloadManager = [WHC_SessionDownloadManager new];\n    });\n    return downloadManager;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _asynQueue = [NSOperationQueue new];\n        _asynQueue.maxConcurrentOperationCount = kWHCDefaultDownloadNumber;\n        _downloadTaskArr = [NSMutableArray array];\n        _resumeDataDictionary = [NSMutableDictionary dictionary];\n        _fileManager = [NSFileManager defaultManager];\n        _etagDictionary = [NSMutableDictionary dictionary];\n        _resumeDataPath = [NSString stringWithFormat:@\"%@/Library/Caches/WHCResumeDataCache/\",NSHomeDirectory()];\n        BOOL isDirectory = YES;\n        if (![_fileManager fileExistsAtPath:_resumeDataPath isDirectory:&isDirectory]) {\n            [_fileManager createDirectoryAtPath:_resumeDataPath\n          withIntermediateDirectories:YES\n                           attributes:@{NSFileProtectionKey:NSFileProtectionNone} error:nil];\n        }\n    }\n    return self;\n}\n\n- (void)setBundleIdentifier:(nonnull NSString *)identifier {\n    if (_downloadSession == nil) {\n        _bundleIdentifier = nil;\n        _bundleIdentifier = identifier.copy;\n        NSURLSessionConfiguration * configuration;\n        if ([NSURLSessionConfiguration respondsToSelector:@selector(backgroundSessionConfigurationWithIdentifier:)]){\n            configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:_bundleIdentifier];\n        }else {\n            configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:_bundleIdentifier];\n        }\n        configuration.discretionary = YES;\n        _downloadSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:_asynQueue];\n        \n    }\n}\n\n- (BOOL)waitingDownload {\n    return _asynQueue.operations.count > kWHCDefaultDownloadNumber;\n}\n\n#pragma mark - 下载对外接口\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    return [self download:strUrl savePath:savePath saveFileName:nil delegate:delegate];\n}\n\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    delegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    WHC_DownloadSessionTask  * downloadTask = nil;\n    NSString * fileName = nil;\n    if (strUrl != nil && ![[WHC_HttpManager shared].failedUrls containsObject:strUrl]) {\n        fileName = [[WHC_HttpManager shared] handleFileName:saveFileName url:strUrl];\n        for (WHC_DownloadSessionTask * tempDownloadTask in _downloadTaskArr) {\n            if ([fileName isEqualToString: tempDownloadTask.saveFileName]){\n                __autoreleasing NSError * error = [[WHC_HttpManager shared] error:[NSString stringWithFormat:@\"%@:已经在下载中\",fileName]];\n                if (delegate && [delegate respondsToSelector:@selector(WHCDownloadResponse:error:ok:)]) {\n                    [delegate WHCDownloadResponse:tempDownloadTask error:error ok:NO];\n                } else if (delegate && [delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n                    [delegate WHCDownloadDidFinished:tempDownloadTask data:nil error:error success:NO];\n                }\n                return tempDownloadTask;\n            }\n        }\n        if([[WHC_HttpManager shared] createFileSavePath:savePath]) {\n            \n            downloadTask = [WHC_DownloadSessionTask new];\n            downloadTask.requestType = WHCHttpRequestFileDownload;\n            downloadTask.saveFileName = fileName;\n            downloadTask.saveFilePath = savePath;\n            downloadTask.delegate = delegate;\n            downloadTask.strUrl = strUrl;\n            downloadTask.delegate = delegate;\n            [self startDownload:downloadTask];\n        }\n    }else {\n        __autoreleasing NSError * error = [[WHC_HttpManager shared] error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n        if (delegate &&\n            [delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n            [delegate WHCDownloadDidFinished:downloadTask data:nil error:error success:NO];\n        }\n    }\n    return downloadTask;\n    \n}\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                    response:(nullable WHCResponse)responseBlock\n                                     process:(nullable WHCProgress)processBlock\n                                 didFinished:(nullable WHCDidFinished)finishedBlock {\n    return nil;\n}\n\n- (nullable WHC_DownloadSessionTask *)download:(nonnull NSString *)strUrl\n                                    savePath:(nonnull NSString *)savePath\n                                saveFileName:(nullable NSString *)saveFileName\n                                    response:(nullable WHCResponse) responseBlock\n                                     process:(nullable WHCProgress) processBlock\n                                 didFinished:(nullable WHCDidFinished) finishedBlock {\n    WHC_DownloadSessionTask  * downloadTask = nil;\n    NSString * fileName = nil;\n    if (strUrl != nil && ![[WHC_HttpManager shared].failedUrls containsObject:strUrl]) {\n        fileName = [[WHC_HttpManager shared] handleFileName:saveFileName url:strUrl];\n        for (WHC_DownloadSessionTask * tempDownloadTask in _downloadTaskArr) {\n            if ([fileName isEqualToString:tempDownloadTask.saveFileName]){\n                __autoreleasing NSError * error = [[WHC_HttpManager shared] error:[NSString stringWithFormat:@\"%@:已经在下载中\",fileName]];\n                if (responseBlock) {\n                    responseBlock(tempDownloadTask, error, NO);\n                } else if (finishedBlock) {\n                    finishedBlock(tempDownloadTask ,nil, error, NO);\n                }\n                return tempDownloadTask;\n            }\n        }\n        if([[WHC_HttpManager shared] createFileSavePath:savePath]) {\n            downloadTask = [WHC_DownloadSessionTask new];\n            downloadTask.requestType = WHCHttpRequestFileDownload;\n            downloadTask.saveFileName = fileName;\n            downloadTask.saveFilePath = savePath;\n            downloadTask.progressBlock = processBlock;\n            downloadTask.responseBlock = responseBlock;\n            downloadTask.strUrl = strUrl;\n            downloadTask.didFinishedBlock = ^(WHC_BaseOperation *operation,\n                                                   NSData *data,\n                                                   NSError *error,\n                                                   BOOL isSuccess) {\n                if (!isSuccess && error.code == 404) {\n                    [[WHC_HttpManager shared].failedUrls addObject:strUrl];\n                }\n                if (finishedBlock) {\n                    finishedBlock(operation , data , error , isSuccess);\n                }\n            };\n            [self startDownload:downloadTask];\n        }\n    }else {\n        __autoreleasing NSError * error = [[WHC_HttpManager shared] error:[NSString stringWithFormat:@\"%@:请求失败\",strUrl]];\n        if (responseBlock) {\n            responseBlock(downloadTask , error , NO);\n        }else if (finishedBlock) {\n            finishedBlock(downloadTask , nil , error , NO);\n        }\n    }\n    return downloadTask;\n}\n\n#pragma mark - 私有方法\n\n- (NSString *)getResumeDataFilePath:(NSString *)fileName {\n    if (fileName && fileName.length > 0) {\n        return [NSString stringWithFormat:@\"%@%@\",_resumeDataPath , fileName];\n    }\n    return nil;\n}\n\n\n- (void)startDownload:(WHC_DownloadSessionTask *)downloadTask {\n    if (_downloadSession) {\n        NSString * resumeDataFilePath = [self getResumeDataFilePath:downloadTask.saveFileName];\n        if (resumeDataFilePath && [_fileManager fileExistsAtPath:resumeDataFilePath]) {\n            NSData * resumeData = [NSData dataWithContentsOfFile:resumeDataFilePath];\n            downloadTask.downloadTask = [_downloadSession downloadTaskWithResumeData:resumeData];\n        }else {\n            NSURL * url = [NSURL URLWithString:downloadTask.strUrl];\n            NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];\n            downloadTask.downloadTask = [_downloadSession downloadTaskWithRequest:urlRequest];\n        }\n        [downloadTask startSpeedTimer];\n        [downloadTask.downloadTask resume];\n        [_downloadTaskArr addObject:downloadTask];\n    }\n}\n\n- (void)cancelDownloadTask:(BOOL)isDelete task:(WHC_DownloadSessionTask *)task {\n    if (!isDelete) {\n        [task.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {\n            // 存储恢复下载数据在didCompleteWithError处理\n            NSLog(@\"暂停下载\");\n        }];\n    }else {\n        [task cancelDownloadTaskAndDeleteFile:isDelete];\n    }\n}\n\n#pragma mark - 下载过程对外接口\n\n- (nullable WHC_DownloadSessionTask *)downloadOperationWithFileName:(nonnull NSString *)fileName {\n    WHC_DownloadSessionTask * downloadTask = nil;\n    for (WHC_DownloadSessionTask * tempDownloadTask in _downloadTaskArr) {\n        if([tempDownloadTask.saveFileName isEqualToString:fileName]) {\n            downloadTask = tempDownloadTask;\n            break;\n        }\n    }\n    return downloadTask;\n}\n\n- (void)cancelAllDownloadTaskAndDelFile:(BOOL)isDelete {\n    for (WHC_DownloadSessionTask * task in _downloadTaskArr) {\n        [self cancelDownloadTask:isDelete task:task];\n    }\n}\n\n- (void)cancelDownloadWithDownloadUrl:(nonnull NSString *)strUrl deleteFile:(BOOL)isDelete {\n    for(WHC_DownloadSessionTask * task in _downloadTaskArr){\n        if ([task.strUrl isEqualToString:strUrl]) {\n            [self cancelDownloadTask:isDelete task:task];\n            break;\n        }\n    }\n}\n\n- (void)cancelDownloadWithFileName:(nonnull NSString *)fileName deleteFile:(BOOL)isDelete {\n    for(WHC_DownloadSessionTask * task in _downloadTaskArr){\n        if([task.saveFileName isEqualToString:fileName]){\n            [self cancelDownloadTask:isDelete task:task];\n            break;\n        }\n    }\n}\n\n- (WHC_DownloadSessionTask *)replaceCurrentDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                             process:(nullable WHCProgress)processBlock\n                                         didFinished:(nullable WHCDidFinished)didFinishedBlock\n                                            fileName:(nonnull NSString *)fileName {\n    for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n        if([downloadTask.saveFileName isEqualToString:fileName]){\n            downloadTask.delegate = nil;\n            downloadTask.progressBlock = processBlock;\n            downloadTask.responseBlock = responseBlock;\n            downloadTask.didFinishedBlock = didFinishedBlock;\n            return downloadTask;\n        }\n    }\n    return nil;\n}\n\n- (WHC_DownloadSessionTask *)replaceCurrentDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate\n                                       fileName:(nonnull NSString *)fileName {\n    for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n        if([downloadTask.saveFileName isEqualToString:fileName]){\n            downloadTask.progressBlock = nil;\n            downloadTask.responseBlock = nil;\n            downloadTask.didFinishedBlock = nil;\n            downloadTask.delegate = delegate;\n            return downloadTask;\n        }\n    }\n    return nil;\n}\n\n- (WHC_DownloadSessionTask *)replaceAllDownloadOperationBlockResponse:(nullable WHCResponse)responseBlock\n                                         process:(nullable WHCProgress)processBlock\n                                     didFinished:(nullable WHCDidFinished)didFinishedBlock {\n    if (_downloadTaskArr.count > 0) {\n        for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n            downloadTask.delegate = nil;\n            downloadTask.progressBlock = processBlock;\n            downloadTask.responseBlock = responseBlock;\n            downloadTask.didFinishedBlock = didFinishedBlock;\n        }\n        return nil;\n    }\n    return nil;\n}\n\n- (WHC_DownloadSessionTask *)replaceAllDownloadOperationDelegate:(nullable id<WHC_DownloadDelegate>)delegate {\n    if (_downloadTaskArr.count > 0) {\n        for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n            downloadTask.progressBlock = nil;\n            downloadTask.responseBlock = nil;\n            downloadTask.didFinishedBlock = nil;\n            downloadTask.delegate = delegate;\n        }\n        return nil;\n    }\n    return nil;\n}\n\n\n- (BOOL)existDownloadOperationTaskWithFileName:(nonnull NSString *)fileName {\n    BOOL  result = NO;\n    for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n        if([downloadTask.saveFileName isEqualToString:fileName]){\n            result = YES;\n            break;\n        }\n    }\n    return result;\n}\n\n- (BOOL)existDownloadOperationTaskWithUrl:(nonnull NSString *)strUrl {\n    BOOL  result = NO;\n    for (WHC_DownloadSessionTask * downloadTask in _downloadTaskArr) {\n        if([downloadTask.strUrl isEqualToString:strUrl]){\n            result = YES;\n            break;\n        }\n    }\n    return result;\n}\n\n\n- (WHC_DownloadSessionTask *)getCurrentDownloadTask:(NSURLSessionDownloadTask *)downloadTask {\n    WHC_DownloadSessionTask * whc_downloadTask = nil;\n    for (WHC_DownloadSessionTask * tempDownloadTask in _downloadTaskArr) {\n        if ([tempDownloadTask.downloadTask isEqual:downloadTask]) {\n            whc_downloadTask = tempDownloadTask;\n            break;\n        }\n    }\n    return whc_downloadTask;\n}\n\n- (void)removeDownloadTask:(WHC_DownloadSessionTask *)downloadTask {\n    downloadTask.delegate = nil;\n    downloadTask.downloadTask = nil;\n    downloadTask.responseBlock = nil;\n    downloadTask.didFinishedBlock = nil;\n    downloadTask.progressBlock = nil;\n    [_downloadTaskArr removeObject:downloadTask];\n}\n\n\n- (void)saveDownloadFile:(NSString *)path downloadTask:(WHC_DownloadSessionTask *)downloadTask {\n    if (path) {\n        if ([_fileManager fileExistsAtPath:downloadTask.saveFilePath isDirectory:NULL]) {\n            NSFileHandle * fileHandle = [NSFileHandle fileHandleForWritingAtPath:downloadTask.saveFilePath];\n            [fileHandle seekToEndOfFile];\n            NSData * data = [NSData dataWithContentsOfFile:path];\n            if (data) {\n                [fileHandle writeData:data];\n                [fileHandle synchronizeFile];\n                [fileHandle closeFile];\n            }\n        }else {\n            [_fileManager moveItemAtPath:path toPath:downloadTask.saveFilePath error:NULL];\n        }\n    }\n}\n\n- (void)saveDidFinishDownloadTask:(NSURLSessionDownloadTask *)downloadTask\n                            toUrl:(NSURL *)location {\n    WHC_DownloadSessionTask * whc_downloadTask = [self getCurrentDownloadTask:downloadTask];\n    if (whc_downloadTask) {\n        whc_downloadTask.actualFileSizeLenght = downloadTask.countOfBytesExpectedToReceive;\n        whc_downloadTask.recvDataLenght = downloadTask.countOfBytesReceived;\n        whc_downloadTask.requestStatus = WHCHttpRequestFinished;\n        [self saveDownloadFile:location.path downloadTask:whc_downloadTask];\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (whc_downloadTask.delegate &&\n                [whc_downloadTask.delegate respondsToSelector:@selector(WHCDownloadProgress:recv:total:speed:)]) {\n                [whc_downloadTask.delegate WHCDownloadProgress:whc_downloadTask\n                                                          recv:downloadTask.countOfBytesReceived\n                                                         total:downloadTask.countOfBytesExpectedToReceive\n                                                         speed:whc_downloadTask.networkSpeed];\n                if ([whc_downloadTask.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n                    [whc_downloadTask.delegate WHCDownloadDidFinished:whc_downloadTask\n                                                                 data:nil\n                                                                error:nil\n                                                              success:YES];\n                }\n            }else {\n                if (whc_downloadTask.progressBlock) {\n                    whc_downloadTask.progressBlock(whc_downloadTask ,\n                                                   downloadTask.countOfBytesReceived ,\n                                                   downloadTask.countOfBytesExpectedToReceive ,\n                                                   whc_downloadTask.networkSpeed);\n                }\n                if (whc_downloadTask.didFinishedBlock) {\n                    whc_downloadTask.didFinishedBlock(whc_downloadTask , nil , nil , YES);\n                }\n            }\n            [self removeDownloadTask:whc_downloadTask];\n        });\n    }\n}\n\n#pragma mark - NSURLSessionDownloadDelegate\n\n- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {\n    \n}\n\n- (void)URLSession:(NSURLSession *)session\n      downloadTask:(NSURLSessionDownloadTask *)downloadTask\ndidFinishDownloadingToURL:(NSURL *)location {\n    [self saveDidFinishDownloadTask:downloadTask toUrl:location];\n}\n\n- (void)URLSession:(NSURLSession *)session\n              task:(NSURLSessionTask *)task\ndidCompleteWithError:(NSError *)error {\n    WHC_DownloadSessionTask * whc_downloadTask = [self getCurrentDownloadTask:(NSURLSessionDownloadTask *)task];\n    if (whc_downloadTask.delegate &&\n        [whc_downloadTask.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (error &&\n                [error.userInfo[NSLocalizedDescriptionKey] isEqualToString:@\"cancelled\"]) {\n                NSData * resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];\n                if (resumeData) {\n                    [resumeData writeToFile:[self getResumeDataFilePath:whc_downloadTask.saveFileName] atomically:YES];\n                }\n                if (whc_downloadTask.delegate &&\n                    [whc_downloadTask.delegate respondsToSelector:@selector(WHCDownloadDidFinished:data:error:success:)]) {\n                    [whc_downloadTask.delegate WHCDownloadDidFinished:whc_downloadTask\n                                                                 data:nil\n                                                                error:error\n                                                              success:NO];\n                }else {\n                    if (whc_downloadTask.didFinishedBlock) {\n                        whc_downloadTask.didFinishedBlock(whc_downloadTask , nil , error , NO);\n                    }\n                }\n                [self removeDownloadTask:whc_downloadTask];\n            }\n        });\n    }\n}\n\n- (void)URLSession:(NSURLSession *)session\n      downloadTask:(NSURLSessionDownloadTask *)downloadTask\n      didWriteData:(int64_t)bytesWritten\n totalBytesWritten:(int64_t)totalBytesWritten\ntotalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {\n    WHC_DownloadSessionTask * whc_downloadTask = [self getCurrentDownloadTask:downloadTask];\n    whc_downloadTask.recvDataLenght += bytesWritten;\n    whc_downloadTask.orderTimeDataLenght += bytesWritten;\n    if (whc_downloadTask.actualFileSizeLenght < 10) {\n        whc_downloadTask.actualFileSizeLenght = totalBytesExpectedToWrite;\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n       if (whc_downloadTask.delegate &&\n           [whc_downloadTask.delegate respondsToSelector:@selector(WHCDownloadProgress:recv:total:speed:)]) {\n           [whc_downloadTask.delegate WHCDownloadProgress:whc_downloadTask\n                                                     recv:totalBytesWritten\n                                                    total:totalBytesExpectedToWrite\n                                                    speed:whc_downloadTask.networkSpeed];\n       }else {\n           if (whc_downloadTask.progressBlock) {\n               whc_downloadTask.progressBlock(whc_downloadTask ,\n                                              totalBytesWritten ,\n                                              totalBytesExpectedToWrite ,\n                                              whc_downloadTask.networkSpeed);\n           }\n       }\n    });\n}\n\n- (void)URLSession:(NSURLSession *)session\n      downloadTask:(NSURLSessionDownloadTask *)downloadTask\n didResumeAtOffset:(int64_t)fileOffset\nexpectedTotalBytes:(int64_t)expectedTotalBytes {\n    WHC_DownloadSessionTask * whc_downloadTask = [self getCurrentDownloadTask:downloadTask];\n    whc_downloadTask.orderTimeDataLenght = fileOffset;\n}\n\n- (void)URLSession:(NSURLSession *)session\n          dataTask:(NSURLSessionDataTask *)dataTask\ndidReceiveResponse:(NSURLResponse *)response\n completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {\n    WHC_DownloadSessionTask * whc_downloadTask = [self getCurrentDownloadTask:(NSURLSessionDownloadTask *)dataTask];\n    [whc_downloadTask handleResponse:response];\n    if (whc_downloadTask.requestStatus == WHCHttpRequestFinished ) {\n        [self removeDownloadTask:whc_downloadTask];\n    }\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/Reachability/Reachability.h",
    "content": "/*\n     File: Reachability.h\n Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.\n  Version: 3.5\n \n Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple\n Inc. (\"Apple\") in consideration of your agreement to the following\n terms, and your use, installation, modification or redistribution of\n this Apple software constitutes acceptance of these terms.  If you do\n not agree with these terms, please do not use, install, modify or\n redistribute this Apple software.\n \n In consideration of your agreement to abide by the following terms, and\n subject to these terms, Apple grants you a personal, non-exclusive\n license, under Apple's copyrights in this original Apple software (the\n \"Apple Software\"), to use, reproduce, modify and redistribute the Apple\n Software, with or without modifications, in source and/or binary forms;\n provided that if you redistribute the Apple Software in its entirety and\n without modifications, you must retain this notice and the following\n text and disclaimers in all such redistributions of the Apple Software.\n Neither the name, trademarks, service marks or logos of Apple Inc. may\n be used to endorse or promote products derived from the Apple Software\n without specific prior written permission from Apple.  Except as\n expressly stated in this notice, no other rights or licenses, express or\n implied, are granted by Apple herein, including but not limited to any\n patent rights that may be infringed by your derivative works or by other\n works in which the Apple Software may be incorporated.\n \n The Apple Software is provided by Apple on an \"AS IS\" basis.  APPLE\n MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION\n THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS\n FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND\n OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.\n \n IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL\n OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,\n MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED\n AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),\n STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE\n POSSIBILITY OF SUCH DAMAGE.\n \n Copyright (C) 2014 Apple Inc. All Rights Reserved.\n \n */\n\n#import <Foundation/Foundation.h>\n#import <SystemConfiguration/SystemConfiguration.h>\n#import <netinet/in.h>\n\n\ntypedef enum : NSInteger {\n\tNotReachable = 0,\n\tReachableViaWiFi,\n\tReachableViaWWAN\n} NetworkStatus;\n\n\nextern NSString *kReachabilityChangedNotification;\n\n\n@interface Reachability : NSObject\n\n/*!\n * Use to check the reachability of a given host name.\n */\n+ (instancetype)reachabilityWithHostName:(NSString *)hostName;\n\n/*!\n * Use to check the reachability of a given IP address.\n */\n+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;\n\n/*!\n * Checks whether the default route is available. Should be used by applications that do not connect to a particular host.\n */\n+ (instancetype)reachabilityForInternetConnection;\n\n/*!\n * Checks whether a local WiFi connection is available.\n */\n+ (instancetype)reachabilityForLocalWiFi;\n\n/*!\n * Start listening for reachability notifications on the current run loop.\n */\n- (BOOL)startNotifier;\n- (void)stopNotifier;\n\n- (NetworkStatus)currentReachabilityStatus;\n\n/*!\n * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.\n */\n- (BOOL)connectionRequired;\n\n@end\n\n\n"
  },
  {
    "path": "WHCNetWorkKit/Reachability/Reachability.m",
    "content": "/*\n     File: Reachability.m\n Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.\n  Version: 3.5\n \n Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple\n Inc. (\"Apple\") in consideration of your agreement to the following\n terms, and your use, installation, modification or redistribution of\n this Apple software constitutes acceptance of these terms.  If you do\n not agree with these terms, please do not use, install, modify or\n redistribute this Apple software.\n \n In consideration of your agreement to abide by the following terms, and\n subject to these terms, Apple grants you a personal, non-exclusive\n license, under Apple's copyrights in this original Apple software (the\n \"Apple Software\"), to use, reproduce, modify and redistribute the Apple\n Software, with or without modifications, in source and/or binary forms;\n provided that if you redistribute the Apple Software in its entirety and\n without modifications, you must retain this notice and the following\n text and disclaimers in all such redistributions of the Apple Software.\n Neither the name, trademarks, service marks or logos of Apple Inc. may\n be used to endorse or promote products derived from the Apple Software\n without specific prior written permission from Apple.  Except as\n expressly stated in this notice, no other rights or licenses, express or\n implied, are granted by Apple herein, including but not limited to any\n patent rights that may be infringed by your derivative works or by other\n works in which the Apple Software may be incorporated.\n \n The Apple Software is provided by Apple on an \"AS IS\" basis.  APPLE\n MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION\n THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS\n FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND\n OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.\n \n IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL\n OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,\n MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED\n AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),\n STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE\n POSSIBILITY OF SUCH DAMAGE.\n \n Copyright (C) 2014 Apple Inc. All Rights Reserved.\n \n */\n\n#import <arpa/inet.h>\n#import <ifaddrs.h>\n#import <netdb.h>\n#import <sys/socket.h>\n\n#import <CoreFoundation/CoreFoundation.h>\n\n#import \"Reachability.h\"\n\n\nNSString *kReachabilityChangedNotification = @\"kNetworkReachabilityChangedNotification\";\n\n\n#pragma mark - Supporting functions\n\n#define kShouldPrintReachabilityFlags 1\n\nstatic void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)\n{\n#if kShouldPrintReachabilityFlags\n\n    NSLog(@\"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\\n\",\n          (flags & kSCNetworkReachabilityFlagsIsWWAN)\t\t\t\t? 'W' : '-',\n          (flags & kSCNetworkReachabilityFlagsReachable)            ? 'R' : '-',\n\n          (flags & kSCNetworkReachabilityFlagsTransientConnection)  ? 't' : '-',\n          (flags & kSCNetworkReachabilityFlagsConnectionRequired)   ? 'c' : '-',\n          (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic)  ? 'C' : '-',\n          (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',\n          (flags & kSCNetworkReachabilityFlagsConnectionOnDemand)   ? 'D' : '-',\n          (flags & kSCNetworkReachabilityFlagsIsLocalAddress)       ? 'l' : '-',\n          (flags & kSCNetworkReachabilityFlagsIsDirect)             ? 'd' : '-',\n          comment\n          );\n#endif\n}\n\n\nstatic void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)\n{\n#pragma unused (target, flags)\n\tNSCAssert(info != NULL, @\"info was NULL in ReachabilityCallback\");\n\tNSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @\"info was wrong class in ReachabilityCallback\");\n\n    Reachability* noteObject = (__bridge Reachability *)info;\n    // Post a notification to notify the client that the network reachability changed.\n    [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];\n}\n\n\n#pragma mark - Reachability implementation\n\n@implementation Reachability\n{\n\tBOOL _alwaysReturnLocalWiFiStatus; //default is NO\n\tSCNetworkReachabilityRef _reachabilityRef;\n}\n\n+ (instancetype)reachabilityWithHostName:(NSString *)hostName\n{\n\tReachability* returnValue = NULL;\n\tSCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);\n\tif (reachability != NULL)\n\t{\n\t\treturnValue= [[self alloc] init];\n\t\tif (returnValue != NULL)\n\t\t{\n\t\t\treturnValue->_reachabilityRef = reachability;\n\t\t\treturnValue->_alwaysReturnLocalWiFiStatus = NO;\n\t\t}\n\t}\n\treturn returnValue;\n}\n\n\n+ (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress\n{\n\tSCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);\n\n\tReachability* returnValue = NULL;\n\n\tif (reachability != NULL)\n\t{\n\t\treturnValue = [[self alloc] init];\n\t\tif (returnValue != NULL)\n\t\t{\n\t\t\treturnValue->_reachabilityRef = reachability;\n\t\t\treturnValue->_alwaysReturnLocalWiFiStatus = NO;\n\t\t}\n\t}\n\treturn returnValue;\n}\n\n\n\n+ (instancetype)reachabilityForInternetConnection\n{\n\tstruct sockaddr_in zeroAddress;\n\tbzero(&zeroAddress, sizeof(zeroAddress));\n\tzeroAddress.sin_len = sizeof(zeroAddress);\n\tzeroAddress.sin_family = AF_INET;\n    \n\treturn [self reachabilityWithAddress:&zeroAddress];\n}\n\n\n+ (instancetype)reachabilityForLocalWiFi\n{\n\tstruct sockaddr_in localWifiAddress;\n\tbzero(&localWifiAddress, sizeof(localWifiAddress));\n\tlocalWifiAddress.sin_len = sizeof(localWifiAddress);\n\tlocalWifiAddress.sin_family = AF_INET;\n\n\t// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0.\n\tlocalWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);\n\n\tReachability* returnValue = [self reachabilityWithAddress: &localWifiAddress];\n\tif (returnValue != NULL)\n\t{\n\t\treturnValue->_alwaysReturnLocalWiFiStatus = YES;\n\t}\n    \n\treturn returnValue;\n}\n\n\n#pragma mark - Start and stop notifier\n\n- (BOOL)startNotifier\n{\n\tBOOL returnValue = NO;\n\tSCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};\n\n\tif (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context))\n\t{\n\t\tif (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode))\n\t\t{\n\t\t\treturnValue = YES;\n\t\t}\n\t}\n    \n\treturn returnValue;\n}\n\n\n- (void)stopNotifier\n{\n\tif (_reachabilityRef != NULL)\n\t{\n\t\tSCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);\n\t}\n}\n\n\n- (void)dealloc\n{\n\t[self stopNotifier];\n\tif (_reachabilityRef != NULL)\n\t{\n\t\tCFRelease(_reachabilityRef);\n\t}\n}\n\n\n#pragma mark - Network Flag Handling\n\n- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags\n{\n\tPrintReachabilityFlags(flags, \"localWiFiStatusForFlags\");\n\tNetworkStatus returnValue = NotReachable;\n\n\tif ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))\n\t{\n\t\treturnValue = ReachableViaWiFi;\n\t}\n    \n\treturn returnValue;\n}\n\n\n- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags\n{\n\tPrintReachabilityFlags(flags, \"networkStatusForFlags\");\n\tif ((flags & kSCNetworkReachabilityFlagsReachable) == 0)\n\t{\n\t\t// The target host is not reachable.\n\t\treturn NotReachable;\n\t}\n\n    NetworkStatus returnValue = NotReachable;\n\n\tif ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)\n\t{\n\t\t/*\n         If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...\n         */\n\t\treturnValue = ReachableViaWiFi;\n\t}\n\n\tif ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||\n        (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))\n\t{\n        /*\n         ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...\n         */\n\n        if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)\n        {\n            /*\n             ... and no [user] intervention is needed...\n             */\n            returnValue = ReachableViaWiFi;\n        }\n    }\n\n\tif ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)\n\t{\n\t\t/*\n         ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.\n         */\n\t\treturnValue = ReachableViaWWAN;\n\t}\n    \n\treturn returnValue;\n}\n\n\n- (BOOL)connectionRequired\n{\n\tNSAssert(_reachabilityRef != NULL, @\"connectionRequired called with NULL reachabilityRef\");\n\tSCNetworkReachabilityFlags flags;\n\n\tif (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))\n\t{\n\t\treturn (flags & kSCNetworkReachabilityFlagsConnectionRequired);\n\t}\n\n    return NO;\n}\n\n\n- (NetworkStatus)currentReachabilityStatus\n{\n\tNSAssert(_reachabilityRef != NULL, @\"currentNetworkStatus called with NULL SCNetworkReachabilityRef\");\n\tNetworkStatus returnValue = NotReachable;\n\tSCNetworkReachabilityFlags flags;\n    \n\tif (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))\n\t{\n\t\tif (_alwaysReturnLocalWiFiStatus)\n\t\t{\n\t\t\treturnValue = [self localWiFiStatusForFlags:flags];\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturnValue = [self networkStatusForFlags:flags];\n\t\t}\n\t}\n    \n\treturn returnValue;\n}\n\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/UIButton+WHC_HttpButton.h",
    "content": "//\n//  UIButton+WHC_HttpButton.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import <UIKit/UIKit.h>\n\n@interface UIButton (WHC_HttpButton)\n\n/**\n * 说明: 给按钮设置网络图片 (没有默认图片)\n * @param strUrl 图片地址\n * @param state 图片对应的状态\n */\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl\n                   forState:(UIControlState)state;\n\n/**\n * 说明: 给按钮设置网络图片\n * @param strUrl 图片地址\n * @param state 图片对应的状态\n * @param placeholderImage 默认显示图片\n */\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl\n                   forState:(UIControlState)state\n           placeholderImage:(nullable UIImage *)image;\n\n\n/**\n * 说明: 给按钮背景设置网络图片\n * @param strUrl 图片地址\n * @param state 图片对应的状态\n */\n\n- (void)whc_setBackgroundImageWithURL:(nonnull NSString *)strUrl\n                             forState:(UIControlState)state;\n\n/**\n * 说明: 给按钮背景设置网络图片\n * @param strUrl 图片地址\n * @param state 图片对应的状态\n * @param placeholderImage 默认显示图片\n */\n\n- (void)whc_setBackgroundImageWithURL:(nonnull NSString *)strUrl\n                             forState:(UIControlState)state\n                     placeholderImage:(nullable UIImage *)image;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/UIButton+WHC_HttpButton.m",
    "content": "//\n//  UIButton+WHC_HttpButton.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import \"UIButton+WHC_HttpButton.h\"\n#import <objc/runtime.h>\n#import \"WHC_ImageCache.h\"\n#import \"WHC_HttpManager.h\"\n\n\n@implementation UIButton (WHC_HttpButton)\n\n- (NSMutableDictionary *)operationDictionary {\n    NSMutableDictionary *operationDictionary = objc_getAssociatedObject([WHC_ImageCache shared], &loadOperationKey);\n    if (!operationDictionary) {\n        operationDictionary = [NSMutableDictionary dictionary];\n        objc_setAssociatedObject([WHC_ImageCache shared],\n                                 &loadOperationKey,\n                                 operationDictionary,\n                                 OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n    }\n    return operationDictionary;\n}\n\n- (void)cancelOperationWithState:(UIControlState)state url:(NSString *)strUrl {\n    NSMutableDictionary * operationDict = [self operationDictionary];\n    WHC_BaseOperation * operation = [operationDict objectForKey:@(state).stringValue];\n    if (operation) {\n        if ([operation.strUrl isEqualToString:strUrl]){\n            [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:strUrl];\n        }\n        [operation cancelledRequest];\n        [operationDict removeObjectForKey:@(state).stringValue];\n    }\n}\n\n- (void)addOperation:(WHC_BaseOperation *)operation forState:(UIControlState)state {\n    if (operation) {\n        NSMutableDictionary * operationDict = [self operationDictionary];\n        [operationDict setValue:operation forKey:@(state).stringValue];\n    }\n}\n\n- (void)removeOperationForState:(UIControlState)state url:(NSString *)strUrl{\n    NSMutableDictionary * operationDict = [self operationDictionary];\n    [operationDict removeObjectForKey:@(state).stringValue];\n    if ([operationDict.allKeys containsObject:@(state).stringValue]) {\n        [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:strUrl];\n    }\n}\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl\n                   forState:(UIControlState)state {\n    [self whc_setImageWithUrl:strUrl\n                     forState:state placeholderImage:nil];\n}\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl\n                   forState:(UIControlState)state\n           placeholderImage:(nullable UIImage *)image {\n    if (!strUrl && !image){\n        return;\n    }\n    [self cancelOperationWithState:state url:strUrl];\n    if (image) {\n        [self setImage:image forState:state];\n    }\n    if (![[WHC_HttpManager shared].failedUrls containsObject:strUrl]){\n        __weak typeof(self) weakSelf = self;\n        [[WHC_ImageCache shared]queryImageForUrl:strUrl state:state didFinished:^(UIImage *image , UIControlState state) {\n            if (!image) {\n                if (![WHC_ImageCache shared].callBackDictionary[strUrl]) {\n                    [WHC_ImageCache shared].callBackDictionary[strUrl] = [NSMutableArray array];\n                   WHC_BaseOperation * operation = [[WHC_HttpManager shared] get:strUrl didFinished: ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n                             if (!isSuccess) {\n                                 if (operation) {\n                                     [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                                 }\n                             }else {\n                                 UIImage * image = [UIImage imageWithData:data];\n                                 [weakSelf setImage:image forState:state];\n                                 [[WHC_ImageCache shared] storeImage:image forUrl:operation.strUrl];\n                                 NSMutableArray * urlCallBackArr = [[WHC_ImageCache shared].callBackDictionary[operation.strUrl] copy];\n                                 [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                                 typedef  void (^callBack)(UIImage * image);\n                                 for (NSMutableDictionary * dict in urlCallBackArr) {\n                                     callBack cb = dict[@\"completed\"];\n                                     cb(image);\n                                 }\n                             }\n                         }];\n                    [weakSelf addOperation:operation forState:state];\n                }\n                NSMutableArray *callbacksForURL = [WHC_ImageCache shared].callBackDictionary[strUrl];\n                NSMutableDictionary *callbacks = [NSMutableDictionary dictionary];\n                callbacks[@\"completed\"] = ^(UIImage * image){\n                    [weakSelf setImage:image forState:state];\n                };\n                [callbacksForURL addObject:callbacks];\n                [WHC_ImageCache shared].callBackDictionary[strUrl] = callbacksForURL;\n            }else {\n                [self setImage:image forState:state];\n            }\n        }];\n    }\n}\n\n\n- (void)whc_setBackgroundImageWithURL:(nonnull NSString *)strUrl\n                             forState:(UIControlState)state {\n    [self whc_setBackgroundImageWithURL:strUrl\n                               forState:state placeholderImage:nil];\n}\n\n- (void)whc_setBackgroundImageWithURL:(nonnull NSString *)strUrl\n                             forState:(UIControlState)state\n                     placeholderImage:(nullable UIImage *)image {\n    if (!strUrl && !image){\n        return;\n    }\n    [self cancelOperationWithState:state url:strUrl];\n    if (image) {\n        [self setBackgroundImage:image forState:state];\n    }\n    if (![[WHC_HttpManager shared].failedUrls containsObject:strUrl]){\n        __weak typeof(self) weakSelf = self;\n        [[WHC_ImageCache shared]queryImageForUrl:strUrl state:state didFinished:^(UIImage *image , UIControlState state) {\n            if (!image) {\n                if (![WHC_ImageCache shared].callBackDictionary[strUrl]) {\n                    [WHC_ImageCache shared].callBackDictionary[strUrl] = [NSMutableArray array];\n                    WHC_BaseOperation * operation = [[WHC_HttpManager shared] get:strUrl didFinished: ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n                        if (!isSuccess) {\n                            if (operation) {\n                                [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                            }\n                        }else {\n                            UIImage * image = [UIImage imageWithData:data];\n                            [weakSelf setBackgroundImage:image forState:state];\n                            [[WHC_ImageCache shared] storeImage:image forUrl:operation.strUrl];\n                            NSMutableArray * urlCallBackArr = [[WHC_ImageCache shared].callBackDictionary[operation.strUrl] copy];\n                            [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                            typedef  void (^callBack)(UIImage * image);\n                            for (NSMutableDictionary * dict in urlCallBackArr) {\n                                callBack cb = dict[@\"completed\"];\n                                cb(image);\n                            }\n                        }\n                    }];\n                    [weakSelf addOperation:operation forState:state];\n                }\n                NSMutableArray *callbacksForURL = [WHC_ImageCache shared].callBackDictionary[strUrl];\n                NSMutableDictionary *callbacks = [NSMutableDictionary dictionary];\n                callbacks[@\"completed\"] = ^(UIImage * image){\n                    [weakSelf setBackgroundImage:image forState:state];\n                };\n                [callbacksForURL addObject:callbacks];\n                [WHC_ImageCache shared].callBackDictionary[strUrl] = callbacksForURL;\n            }else {\n                [weakSelf setBackgroundImage:image forState:state];\n            }\n        }];\n    }\n}\n\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/UIImageView+WHC_HttpImageView.h",
    "content": "//\n//  UIImageView+WHC_HttpImageView.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import <UIKit/UIKit.h>\n\n@interface UIImageView (WHC_HttpImageView)\n\n/**\n * 说明: 给UIImageView背景设置网络图片\n * @param strUrl 图片地址\n */\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl ;\n\n/**\n * 说明: 给UIImageView背景设置网络图片\n * @param strUrl 图片地址\n * @param placeholderImage 默认显示图片\n */\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl placeholderImage:(nullable UIImage *)image;\n\n/**\n * 说明: 给UIImageView 设置本地git图片\n * @param path gif本地路径\n */\n- (void)setGifWithPath:(nonnull NSString *)path;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/UIImageView+WHC_HttpImageView.m",
    "content": "//\n//  UIImageView+WHC_HttpImageView.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import \"UIImageView+WHC_HttpImageView.h\"\n#import <objc/runtime.h>\n#import \"WHC_ImageCache.h\"\n#import \"WHC_HttpManager.h\"\n#import <ImageIO/ImageIO.h>\n\n@implementation UIImageView (WHC_HttpImageView)\n\n- (NSMutableDictionary *)operationDictionary {\n    NSMutableDictionary *operationDictionary = objc_getAssociatedObject([WHC_ImageCache shared], &loadOperationKey);\n    if (!operationDictionary) {\n        operationDictionary = [NSMutableDictionary dictionary];\n        objc_setAssociatedObject([WHC_ImageCache shared], &loadOperationKey, operationDictionary, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n    }\n    return operationDictionary;\n}\n\n- (void)cancelOperationWithUrl:(NSString *)strUrl {\n    NSMutableDictionary * operationDictionary = [self operationDictionary];\n    WHC_BaseOperation * operation = [operationDictionary objectForKey:strUrl];\n    if (operation) {\n        [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:strUrl];\n        [operation cancelledRequest];\n        [operationDictionary removeObjectForKey:strUrl];\n    }\n}\n\n- (void)addOperation:(WHC_BaseOperation *)operation url:(NSString *)strUrl{\n    if (operation) {\n        NSMutableDictionary * operationDict = [self operationDictionary];\n        [operationDict setValue:operation forKey:strUrl];\n    }\n}\n\n- (void)removeOperationForUrl:(NSString *)strUrl{\n    NSMutableDictionary * operationDict = [self operationDictionary];\n    [operationDict removeObjectForKey:strUrl];\n    [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:strUrl];\n}\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl {\n    [self whc_setImageWithUrl:strUrl placeholderImage:nil];\n}\n\n- (void)whc_setImageWithUrl:(nonnull NSString *)strUrl placeholderImage:(nullable UIImage *)image {\n    if (!strUrl && !image){\n        return;\n    }\n    [self cancelOperationWithUrl:strUrl];\n    if (image) {\n        [self setImage:image];\n    }\n    if (![[WHC_HttpManager shared].failedUrls containsObject:strUrl]){\n        __weak typeof(self) weakSelf = self;\n        [[WHC_ImageCache shared]queryImageForUrl:strUrl\n                                           state:UIControlStateNormal\n                                     didFinished:^(UIImage *image , UIControlState state) {\n            if (!image) {\n                if (![WHC_ImageCache shared].callBackDictionary[strUrl]) {\n                    [WHC_ImageCache shared].callBackDictionary[strUrl] = [NSMutableArray array];\n                    WHC_BaseOperation * operation = [[WHC_HttpManager shared] get:strUrl didFinished: ^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n                        if (!isSuccess) {\n                            if (operation) {\n                                [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                            }\n                        }else {\n                            UIImage * image = nil;\n                            if ([[[WHC_HttpManager shared] fileFormatWithUrl:operation.strUrl] isEqualToString:@\".gif\"]) {\n                                image = [self gifImageWithData:data];\n                            }else {\n                                image = [UIImage imageWithData:data];\n                            }\n                            [weakSelf setImage:image];\n                            [[WHC_ImageCache shared] storeImage:image forUrl:operation.strUrl];\n                            NSMutableArray * urlCallBackArr = [[WHC_ImageCache shared].callBackDictionary[operation.strUrl] copy];\n                            [[WHC_ImageCache shared].callBackDictionary removeObjectForKey:operation.strUrl];\n                            typedef  void (^callBack)(UIImage * image);\n                            for (NSMutableDictionary * dict in urlCallBackArr) {\n                                callBack cb = dict[@\"completed\"];\n                                cb(image);\n                            }\n                        }\n                    }];\n                    [weakSelf addOperation:operation url:strUrl];\n                }\n                NSMutableArray *callbacksForURL = [WHC_ImageCache shared].callBackDictionary[strUrl];\n                NSMutableDictionary *callbacks = [NSMutableDictionary dictionary];\n                callbacks[@\"completed\"] = ^(UIImage * image){\n                    [weakSelf setImage:image];\n                };\n                [callbacksForURL addObject:callbacks];\n                [WHC_ImageCache shared].callBackDictionary[strUrl] = callbacksForURL;\n            }else {\n                [self setImage:image];\n            }\n        }];\n    }\n}\n\n- (void)setGifWithPath:(nonnull NSString *)path {\n    NSData *data = [NSData dataWithContentsOfFile:path];\n    self.image = [self gifImageWithData:data];\n}\n\n- (UIImage *)gifImageWithData:(NSData *)gifData{\n    NSMutableArray  * imageArr = [NSMutableArray array];\n    CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef) gifData, NULL);\n    NSTimeInterval animationDuration = 0.0;\n    if (src) {\n        NSUInteger frameCount = CGImageSourceGetCount(src);\n        NSDictionary *gifProperties = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyProperties(src, NULL));\n        if(gifProperties) {\n            NSDictionary *gifDictionary =[gifProperties objectForKey:(NSString*)kCGImagePropertyGIFDictionary];\n            NSUInteger loopCount = [[gifDictionary objectForKey:(NSString*)kCGImagePropertyGIFLoopCount] integerValue];\n            self.animationRepeatCount = loopCount;\n            for (NSUInteger i = 0; i < frameCount; i++) {\n                CGImageRef img = CGImageSourceCreateImageAtIndex(src, (size_t) i, NULL);\n                if (img) {\n                    UIImage *frameImage = [UIImage imageWithCGImage:img];\n                    if(frameImage){\n                        [imageArr addObject:frameImage];\n                    }\n                    NSDictionary *frameProperties = (NSDictionary *) CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(src, (size_t) i, NULL));\n                    if (frameProperties) {\n                        NSDictionary *frameDictionary = [frameProperties objectForKey:(NSString*)kCGImagePropertyGIFDictionary];\n                        CGFloat delayTime = [[frameDictionary objectForKey:(NSString*)kCGImagePropertyGIFDelayTime] floatValue];\n                        animationDuration += delayTime;\n                    }\n                    CGImageRelease(img);\n                }\n            }\n        }\n        CFRelease(src);\n    }\n    return [UIImage animatedImageWithImages:imageArr duration:animationDuration];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/WHC_ImageCache.h",
    "content": "//\n//  WHC_ImageCache.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n/**\n * 读取当前图片下载操作key\n */\n\nstatic char loadOperationKey;\n\n/**\n * 查询本地磁盘缓存和内存缓存结束回调块\n * @param: image 查询获取的图片对象\n * @param: state 图片显示对应的状态(这个只针对UIButton)\n */\n\ntypedef void(^WHCImageQueryFinished)(UIImage * _Nullable image , UIControlState state);\n\n/**\n * 说明: WHC_ImageCache 网络下载图片缓存类\n */\n\n@interface WHC_ImageCache : NSObject\n\n/**\n * 说明: WHC_ImageCache 单例对象\n */\n\n+ (nonnull instancetype)shared;\n\n/**\n * 网络请求404错误集合(下次再遇到则不请求)\n */\n\n@property (nonatomic , strong , nonnull) NSMutableSet * failedUrls;\n\n/**\n * 异步图片下载回调块字典集合\n */\n\n@property (nonatomic , strong , nonnull) NSMutableDictionary * callBackDictionary;\n\n/**\n * 正在进行异步图片下载操作对象数组集合\n */\n\n@property (nonatomic , strong , nonnull) NSMutableArray * runningOperationArray;\n\n/**\n * 存储图片对象\n * @param: image 图片对象\n * @param: strUrl 图片下载地址\n */\n\n- (void)storeImage:(nonnull UIImage *)image\n            forUrl:(nonnull NSString *)strUrl;\n\n/**\n * 查询本地磁盘缓存和内存缓存图片(异步查询)\n * @param: strUrl 图片下载地址\n * @param: state 图片对应得按钮状态(这个只针对UIButton)\n * @param: finishedBlock 查询完成回调块\n */\n\n- (void)queryImageForUrl:(nonnull NSString *)strUrl\n                   state:(UIControlState)state\n             didFinished:(nullable WHCImageQueryFinished)finishedBlock;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UIKit+WHCNetWorkKit/WHC_ImageCache.m",
    "content": "//\n//  WHC_ImageCache.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/11/6.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import \"WHC_ImageCache.h\"\n#import <CommonCrypto/CommonDigest.h>\n#import \"WHC_HttpManager.h\"\n#import <objc/runtime.h>\n\n#define kWHCImageCachePath (@\"WHCImageCache\")\n\n\n\n@interface WHC_Cache : NSCache\n\n@end\n\n@implementation WHC_Cache\n\n- (id)init {\n    self = [super init];\n    if (self) {\n        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];\n    }\n    return self;\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self\n                                                    name:UIApplicationDidReceiveMemoryWarningNotification\n                                                  object:nil];\n}\n\n@end\n\n@interface WHC_ImageCache (){\n    NSFileManager  * _fileManager;\n    dispatch_queue_t _fileQueue;\n}\n@property (nonatomic , strong) WHC_Cache * memCache;\n@property (nonatomic , strong) NSString * diskCachePath;\n\n@end\n\nstatic inline NSUInteger WHCCacheCostForImage(UIImage *image) {\n    return image.size.height * image.size.width * image.scale * image.scale;\n}\n\n@implementation WHC_ImageCache\n\n+ (nonnull instancetype)shared {\n    static WHC_ImageCache * imageCache;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        imageCache = [WHC_ImageCache new];\n    });\n    return imageCache;\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _callBackDictionary = [NSMutableDictionary dictionary];\n        _runningOperationArray = [NSMutableArray array];\n        _fileQueue = dispatch_queue_create([NSStringFromClass(self.class) UTF8String], NULL);\n        _failedUrls = [NSMutableSet set];\n        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);\n        _diskCachePath = [paths[0] stringByAppendingPathComponent:kWHCImageCachePath];\n        \n        _memCache = [WHC_Cache new];\n        _memCache.name = kWHCImageCachePath;\n        \n        dispatch_sync(_fileQueue, ^{\n            _fileManager = [NSFileManager new];\n            if (![_fileManager fileExistsAtPath:_diskCachePath]) {\n                [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];\n            }\n        });\n        \n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(clearMemory)\n                                                     name:UIApplicationDidReceiveMemoryWarningNotification\n                                                   object:nil];\n        \n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(cleanDisk)\n                                                     name:UIApplicationWillTerminateNotification\n                                                   object:nil];\n    }\n    return self;\n}\n\n- (NSString *)cachedImageFileNameForUrl:(NSString *)strUrl {\n    NSMutableString * cachedFileName = [NSMutableString string];\n    if (strUrl != nil) {\n        const char * cStr = strUrl.UTF8String;\n        unsigned char buffer[CC_MD5_DIGEST_LENGTH];\n        memset(buffer, 0x00, CC_MD5_DIGEST_LENGTH);\n        CC_MD5(cStr, (CC_LONG)(strlen(cStr)), buffer);\n        for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {\n            [cachedFileName appendFormat:@\"%02x\",buffer[i]];\n        }\n        return cachedFileName;\n    }\n    return nil;\n}\n\n- (UIImage *)diskImageForUrl:(NSString *)strUrl {\n    NSString * filePath = [_diskCachePath stringByAppendingPathComponent:[self cachedImageFileNameForUrl:strUrl]];\n    BOOL isDirectory = NO;\n    if ([_fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {\n        NSData * imageData = [NSData dataWithContentsOfFile:filePath];\n        if (imageData){\n            return [UIImage imageWithData:imageData];\n        }else {\n            return nil;\n        }\n    }\n    return nil;\n}\n\n- (void)storeImage:(UIImage *)image forUrl:(NSString *)strUrl {\n    if (!image || !strUrl){\n        return;\n    }\n    [self.memCache setObject:image forKey:strUrl cost:WHCCacheCostForImage(image)];\n    dispatch_async(_fileQueue, ^{\n        NSString * filePath = [_diskCachePath stringByAppendingPathComponent:[self cachedImageFileNameForUrl:strUrl]];\n        NSString * imageFormat = [[WHC_HttpManager shared] fileFormatWithUrl:strUrl];\n        NSData * imageData = nil;\n        if ([imageFormat isEqualToString:@\".png\"]) {\n            imageData = UIImagePNGRepresentation(image);\n        }else {\n            imageData = UIImageJPEGRepresentation(image, 1.0);\n        }\n        [_fileManager createFileAtPath:filePath contents:imageData attributes:NULL];\n    });\n}\n\n- (void)queryImageForUrl:(NSString *)strUrl state:(UIControlState)state didFinished:(WHCImageQueryFinished)finishedBlock {\n    if (!finishedBlock) {\n        return;\n    }\n    if (!strUrl) {\n        finishedBlock(nil , state);\n        return;\n    }\n    \n    UIImage * image = [self.memCache objectForKey:strUrl];\n    if (image) {\n        finishedBlock(image , state);\n    }else {\n        dispatch_async(_fileQueue, ^{\n            @autoreleasepool {\n                UIImage *diskImage = [self diskImageForUrl:strUrl];\n                if (diskImage) {\n                    [self.memCache setObject:diskImage forKey:strUrl cost:WHCCacheCostForImage(diskImage)];\n                }\n                dispatch_async(dispatch_get_main_queue(), ^{\n                    finishedBlock(diskImage , state);\n                });\n            }\n        });\n    }\n}\n\n- (void)clearMemory {\n    [self.memCache removeAllObjects];\n}\n\n- (void)cleanDisk {\n    dispatch_async(_fileQueue, ^{\n        [_fileManager removeItemAtPath:_diskCachePath error:nil];\n        [_fileManager createDirectoryAtPath:self.diskCachePath\n                withIntermediateDirectories:YES\n                                 attributes:nil\n                                      error:NULL];\n    });\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_DataModel.h",
    "content": "//\n//  WHC_DataModel.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * 说明: WHC_DataModel json/xml转模型类对象\n */\n\n@interface WHC_DataModel : NSObject\n\n/**\n * 说明: json/xml (data)数据对象转模型类对象数组\n * @param: data json/xml数据对象\n * @param: className 模型类\n */\n\n+ (NSArray *)dataModelWithArrayData:(NSData *)data className:(Class)className;\n\n/**\n * 说明: json/xml (array)数组对象转模型类对象数组\n * @param: array json/xml数组对象\n * @param: className 模型类\n */\n\n+ (NSArray*)dataModelWithArray:(NSArray*)array className:(Class)className;\n\n/**\n * 说明: json/xml (dictionary)字典对象转模型类对象\n * @param: data json/xml字典对象\n * @param: className 模型类\n */\n\n+ (id)dataModelWithDictionary:(NSDictionary*)dictionary className:(Class)className;\n\n/**\n * 说明: json/xml (data)字典对象转模型类对象\n * @param: data json/xml字典对象\n * @param: className 模型类\n */\n\n+ (id)dataModelWithDictionaryData:(NSData *)data className:(Class)className;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_DataModel.m",
    "content": "//\n//  WHC_DataModel.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_DataModel.h\"\n#import <objc/runtime.h>\n#define kWHCKey    (@\"\")\n@interface WHC_DataModel (){\n    \n}\n\n@end\n@implementation WHC_DataModel\n\n- (instancetype)init{\n    self = [super init];\n    if(self){\n    \n    }\n    return self;\n}\n\n+ (NSArray *)dataModelWithArrayData:(NSData *)data className:(Class)className{\n    NSArray * array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];\n    return [WHC_DataModel dataModelWithArray:array className:className];\n}\n\n+ (NSArray*)dataModelWithArray:(NSArray*)array className:(Class)className{\n    NSMutableArray * _array = [NSMutableArray new];\n    for (NSDictionary * dict in array) {\n        [_array addObject:[WHC_DataModel dataModelWithDictionary:dict className:className]];\n    }\n    return _array;\n}\n\n+ (id)dataModelWithDictionary:(NSDictionary*)dictionary className:(Class)className{\n    WHC_DataModel  * whcDataModel = [WHC_DataModel new];\n    id object = [whcDataModel handleDataModelEngine:dictionary arrKey:kWHCKey calssName:className];\n    return object;\n}\n\n+ (id)dataModelWithDictionaryData:(NSData *)data className:(Class)className{\n    NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];\n    return [WHC_DataModel dataModelWithDictionary:dict className:className];\n}\n\n- (NSString *)getClassNameString:(const char *)attr{\n    NSString * strClassName = nil;\n    NSString * attrStr = @(attr);\n    NSRange  oneRange = [attrStr rangeOfString:@\"T@\\\"\"];\n    if(oneRange.location != NSNotFound){\n        NSRange twoRange = [attrStr rangeOfString:@\"\\\"\" options:NSBackwardsSearch];\n        if(twoRange.location != NSNotFound){\n            NSRange  classRange = NSMakeRange(oneRange.location + oneRange.length, twoRange.location - (oneRange.location + oneRange.length));\n            strClassName = [attrStr substringWithRange:classRange];\n        }\n    }\n    return strClassName;\n}\n\n- (BOOL)existproperty:(NSString *)property withObject:(NSObject *)object{\n    unsigned int  propertyCount = 0;\n    Ivar *vars = class_copyIvarList([object class], &propertyCount);\n    for (NSInteger i = 0; i < propertyCount; i++) {\n        Ivar var = vars[i];\n        NSString * tempProperty = [[NSString stringWithUTF8String:ivar_getName(var)] stringByReplacingOccurrencesOfString:@\"_\" withString:@\"\"];\n        if([property isEqualToString:tempProperty]){\n            return YES;\n        }\n    }\n    return NO;\n}\n\n- (Class)classExistProperty:(NSString *)property withObject:(NSObject *)object{\n    Class  class = [NSNull class];\n    unsigned int  propertyCount = 0;\n    Ivar *vars = class_copyIvarList([object class], &propertyCount);\n    for (NSInteger i = 0; i < propertyCount; i++) {\n        Ivar var = vars[i];\n        NSString * tempProperty = [[NSString stringWithUTF8String:ivar_getName(var)] stringByReplacingOccurrencesOfString:@\"_\" withString:@\"\"];\n        if([property isEqualToString:tempProperty]){\n            NSString * type = [NSString stringWithUTF8String:ivar_getTypeEncoding(var)];\n            if([type hasPrefix:@\"@\"]){\n                type = [type stringByReplacingOccurrencesOfString:@\"@\" withString:@\"\"];\n                type = [type stringByReplacingOccurrencesOfString:@\"\\\"\" withString:@\"\"];\n                class = NSClassFromString(type);\n            }\n        }\n    }\n    return class;\n}\n\n- (id)handleDataModelEngine:(id)object arrKey:(NSString*)arrKey calssName:(Class)className{\n    if(object){\n        id  modelObject = [className new];\n        if([object isKindOfClass:[NSDictionary class]]){\n            NSDictionary  * dict = object;\n            NSInteger       count = dict.count;\n            NSArray       * keyArr = [dict allKeys];\n            for (NSInteger i = 0; i < count; i++) {\n                id subObject = dict[keyArr[i]];\n                if(subObject){\n                    if([self classExistProperty:keyArr[i] withObject:modelObject] == [NSDictionary class]){\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@{} forKey:keyArr[i]];\n                        }else{\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:keyArr[i] calssName:objc_getClass([keyArr[i] UTF8String])];\n                            [modelObject setValue:subModelObject forKey:keyArr[i]];\n                        }\n                    }else if ([self classExistProperty:keyArr[i] withObject:modelObject] == [NSArray class]){\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@[] forKey:keyArr[i]];\n                        }else{\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:keyArr[i] calssName:objc_getClass([keyArr[i] UTF8String])];\n                            [modelObject setValue:[subModelObject mutableCopy] forKey:keyArr[i]];\n                        }\n                    }else if ([self classExistProperty:keyArr[i] withObject:modelObject] == [NSString class]){\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@\"\" forKey:keyArr[i]];\n                        }else{\n                            [modelObject setValue:subObject forKey:keyArr[i]];\n                        }\n                    }else if ([self classExistProperty:keyArr[i] withObject:modelObject] == [NSNumber class]){\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@(0) forKey:keyArr[i]];\n                        }else{\n                            [modelObject setValue:subObject forKey:keyArr[i]];\n                        }\n                    }else{\n                        if(subObject && ![subObject isKindOfClass:[NSNull class]]){\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:keyArr[i] calssName:objc_getClass([keyArr[i] UTF8String])];\n                            if([self existproperty:keyArr[i] withObject:modelObject]){\n                                [modelObject setValue:subModelObject forKey:keyArr[i]];\n                            }\n                        }else{\n                            if([self existproperty:keyArr[i] withObject:modelObject]){\n                                [modelObject setValue:@\"\" forKey:keyArr[i]];\n                            }\n                        }\n                    }\n                }\n            }\n        }else if ([object isKindOfClass:[NSArray class]]){\n            NSArray  * objectArr = object;\n            NSInteger  count = objectArr.count;\n            NSMutableArray  * modelObjectArr = [NSMutableArray new];\n            for (NSInteger i = 0; i < count; i++) {\n                id subModelObject = [self handleDataModelEngine:objectArr[i] arrKey:arrKey calssName:objc_getClass([arrKey UTF8String])];\n                if(subModelObject){\n                    [modelObjectArr addObject:subModelObject];\n                }\n            }\n            modelObject = nil;\n            return modelObjectArr;\n        }else if([object isKindOfClass:[NSString class]]){\n            if(object){\n                return object;\n            }else{\n                return @\"\";\n            }\n        }else if([object isKindOfClass:[NSNumber class]]){\n            if(object){\n                return object;\n            }else{\n                return @(0);\n            }\n        }else{\n            unsigned int propertyCount = 0;\n            objc_property_t  * propertys = class_copyPropertyList(className, &propertyCount);\n            for (int i = 0; i < propertyCount; i++) {\n                NSString * propertyName = @(property_getName(propertys[i]));\n                NSString * classType = [self getClassNameString:property_getAttributes(propertys[i])];\n                if(classType){\n                    Class propertyClass = objc_getClass([classType UTF8String]);\n                    if(propertyClass == [NSDictionary class]){\n                        id subObject = [object objectForKey:propertyName];\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@{} forKey:propertyName];\n                        }else{\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:propertyName calssName:objc_getClass([propertyName UTF8String])];\n                            [modelObject setValue:subModelObject forKey:propertyName];\n                        }\n                    }else if (propertyClass == [NSArray class]){\n                        id subObject = [object objectForKey:propertyName];\n                        if([subObject isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:@[] forKey:propertyName];\n                        }else{\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:propertyName calssName:objc_getClass([arrKey UTF8String])];\n                            [modelObject setValue:subModelObject forKey:propertyName];\n                        }\n                    }else if(propertyClass == [NSString class] ||\n                             propertyClass == [NSNumber class]){\n                        id value = [object objectForKey:propertyName];\n                        if(value && ![value isKindOfClass:[NSNull class]]){\n                            [modelObject setValue:value forKey:propertyName];\n                        }else{\n                            if([value isKindOfClass:[NSString class]]){\n                                [modelObject setValue:@\"\" forKey:propertyName];\n                            }else{\n                                [modelObject setValue:@(0) forKey:propertyName];\n                            }\n                        }\n                    }else if (propertyClass == objc_getClass([propertyName UTF8String])){\n                        id subObject = [object objectForKey:propertyName];\n                        if(subObject && ![subObject isKindOfClass:[NSNull class]]){\n                            id subModelObject = [self handleDataModelEngine:subObject arrKey:propertyName calssName:objc_getClass([propertyName UTF8String])];\n                           [modelObject setValue:subModelObject forKey:propertyName];\n                        }else{\n                            [modelObject setValue:[objc_getClass([propertyName UTF8String]) new] forKey:propertyName];\n                        }\n                    }\n                }\n            }\n        }\n        return modelObject;\n    }else{\n        NSLog(@\"有object = nil\");\n    }\n    return nil;\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_Json.h",
    "content": "//\n//  WHC_Json.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * 说明: WHC_Json dictionary对象转换为json字符串\n */\n\n@interface WHC_Json : NSObject\n\n\n/**\n * 说明: dictionary对象转换为json字符串\n */\n+ (NSString *)jsonWithDictionary:(NSDictionary*)dictionary;\n\n/**\n * 说明: jsonData对象转换为NSDictionary对象\n */\n+ (NSDictionary *)dictionaryWithJsonData:(NSData *)jsonData;\n\n/**\n * 说明: json字符串对象转换为NSDictionary对象\n */\n+ (NSDictionary *)dictionaryWithJson:(NSString *)json;\n\n/**\n * 说明: jsonData对象转换为NSArray对象\n */\n+ (NSArray *)arrayWithJsonData:(NSData *)jsonData;\n\n/**\n * 说明: json字符串对象转换为NSArray对象\n */\n+ (NSArray *)arrayWithJson:(NSString *)json;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_Json.m",
    "content": "//\n//  WHC_Json.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_Json.h\"\n\n@interface WHC_Json (){\n    NSMutableString            * _jsonString;     //存放json字符串\n}\n\n@end\n\n@implementation WHC_Json\n\n- (instancetype)init{\n    self = [super init];\n    if(self){\n        _jsonString  = [NSMutableString new];\n        [_jsonString appendString:@\"{\"];\n    }\n    return self;\n}\n\n+ (NSString*)jsonWithDictionary:(NSDictionary *)dictionary{\n    assert(dictionary);\n    WHC_Json  * whcJson = [WHC_Json new];\n    return [NSString stringWithFormat:@\"%@}\",[whcJson handleDictionaryEngine:dictionary]];\n}\n\n+ (NSDictionary *)dictionaryWithJsonData:(NSData *)jsonData {\n    assert(jsonData);\n    return [NSJSONSerialization JSONObjectWithData:jsonData\n                                           options:NSJSONReadingAllowFragments error:nil];\n}\n\n+ (NSDictionary *)dictionaryWithJson:(NSString *)json {\n    assert(json);\n    return [WHC_Json dictionaryWithJsonData:[json dataUsingEncoding:NSUTF8StringEncoding]];\n}\n\n+ (NSArray *)arrayWithJsonData:(NSData *)jsonData {\n    assert(jsonData);\n    return [NSJSONSerialization JSONObjectWithData:jsonData\n                                           options:NSJSONReadingAllowFragments error:nil];\n}\n\n+ (NSArray *)arrayWithJson:(NSString *)json {\n    assert(json);\n    return [WHC_Json arrayWithJsonData:[json dataUsingEncoding:NSUTF8StringEncoding]];\n}\n\n\n- (NSString*)handleDictionaryEngine:(id)object{\n    if([object isKindOfClass:[NSDictionary class]]){\n        NSDictionary  * dict = object;\n        NSInteger       count = dict.count;\n        NSArray       * keyArr = [dict allKeys];\n        for (NSInteger i = 0; i < count; i++) {\n            id subObject = dict[keyArr[i]];\n            if([subObject isKindOfClass:[NSDictionary class]]){\n                [_jsonString appendFormat:@\"\\\"%@\\\":{\",keyArr[i]];\n                [self handleDictionaryEngine:subObject];\n                [_jsonString appendString:@\"}\"];\n                if(i < count - 1){\n                    [_jsonString appendString:@\",\"];\n                }\n            }else if ([subObject isKindOfClass:[NSArray class]]){\n                [_jsonString appendFormat:@\"\\\"%@\\\":[\",keyArr[i]];\n                [self handleDictionaryEngine:subObject];\n                [_jsonString appendString:@\"]\"];\n                if(i < count - 1){\n                    [_jsonString appendString:@\",\"];\n                }\n            }else if([subObject isKindOfClass:[NSString class]]){\n                [_jsonString appendFormat:@\"\\\"%@\\\":\\\"%@\\\"\",keyArr[i],subObject];\n                if(i < count - 1){\n                    [_jsonString appendString:@\",\"];\n                }\n            }else if([subObject isKindOfClass:[NSNumber class]]){\n                [_jsonString appendFormat:@\"\\\"%@\\\":%@\",keyArr[i],subObject];\n                if(i < count - 1){\n                    [_jsonString appendString:@\",\"];\n                }\n            }\n        }\n    }else if([object isKindOfClass:[NSArray class]]){\n        NSArray  * dictArr = object;\n        NSInteger  count = dictArr.count;\n        for (NSInteger i = 0; i < count; i++) {\n            [_jsonString appendString:@\"{\"];\n            [self handleDictionaryEngine:dictArr[i]];\n            [_jsonString appendString:@\"}\"];\n            if(i < count - 1){\n                [_jsonString appendString:@\",\"];\n            }\n        }\n    }\n    return _jsonString;\n}\n\n- (void)checkIsAddComma:(id)object{\n    if(![object isKindOfClass:[NSArray class]] &&\n       ![object isKindOfClass:[NSDictionary class]]){\n        [_jsonString appendString:@\",\"];\n    }\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_XMLParser.h",
    "content": "//\n//  WHC_XMLParse.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/28.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import <Foundation/Foundation.h>\n\n#define  kWHCCanFilterString (@\":\")                 //可过滤的字符串\n\ntypedef enum:NSInteger {\n    WHC_XMLParserOptionsProcessNamespaces           = 1 << 0, // 指定是否接对象名称空间和元素的限定名称\n    WHC_XMLParserOptionsReportNamespacePrefixes     = 1 << 1, // 指定是否接对象名称空间声明的范围\n    WHC_XMLParserOptionsResolveExternalEntities     = 1 << 2, // 指定的接收对象声明是否外部实体\n}WHC_XMLParserOptions;\n\n/**\n * 说明 WHC_XMLParser xml解析器自动把xml字符串解析为字典对象(和json字符串解析为字典一样无任何多余key)\n */\n\n@interface WHC_XMLParser : NSObject\n\n/**\n * 说明: xml数据对象解析为字典\n * @param: data xml数据对象\n */\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data;\n\n/**\n * 说明: xml数据对象解析为字典\n * @param: data xml数据对象\n */\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string;\n\n/**\n * 说明: xml数据对象解析为字典\n * @param: data xml数据对象\n * @param: options xml解析类型\n */\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(WHC_XMLParserOptions)options;\n\n/**\n * 说明: xml字符串对象解析为字典\n * @param: string xml字符串对象\n * @param: options xml解析类型\n */\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(WHC_XMLParserOptions)options;\n\n/**\n * 说明: xml数据对象解析为字典\n * @param: data xml数据对象\n * @param: filterString xml解析过滤字符串\n */\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data filterString:(NSString *)filterString;\n\n/**\n * 说明: xml字符串对象解析为字典\n * @param: string xml字符串对象\n * @param: filterString xml解析过滤字符串\n */\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string filterString:(NSString *)filterString;\n\n/**\n * 说明: xml数据对象解析为字典\n * @param: data xml数据对象\n * @param: filterString xml解析过滤字符串\n * @param: options xml解析类型\n */\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data filterString:(NSString *)filterString options:(WHC_XMLParserOptions)options;\n\n/**\n * 说明: xml字符串对象解析为字典\n * @param: string xml字符串对象\n * @param: filterString xml解析过滤字符串\n * @param: options xml解析类型\n */\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string filterString:(NSString *)filterString options:(WHC_XMLParserOptions)options;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_XMLParser.m",
    "content": "//\n//  WHC_XMLParse.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/28.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n#import \"WHC_XMLParser.h\"\n\n#define kWHCXMLParserTextNodeKey\t\t(@\"WHC_TXT\")\n@interface WHC_XMLParser ()<NSXMLParserDelegate>{\n    NSMutableArray            *     _dictArr;             //存放字典数组\n    NSMutableString           *     _contentTxt;          //存放当前解析内容文字\n    NSError                   *     _error;               //存放错误信息\n    NSString                  *     _filterString;        //要过滤字符串\n}\n\n@end\n\n@implementation WHC_XMLParser\n\n- (instancetype)init{\n    self = [super init];\n    if(self){\n        _error = [NSError new];\n        _dictArr = [NSMutableArray new];\n        _contentTxt = [NSMutableString new];\n    }\n    return self;\n}\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data{\n    return [WHC_XMLParser dictionaryForXMLData:data options:0];\n}\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string{\n    return [WHC_XMLParser dictionaryForXMLData:[string dataUsingEncoding:NSUTF8StringEncoding]];\n}\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(WHC_XMLParserOptions)options{\n    WHC_XMLParser  * whc_xmlParser = [WHC_XMLParser new];\n   return [whc_xmlParser startParserXML:data options:options];\n}\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(WHC_XMLParserOptions)options{\n    return [WHC_XMLParser dictionaryForXMLData:[string dataUsingEncoding:NSUTF8StringEncoding] options:options];\n}\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data filterString:(NSString *)filterString{\n    return [WHC_XMLParser dictionaryForXMLData:data filterString:filterString options:0];\n}\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string filterString:(NSString *)filterString{\n    return [WHC_XMLParser dictionaryForXMLString:string filterString:filterString options:0];\n}\n\n+ (NSDictionary *)dictionaryForXMLData:(NSData *)data filterString:(NSString *)filterString options:(WHC_XMLParserOptions)options{\n    WHC_XMLParser  * whc_xmlParser = [WHC_XMLParser new];\n    [whc_xmlParser setFilterString:filterString];\n    return [whc_xmlParser startParserXML:data options:options];\n}\n\n+ (NSDictionary *)dictionaryForXMLString:(NSString *)string filterString:(NSString *)filterString options:(WHC_XMLParserOptions)options{\n    return [WHC_XMLParser dictionaryForXMLData:[string dataUsingEncoding:NSUTF8StringEncoding] filterString:filterString options:options];\n}\n\n- (void)setFilterString:(NSString*)filterString{\n    if(filterString){\n        _filterString = [filterString copy];\n    }\n}\n\n\n- (NSDictionary*)startParserXML:(NSData*)data options:(WHC_XMLParserOptions)options{\n    [_dictArr addObject:[NSMutableDictionary new]];\n    NSXMLParser  * xmlParser = [[NSXMLParser alloc]initWithData:data];\n    xmlParser.delegate = self;\n    xmlParser.shouldProcessNamespaces = (options & WHC_XMLParserOptionsProcessNamespaces);\n    xmlParser.shouldReportNamespacePrefixes = (options & WHC_XMLParserOptionsReportNamespacePrefixes);\n    xmlParser.shouldResolveExternalEntities = (options & WHC_XMLParserOptionsResolveExternalEntities);\n    if([xmlParser parse]){\n        [self XMLDataHandleEngine:_dictArr[0]];\n        return _dictArr[0];\n    }\n    return nil;\n}\n\n/// xml数据处理引擎 清除多余无用key\n- (void)XMLDataHandleEngine:(id)object{\n    if([object isKindOfClass:[NSDictionary class]]){\n        NSMutableDictionary * dict = object;\n        NSInteger               count = dict.count;\n        NSArray              * keyArr = [dict allKeys];\n        for (NSInteger i = 0; i < count; i++) {\n            NSString  * key = keyArr[i];\n            id   subObject = dict[key];\n            if([subObject isKindOfClass:[NSDictionary class]]){\n                [self handleTopData:dict subDict:subObject index:i];\n                [self XMLDataHandleEngine:subObject];\n            }else if([subObject isKindOfClass:[NSArray class]]){\n                [self XMLDataHandleEngine:subObject];\n            }\n        }\n    }else if ([object isKindOfClass:[NSArray class]]){\n        NSMutableArray * arrs = object;\n        for (NSInteger i = 0; i < arrs.count; i++) {\n            id subObject = arrs[i];\n            [self XMLDataHandleEngine:subObject];\n        }\n    }\n}\n\n- (void)handleTopData:(NSMutableDictionary *)dict subDict:(NSDictionary*)subDict index:(NSInteger)index{\n    NSArray  * subKeyArr = [subDict allKeys];\n    NSArray  * keyArr = [dict allKeys];\n    if(subKeyArr.count == 1 && [subKeyArr[0] isEqualToString:kWHCXMLParserTextNodeKey]){\n        [dict setObject:subDict[kWHCXMLParserTextNodeKey] forKey:keyArr[index]];\n    }else if(subKeyArr.count == 0){\n        [dict setObject:@\"\" forKey:keyArr[index]];\n    }\n}\n\n- (NSString*)getAvailableElementName:(NSString*)elementName{\n    NSString  *   handleElementName = [elementName copy];\n    if(_filterString){\n        if([handleElementName containsString:_filterString]){\n            return [handleElementName stringByReplacingOccurrencesOfString:_filterString withString:@\"\"];\n        }\n    }\n    return handleElementName;\n}\n\n- (NSDictionary*)getAvailableAttributeDict:(NSDictionary *)attributeDict{\n    NSMutableDictionary  * dict = [attributeDict mutableCopy];\n    NSArray  * keyArr = [dict allKeys];\n    for (NSString * key in keyArr) {\n        if([key containsString:kWHCCanFilterString]){\n            NSString * nKey = nil;\n            nKey = [key stringByReplacingOccurrencesOfString:kWHCCanFilterString withString:@\"_\"];\n            id value = dict[key];\n            [dict setObject:value forKey:nKey];\n            [dict removeObjectForKey:key];\n        }\n    }\n    return dict;\n}\n\n#pragma mark - NSXMLParserDelegate\n- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{\n    NSString  *   handleElementName = [self getAvailableElementName:elementName];\n    attributeDict = [self getAvailableAttributeDict:attributeDict];\n    NSMutableDictionary  * parentDict = [_dictArr lastObject];\n    NSMutableDictionary  * childDict = [NSMutableDictionary new];\n    [childDict addEntriesFromDictionary:attributeDict];\n    id existingValue = [parentDict objectForKey:handleElementName];\n    if (existingValue){\n        NSMutableArray *array = nil;\n        if ([existingValue isKindOfClass:[NSMutableArray class]]){\n            //使用存在的数组\n            array = (NSMutableArray *) existingValue;\n        }else{\n            //不存在创建数组\n            array = [NSMutableArray new];\n            [array addObject:existingValue];\n            // 替换子字典用数组\n            [parentDict setObject:array forKey:handleElementName];\n        }\n        // 添加一个新的子字典\n        [array addObject:childDict];\n    }else{\n        // 不存在插入新元素\n        [parentDict setObject:childDict forKey:handleElementName];\n    }\n    \n    // 跟新数组\n    [_dictArr addObject:childDict];\n}\n\n- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{\n    NSMutableDictionary *dictInProgress = [_dictArr lastObject];\n    void (^saveValue)() = ^(){\n        // 存储值\n        NSString *valueTxt = [_contentTxt stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];\n        if(valueTxt.length){\n            [dictInProgress setObject:[valueTxt mutableCopy] forKey:kWHCXMLParserTextNodeKey];\n        }\n    };\n    if (_contentTxt.length > 0){\n        // 检测内容是否为json\n        if(([_contentTxt hasPrefix:@\"{\"] && [_contentTxt hasSuffix:@\"}\"]) ||\n           ([_contentTxt hasPrefix:@\"[\"] && [_contentTxt hasSuffix:@\"]\"])){\n            NSError  * err = nil;\n            NSData * contentData = [_contentTxt dataUsingEncoding:NSUTF8StringEncoding];\n            id contentObject = [NSJSONSerialization JSONObjectWithData:contentData options:NSJSONReadingMutableLeaves error:&err];\n            if(err == nil){\n                [dictInProgress setObject:contentObject forKey:kWHCXMLParserTextNodeKey];\n            }else{\n                saveValue();\n            }\n        }else{\n            saveValue();\n        }\n        _contentTxt = [NSMutableString new];\n    }\n    // 移除当前\n    [_dictArr removeLastObject];\n}\n\n- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{\n    [_contentTxt appendString:string];\n    \n}\n- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{\n    if(parseError){\n        NSLog(@\"WHC_XMLParserError :%@\",parseError);\n    }\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_Xml.h",
    "content": "//\n//  WHC_Xml.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * 说明: WHC_Xml dictionary对象转换为xml字符串\n * 默认 xml 编码类型为utf-8\n */\n\n@interface WHC_Xml : NSObject\n\n/**\n * 说明: dictionary对象转换为xml字符串\n * @param: dictionary 字典对象\n * @param: encode xml编码类型\n * @param: rootAttribute xml 根属性\n */\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary\n                        encode:(NSString*)encode\n                 rootAttribute:(NSString*)rootAttribute;\n\n/**\n * 说明: dictionary对象转换为xml字符串\n * @param: dictionary 字典对象\n * @param: encode xml编码类型\n */\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary\n                        encode:(NSString*)encode;\n\n/**\n * 说明: dictionary对象转换为xml字符串\n * @param: dictionary 字典对象\n */\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary;\n\n/**\n * 说明: dictionary对象转换为xml字符串\n * @param: rootAttribute xml 根属性\n */\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary\n                 rootAttribute:(NSString*)rootAttribute;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/UtilKit+WHCNetWorkKit/WHC_Xml.m",
    "content": "//\n//  WHC_Xml.m\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/4/29.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_Xml.h\"\n\n@interface WHC_Xml (){\n    NSMutableString              * _xmlString;\n    NSString                     * _rootAttribute;\n}\n\n@end\n\n@implementation WHC_Xml\n\n- (instancetype)initWithEncode:(NSString *)encode attribute:(NSString*)attribute{\n    self = [super init];\n    if(self){\n        _rootAttribute = attribute;\n        _xmlString = [NSMutableString new];\n        [_xmlString appendFormat:@\"<?xml version=\\\"1.0\\\" encoding=\\\"%@\\\"?>\",encode];\n    }\n    return self;\n}\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary encode:(NSString*)encode rootAttribute:(NSString*)rootAttribute{\n    WHC_Xml  * whcXml = [[WHC_Xml alloc]initWithEncode:encode attribute:rootAttribute];\n    return [whcXml handleDictionaryEngine:dictionary arrKey:@\"\" root:YES];\n}\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary encode:(NSString*)encode{\n    return [WHC_Xml xmlWithDictionary:dictionary encode:encode rootAttribute:@\"\"];\n}\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary{\n    return [WHC_Xml xmlWithDictionary:dictionary encode:@\"utf-8\"];\n}\n\n+ (NSString*)xmlWithDictionary:(NSDictionary*)dictionary rootAttribute:(NSString*)rootAttribute{\n    return [WHC_Xml xmlWithDictionary:dictionary encode:@\"utf-8\" rootAttribute:rootAttribute];\n}\n\n- (NSString*)handleDictionaryEngine:(id)object arrKey:(NSString*)arrKey root:(BOOL)root{\n    if([object isKindOfClass:[NSDictionary class]]){\n        NSDictionary  * dict = object;\n        NSInteger       count = dict.count;\n        NSArray       * keyArr = [dict allKeys];\n        for (NSInteger i = 0; i < count; i++) {\n            id subObject = dict[keyArr[i]];\n            if([subObject isKindOfClass:[NSDictionary class]]){\n                if(root && _rootAttribute && _rootAttribute.length){\n                    [_xmlString appendFormat:@\"<%@ %@>\",keyArr[i],_rootAttribute];\n                }else{\n                    [_xmlString appendFormat:@\"<%@>\",keyArr[i]];\n                }\n                [self handleDictionaryEngine:subObject arrKey:@\"\" root:NO];\n                [_xmlString appendFormat:@\"</%@>\",keyArr[i]];\n            }else if ([subObject isKindOfClass:[NSArray class]]){\n                [self handleDictionaryEngine:subObject arrKey:keyArr[i] root:NO];\n            }else{\n                [_xmlString appendFormat:@\"<%@>%@</%@>\",keyArr[i],subObject,keyArr[i]];\n            }\n        }\n    }else if([object isKindOfClass:[NSArray class]]){\n        NSArray  * dictArr = object;\n        NSInteger  count = dictArr.count;\n        for (NSInteger i = 0; i < count; i++) {\n            [_xmlString appendFormat:@\"<%@>\",arrKey];\n            [self handleDictionaryEngine:dictArr[i] arrKey:arrKey root:NO];\n            [_xmlString appendFormat:@\"</%@>\",arrKey];\n        }\n    }\n    if(_rootAttribute && _rootAttribute.length){\n        \n    }\n    return _xmlString;\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit/WHCNetWorkKit.h",
    "content": "//\n//  WHCNetWorkKit.h\n//  WHCNetWorkKit\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n//! Project version number for WHCNetWorkKit.\nFOUNDATION_EXPORT double WHCNetWorkKitVersionNumber;\n\n//! Project version string for WHCNetWorkKit.\nFOUNDATION_EXPORT const unsigned char WHCNetWorkKitVersionString[];\n\n// In this header, you should import all the public headers of your framework using statements like #import <WHCNetWorkKit/PublicHeader.h>\n\n\n#import <WHCNetWorkKit/WHC_HttpManager.h>\n#import <WHCNetWorkKit/WHC_SessionDownloadManager.h>\n#import <WHCNetWorkKit/UIButton+WHC_HttpButton.h>\n#import <WHCNetWorkKit/UIImageView+WHC_HttpImageView.h>\n#import <WHCNetWorkKit/WHC_DataModel.h>\n#import <WHCNetWorkKit/WHC_Json.h>\n#import <WHCNetWorkKit/WHC_Xml.h>\n#import <WHCNetWorkKit/WHC_XMLParser.h>"
  },
  {
    "path": "WHCNetWorkKit Example/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  WHCNetWorkKit Example\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n#define WHC_BackgroundDownload (0)\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n\n@end\n\n"
  },
  {
    "path": "WHCNetWorkKit Example/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  WHCNetWorkKit Example\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n#import \"ViewController.h\"\n#import <WHCNetWorkKit/WHC_HttpManager.h>\n@interface AppDelegate ()\n\n@end\n\n@implementation AppDelegate\n\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    // Override point for customization after application launch.\n    _window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];\n    _window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[ViewController new]];\n    [_window makeKeyAndVisible];\n    return YES;\n}\n\n- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {\n}\n\n- (void)applicationWillResignActive:(UIApplication *)application {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.\n}\n\n- (void)applicationDidEnterBackground:(UIApplication *)application {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n}\n\n- (void)applicationWillEnterForeground:(UIApplication *)application {\n    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.\n}\n\n- (void)applicationDidBecomeActive:(UIApplication *)application {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n}\n\n- (void)applicationWillTerminate:(UIApplication *)application {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "WHCNetWorkKit Example/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"8150\" systemVersion=\"15A204g\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"8122\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Llm-lL-Icb\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xb3-aO-Qok\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <animations/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "WHCNetWorkKit Example/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t</dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.WHC.WHCNetWorkKit</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_FillScreenPlayerVC.h",
    "content": "//\n//  WHC_FillScreenPlayerVC.h\n//  PhoneBookBag\n//\n//  Created by 吴海超 on 15/7/8.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <UIKit/UIKit.h>\n@interface WHC_FillScreenPlayerVC : UIViewController\n\n@property (nonatomic , strong)NSURL  * playUrl;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_FillScreenPlayerVC.m",
    "content": "//\n//  WHC_FillScreenPlayerVC.m\n//  PhoneBookBag\n//\n//  Created by 吴海超 on 15/7/8.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_FillScreenPlayerVC.h\"\n#import <MediaPlayer/MediaPlayer.h>\n#import \"UIView+WHC_ViewProperty.h\"\n#import \"UIView+WHC_Loading.h\"\n#define kRotateAnimationDuring         (0.2)       //旋转动画\n@interface WHC_FillScreenPlayerVC (){\n    MPMoviePlayerController  *               _moviePlayer;      //视频播放器\n    CGRect                                   _moviePlayerRect;  //初始视频区域\n    BOOL                                     _visableStatusBar;      //状态栏是否可见\n    BOOL                                     _isRotate;         //是否旋转\n}\n\n@end\n\n@implementation WHC_FillScreenPlayerVC\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    [self initData];\n    [self layoutUI];\n    // Do any additional setup after loading the view.\n}\n\n- (void)viewWillAppear:(BOOL)animated{\n    [super viewWillAppear:animated];\n    [self.view startLoading];\n}\n\n- (void)viewDidAppear:(BOOL)animated{\n    [super viewDidAppear:animated];\n}\n\n- (void)viewDidDisappear:(BOOL)animated{\n    [super viewDidDisappear:animated];\n    [self removeMovieNotificationHandlers];\n    [self showNavigationBar];\n}\n\n- (void)layoutUI{\n    [self hideNavigationBar];\n    self.view.backgroundColor = [UIColor whiteColor];\n    _moviePlayer = [[MPMoviePlayerController alloc]init];\n    _moviePlayer.controlStyle = MPMovieControlStyleDefault;\n    _moviePlayer.movieSourceType = MPMovieScalingModeAspectFit;\n    _moviePlayer.shouldAutoplay = YES;\n    _moviePlayer.view.frame = _moviePlayerRect;\n    [self.view addSubview:_moviePlayer.view];\n    _moviePlayer.contentURL = _playUrl;\n    [_moviePlayer prepareToPlay];\n    [_moviePlayer play];\n}\n\n- (void)initData{\n    _moviePlayerRect = [UIScreen mainScreen].bounds;\n    [self installMovieNotificationObservers];\n}\n\n- (void)moviePlayerReadyForDisplay:(NSNotification *)notifiy{\n    [self.view stopLoading];\n}\n\n- (void)showNavigationBar{\n    _visableStatusBar = NO;\n    self.navigationController.navigationBarHidden = NO;\n    if([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]){\n        [self prefersStatusBarHidden];\n        [self setNeedsStatusBarAppearanceUpdate];\n    }\n}\n\n- (void)hideNavigationBar{\n    _visableStatusBar = YES;\n    self.navigationController.navigationBarHidden = YES;\n    if([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]){\n        [self prefersStatusBarHidden];\n        [self setNeedsStatusBarAppearanceUpdate];\n    }\n}\n\n- (BOOL)prefersStatusBarHidden{\n    return _visableStatusBar;\n}\n\n- (void)scanButton:(UIView *)view visable:(BOOL)visable{\n    NSArray  * subViewArr = view.subviews;\n    if(subViewArr && subViewArr.count > 0){\n        for (UIButton * btn in subViewArr) {\n            if([btn isKindOfClass:[UIButton class]]){\n                if([btn.titleLabel.text isEqualToString:@\"Done\"] ||\n                   [btn.titleLabel.text isEqualToString:@\"完成\"]){\n                    [btn addTarget:self action:@selector(clickDone:) forControlEvents:UIControlEventTouchUpInside];\n                }else if(btn.x < 160 + 5 && btn.x > 160 - 5){\n                    btn.hidden = NO;\n                }else{\n                    btn.hidden = !visable;\n                }\n            }else{\n                [self scanButton:btn visable:visable];\n            }\n        }\n    }\n}\n\n- (void)clickDone:(UIButton *)sender{\n    _moviePlayer.view.xy = _moviePlayerRect.origin;\n    _moviePlayer.controlStyle = MPMovieControlStyleDefault;\n    [self scanButton:_moviePlayer.view visable:NO];\n    __weak  typeof(self) sf = self;\n    [UIView animateWithDuration:kRotateAnimationDuring delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{\n        _moviePlayer.view.size = CGSizeMake(CGRectGetHeight(_moviePlayerRect), CGRectGetWidth(_moviePlayerRect));\n        _moviePlayer.view.center = CGPointMake(CGRectGetMidX(_moviePlayerRect), CGRectGetMidY(_moviePlayerRect));\n        _moviePlayer.view.transform = CGAffineTransformMakeRotation(0);\n        _moviePlayer.view.size = _moviePlayerRect.size;\n    } completion:^(BOOL finished) {\n        [_moviePlayer stop];\n        [self showNavigationBar];\n        [sf.navigationController popViewControllerAnimated:NO];\n    }];\n}\n\n- (void)enterFullScreenMode{\n    _moviePlayer.controlStyle = MPMovieControlStyleFullscreen;\n    _moviePlayer.view.xy = CGPointZero;\n    [self scanButton:_moviePlayer.view visable:NO];\n    [self.view bringSubviewToFront:_moviePlayer.view];\n    [UIView animateWithDuration:kRotateAnimationDuring delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{\n        _moviePlayer.view.size = CGSizeMake(self.view.height, self.view.width);\n        _moviePlayer.view.center = CGPointMake(self.view.width / 2.0, self.view.height / 2.0);\n        _moviePlayer.view.transform = CGAffineTransformMakeRotation(M_PI_2);\n    } completion:^(BOOL finished) {\n        \n    }];\n}\n\n\n- (void)didReceiveMemoryWarning {\n    [super didReceiveMemoryWarning];\n    // Dispose of any resources that can be recreated.\n}\n\n\n\n\n#pragma mark Movie Notification Handlers\n\n/*  Notification called when the movie finished playing. */\n- (void) moviePlayBackDidFinish:(NSNotification*)notification\n{\n    NSNumber *reason = [notification userInfo][MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];\n    switch ([reason integerValue])\n    {\n            /* The end of the movie was reached. */\n        case MPMovieFinishReasonPlaybackEnded:\n            /*\n             Add your code here to handle MPMovieFinishReasonPlaybackEnded.\n             */\n            break;\n            \n            /* An error was encountered during playback. */\n        case MPMovieFinishReasonPlaybackError:\n            NSLog(@\"An error was encountered during playback\");\n            [self clickDone:nil];\n            break;\n            \n            /* The user stopped playback. */\n        case MPMovieFinishReasonUserExited:\n            NSLog(@\"An error was encountered during MPMovieFinishReasonUserExited\");\n            break;\n            \n        default:\n            break;\n    }\n}\n\n/* Handle movie load state changes. */\n- (void)loadStateDidChange:(NSNotification *)notification\n{\n    MPMoviePlayerController *player = notification.object;\n    MPMovieLoadState loadState = player.loadState;\n    if (loadState & MPMovieLoadStateUnknown)\n    {\n//        [self clickDone:nil];\n    }\n}\n\n/* Called when the movie playback state has changed. */\n- (void) moviePlayBackStateDidChange:(NSNotification*)notification\n{\n    MPMoviePlayerController *player = notification.object;\n    \n    if (player.playbackState == MPMoviePlaybackStateInterrupted)\n    {\n        [self clickDone:nil];\n    }\n}\n\n/* Notifies observers of a change in the prepared-to-play state of an object\n conforming to the MPMediaPlayback protocol. */\n- (void) mediaIsPreparedToPlayDidChange:(NSNotification*)notification\n{\n    // Add an overlay view on top of the movie view\n    [self.view stopLoading];\n    if(!_isRotate){\n        _isRotate = YES;\n        [self scanButton:_moviePlayer.view visable:NO];\n        [self enterFullScreenMode];\n    }\n    \n}\n\n#pragma mark Install Movie Notifications\n\n/* Register observers for the various movie object notifications. */\n-(void)installMovieNotificationObservers\n{\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(loadStateDidChange:)\n                                                 name:MPMoviePlayerLoadStateDidChangeNotification\n                                               object:_moviePlayer];\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(moviePlayBackDidFinish:)\n                                                 name:MPMoviePlayerPlaybackDidFinishNotification\n                                               object:_moviePlayer];\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(mediaIsPreparedToPlayDidChange:)\n                                                 name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification\n                                               object:_moviePlayer];\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(moviePlayBackStateDidChange:)\n                                                 name:MPMoviePlayerPlaybackStateDidChangeNotification \n                                               object:_moviePlayer];\n}\n\n-(void)removeMovieNotificationHandlers\n{\n    \n    [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:_moviePlayer];\n    [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:_moviePlayer];\n    [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:_moviePlayer];\n    [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:_moviePlayer];\n}\n/*\n#pragma mark - Navigation\n\n// In a storyboard-based application, you will often want to do a little preparation before navigation\n- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {\n    // Get the new view controller using [segue destinationViewController].\n    // Pass the selected object to the new view controller.\n}\n*/\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_OffLineVideoCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"8191\" systemVersion=\"14F27\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"8154\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <tableViewCell contentMode=\"scaleToFill\" selectionStyle=\"default\" indentationWidth=\"10\" reuseIdentifier=\"WHC_OffLineVideoCell\" rowHeight=\"57\" id=\"HGt-U2-yRc\" customClass=\"WHC_OffLineVideoCell\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"57\"/>\n            <autoresizingMask key=\"autoresizingMask\"/>\n            <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"HGt-U2-yRc\" id=\"QGF-AQ-J80\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"56\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"文件名\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"pB1-Pt-OOF\">\n                        <rect key=\"frame\" x=\"15\" y=\"7\" width=\"264\" height=\"16\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                        <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"文件名\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"6lE-Rh-ucD\">\n                        <rect key=\"frame\" x=\"15\" y=\"37\" width=\"129\" height=\"16\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"12\"/>\n                        <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                    <progressView opaque=\"NO\" contentMode=\"scaleToFill\" verticalHuggingPriority=\"750\" id=\"WTV-7O-Sdb\">\n                        <rect key=\"frame\" x=\"17\" y=\"30\" width=\"262\" height=\"2\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMaxY=\"YES\"/>\n                    </progressView>\n                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"0KB/S\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"vdc-ei-N05\">\n                        <rect key=\"frame\" x=\"180\" y=\"37\" width=\"97\" height=\"16\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMinX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"12\"/>\n                        <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                    <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" lineBreakMode=\"middleTruncation\" id=\"bIY-Z9-ZW0\">\n                        <rect key=\"frame\" x=\"285\" y=\"16\" width=\"35\" height=\"25\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMinX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <state key=\"normal\" title=\"🕗\">\n                            <color key=\"titleColor\" red=\"1\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                            <color key=\"titleShadowColor\" white=\"0.5\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                        </state>\n                        <connections>\n                            <action selector=\"clickDownload:\" destination=\"HGt-U2-yRc\" eventType=\"touchUpInside\" id=\"lQt-Of-bLF\"/>\n                        </connections>\n                    </button>\n                </subviews>\n            </tableViewCellContentView>\n            <connections>\n                <outlet property=\"downloadButton\" destination=\"bIY-Z9-ZW0\" id=\"zsS-vk-gPH\"/>\n                <outlet property=\"downloadValueLabel\" destination=\"6lE-Rh-ucD\" id=\"pBF-HO-agM\"/>\n                <outlet property=\"progressBar\" destination=\"WTV-7O-Sdb\" id=\"3UY-CJ-x5H\"/>\n                <outlet property=\"speedLabel\" destination=\"vdc-ei-N05\" id=\"fMZ-kb-YbT\"/>\n                <outlet property=\"titleLabel\" destination=\"pB1-Pt-OOF\" id=\"lyq-La-8uF\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"-77\" y=\"385.5\"/>\n        </tableViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_OffLineVideoVC.h",
    "content": "//\n//  WHC_OffLineVideoVC.h\n//  DingLibrary\n//\n//  Created by 吴海超 on 15/7/9.\n//  Copyright (c) 2015年 Rudy. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <UIKit/UIKit.h>\n#import \"WHC_DownloadObject.h\"\n\n@protocol WHC_OffLineVideoCellDelegate <NSObject>\n\n- (void)videoDownload:(NSError *)error index:(NSInteger)index strUrl:(NSString *)strUrl;\n- (void)updateDownloadValue:(WHC_DownloadObject *)downloadObject index:(NSInteger)index;\n- (void)videoPlayerIndex:(NSInteger)index;\n\n@end\n\n@interface WHC_OffLineVideoCell : UITableViewCell\n@property (nonatomic , weak)id<WHC_OffLineVideoCellDelegate> delegate;\n@property (nonatomic , assign)NSInteger index;\n@end\n\n@interface WHC_OffLineVideoVC : UIViewController\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_OffLineVideoVC.m",
    "content": "//\n//  WHC_OffLineVideoVC.m\n//  DingLibrary\n//\n//  Created by 吴海超 on 15/7/9.\n//  Copyright (c) 2015年 Rudy. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"WHC_OffLineVideoVC.h\"\n#import <MediaPlayer/MediaPlayer.h>\n#import <MediaPlayer/MPMoviePlayerViewController.h>\n#import <MediaPlayer/MPMusicPlayerController.h>\n#import \"WHC_FillScreenPlayerVC.h\"\n#import \"UIView+WHC_Loading.h\"\n#import \"UIView+WHC_ViewProperty.h\"\n#import \"UIView+WHC_Toast.h\"\n#import \"AppDelegate.h\"\n\n@import WHCNetWorkKit;\n\n#define kFontSize             (15.0)\n#define kCellHeight           (57.0)                   //cell高度\n#define kMinPlaySize          (10.0)                   //最小播放尺寸\n#define kCellName             (@\"WHC_OffLineVideoCell\")//cell名称\n\n@interface WHC_OffLineVideoCell ()<WHC_DownloadDelegate>{\n    UIButton                    * _downloadArrowButton;\n    WHC_DownloadObject          * _downloadObject;\n    BOOL                          _hasDownloadAnimation;\n}\n@property (nonatomic , strong)IBOutlet UILabel          * titleLabel;\n@property (nonatomic , strong)IBOutlet UILabel          * downloadValueLabel;\n@property (nonatomic , strong)IBOutlet UILabel          * speedLabel;\n@property (nonatomic , strong)IBOutlet UIProgressView   * progressBar;\n@property (nonatomic , strong)IBOutlet UIButton         * downloadButton;\n@end\n\n@implementation WHC_OffLineVideoCell\n\n- (void)awakeFromNib{\n    [super awakeFromNib];\n    _downloadButton.clipsToBounds = true;\n    [_downloadButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];\n}\n\n- (void)addDownloadAnimation {\n    if(_downloadArrowButton){\n        [UIView animateWithDuration:1.2 animations:^{\n            _downloadArrowButton.y = _downloadArrowButton.height;\n        }completion:^(BOOL finished) {\n            _downloadArrowButton.y = -_downloadArrowButton.height;\n            [self addDownloadAnimation];\n        }];\n    }\n}\n\n- (void)startDownloadAnimation {\n    if (_downloadArrowButton == nil) {\n        _downloadArrowButton = [UIButton buttonWithType:UIButtonTypeCustom];\n        _downloadArrowButton.enabled = false;\n        _downloadArrowButton.frame = _downloadButton.bounds;\n        [_downloadArrowButton setTitle:@\"↓\" forState:UIControlStateNormal];\n        [_downloadArrowButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];\n        _downloadArrowButton.titleLabel.font = [UIFont boldSystemFontOfSize:20];\n    }\n    if (!_hasDownloadAnimation) {\n        _hasDownloadAnimation = true;\n        _downloadArrowButton.y = -_downloadArrowButton.height;\n        [_downloadButton addSubview:_downloadArrowButton];\n        [self addDownloadAnimation];\n    }\n}\n\n- (void)removeDownloadAnimtion {\n    _hasDownloadAnimation = false;\n    if (_downloadArrowButton != nil) {\n        [_downloadArrowButton removeFromSuperview];\n        _downloadArrowButton = nil;\n    }\n}\n\n- (void)updateDownloadValue {\n    _titleLabel.text = _downloadObject.fileName;\n    _progressBar.progress = _downloadObject.downloadProcessValue;\n    _downloadValueLabel.text = _downloadObject.downloadProcessText;\n    NSString * strSpeed = _downloadObject.downloadSpeed;\n    if (_downloadObject.downloadState != WHCDownloading) {\n        [self removeDownloadAnimtion];\n    }else {\n        [self startDownloadAnimation];\n    }\n    switch (_downloadObject.downloadState) {\n        case WHCDownloadWaitting:\n            [_downloadButton setTitle:@\"🕘\" forState:UIControlStateNormal];\n            strSpeed = @\"等待\";\n            break;\n        case WHCDownloading:\n            [_downloadButton setTitle:@\"\" forState:UIControlStateNormal];\n            break;\n        case WHCDownloadCanceled:\n            [_downloadButton setTitle:@\"■\" forState:UIControlStateNormal];\n            strSpeed = @\"暂停\";\n            break;\n        case WHCDownloadCompleted:\n            [_downloadButton setTitle:@\"▶\" forState:UIControlStateNormal];\n            strSpeed = @\"完成\";\n        case WHCNone:\n            break;\n    }\n    _speedLabel.text = strSpeed;\n}\n\n\n- (IBAction)clickDownload:(UIButton *)sender {\n    switch (_downloadObject.downloadState) {\n        case WHCDownloading:\n            _downloadObject.downloadState = WHCDownloadCanceled;\n    #if WHC_BackgroundDownload\n            [[WHC_SessionDownloadManager shared] cancelDownloadWithFileName:_downloadObject.fileName deleteFile:NO];\n    #else\n            [[WHC_HttpManager shared] cancelDownloadWithFileName:_downloadObject.fileName deleteFile:NO];\n    #endif\n            break;\n        case WHCDownloadCanceled:{\n            _downloadObject.downloadState = WHCDownloadWaitting;\n    #if WHC_BackgroundDownload\n            [[WHC_SessionDownloadManager shared] setBundleIdentifier:@\"com.WHC.WHCNetWorkKit.backgroundsession\"];\n            WHC_DownloadSessionTask * downloadTask = [[WHC_SessionDownloadManager shared] download:_downloadObject.downloadPath\n                                                 savePath:[WHC_DownloadObject videoDirectory]\n                                             saveFileName:_downloadObject.fileName delegate:self];\n            downloadTask.index = self.index;\n            \n    #else\n            WHC_DownloadOperation * operation = [[WHC_HttpManager shared] download:_downloadObject.downloadPath\n                                      savePath:[WHC_DownloadObject videoDirectory]\n                                  saveFileName:_downloadObject.fileName delegate:self];\n            operation.index = self.index;\n    #endif\n            [self updateDownloadValue];\n        }\n            break;\n        case WHCDownloadWaitting:\n            break;\n        case WHCDownloadCompleted:\n            if (_delegate && [_delegate respondsToSelector:@selector(videoPlayerIndex:)]) {\n                [_delegate videoPlayerIndex:_index];\n            }\n            break;\n        default:\n            break;\n    }\n}\n\n- (void)displayCell:(WHC_DownloadObject *)object index:(NSInteger)index {\n    self.index = index;\n    _downloadObject = object;\n    if (_downloadObject.downloadState == WHCNone ||\n        _downloadObject.downloadState == WHCDownloading ) {\n        _downloadObject.downloadState = WHCDownloadWaitting;\n    }\n#if WHC_BackgroundDownload\n    [[WHC_SessionDownloadManager shared] setBundleIdentifier:@\"com.WHC.WHCNetWorkKit.backgroundsession\"];\n    WHC_DownloadSessionTask * downloadTask = [[WHC_SessionDownloadManager shared] replaceCurrentDownloadOperationDelegate:self fileName:_downloadObject.fileName];\n    if ([[WHC_SessionDownloadManager shared] existDownloadOperationTaskWithFileName:_downloadObject.fileName]) {\n        if (_downloadObject.downloadState == WHCDownloadCanceled) {\n            _downloadObject.downloadState = WHCDownloadWaitting;\n        }\n    }\n    downloadTask.index = index;\n#else\n    WHC_DownloadOperation * operation = [[WHC_HttpManager shared] replaceCurrentDownloadOperationDelegate:self fileName:_downloadObject.fileName];\n    if ([[WHC_HttpManager shared] existDownloadOperationTaskWithFileName:_downloadObject.fileName]) {\n        if (_downloadObject.downloadState == WHCDownloadCanceled) {\n            _downloadObject.downloadState = WHCDownloadWaitting;\n        }\n    }\n    operation.index = index;\n#endif\n    [self updateDownloadValue];\n    [self removeDownloadAnimtion];\n}\n\n- (void)saveDownloadState:(WHC_DownloadOperation *)operation {\n    _downloadObject.currentDownloadLenght = operation.recvDataLenght;\n    _downloadObject.totalLenght = operation.fileTotalLenght;\n    [_downloadObject writeDiskCache];\n}\n\n//WHC_DownloadSessionTask : WHC_DownloadOperation\n\n#pragma mark - WHC_DownloadDelegate -\n- (void)WHCDownloadResponse:(nonnull WHC_DownloadOperation *)operation\n                      error:(nullable NSError *)error\n                         ok:(BOOL)isOK {\n    if (isOK) {\n        if (self.index == operation.index) {\n            _downloadObject.downloadState = WHCDownloading;\n            _downloadObject.currentDownloadLenght = operation.recvDataLenght;\n            _downloadObject.totalLenght = operation.fileTotalLenght;\n            [self updateDownloadValue];\n        }else {\n            WHC_DownloadObject * tempDownloadObject = [WHC_DownloadObject readDiskCache:operation.strUrl];\n            if (tempDownloadObject != nil) {\n                tempDownloadObject.downloadState = WHCDownloading;\n                tempDownloadObject.currentDownloadLenght = operation.recvDataLenght;\n                tempDownloadObject.totalLenght = operation.fileTotalLenght;\n                [tempDownloadObject writeDiskCache];\n                if (_delegate && [_delegate respondsToSelector:@selector(updateDownloadValue: index:)]) {\n                    [_delegate updateDownloadValue:tempDownloadObject index:operation.index];\n                }\n            }\n        }\n    }else {\n        _downloadObject.downloadState = WHCNone;\n        if (_delegate &&\n            [_delegate respondsToSelector:@selector(videoDownload:index:strUrl:)]) {\n            [_delegate videoDownload:error index:_index strUrl:operation.strUrl];\n        }\n    }\n}\n\n- (void)WHCDownloadProgress:(nonnull WHC_DownloadOperation *)operation\n                       recv:(uint64_t)recvLength\n                      total:(uint64_t)totalLength\n                      speed:(nullable NSString *)speed {\n    if (operation.index == self.index) {\n        if (_downloadObject.totalLenght < 10) {\n            _downloadObject.totalLenght = totalLength;\n        }\n        _downloadObject.currentDownloadLenght = recvLength;\n        _downloadObject.downloadSpeed = speed;\n        _downloadObject.downloadState = WHCDownloading;\n        [self updateDownloadValue];\n        [self startDownloadAnimation];\n    }\n}\n\n- (void)WHCDownloadDidFinished:(nonnull WHC_DownloadOperation *)operation\n                          data:(nullable NSData *)data\n                         error:(nullable NSError *)error\n                       success:(BOOL)isSuccess {\n    if (isSuccess) {\n        if (self.index == operation.index) {\n            _downloadObject.downloadState = WHCDownloadCompleted;\n            [self saveDownloadState:operation];\n        }else {\n            WHC_DownloadObject * tempDownloadObject = [WHC_DownloadObject readDiskCache:operation.strUrl];\n            if (tempDownloadObject != nil) {\n                tempDownloadObject.downloadState = WHCDownloadCompleted;\n                tempDownloadObject.currentDownloadLenght = operation.recvDataLenght;\n                tempDownloadObject.totalLenght = operation.fileTotalLenght;\n                [tempDownloadObject writeDiskCache];\n                if (_delegate && [_delegate respondsToSelector:@selector(updateDownloadValue:index:)]) {\n                    [_delegate updateDownloadValue:tempDownloadObject index:operation.index];\n                }\n            }\n        }\n    }else {\n        \n        WHC_DownloadObject * tempDownloadObject;\n        if (self.index == operation.index) {\n            _downloadObject.downloadState = WHCDownloadCanceled;\n        }else {\n            tempDownloadObject = [WHC_DownloadObject readDiskCache:operation.strUrl];\n            if (tempDownloadObject != nil) {\n                tempDownloadObject.downloadState = WHCDownloadCanceled;\n            }\n        }\n        if (error != nil &&\n            error.code == WHCCancelDownloadError &&\n            !operation.isDeleted) {\n                if (self.index == operation.index) {\n                    [self saveDownloadState:operation];\n                }else {\n                    if (tempDownloadObject != nil) {\n                        tempDownloadObject.currentDownloadLenght = operation.recvDataLenght;\n                        tempDownloadObject.totalLenght = operation.fileTotalLenght;\n                        [tempDownloadObject writeDiskCache];\n                    }\n                    \n                }\n                [self saveDownloadState:operation];\n            }else {\n                [[[UIAlertView alloc] initWithTitle:@\"下载失败\" message:nil delegate:nil cancelButtonTitle:@\"OK\" otherButtonTitles:nil, nil] show];\n            }\n        if (tempDownloadObject != nil) {\n            if (_delegate && [_delegate respondsToSelector:@selector(updateDownloadValue:index:)]) {\n                [_delegate updateDownloadValue:tempDownloadObject index:operation.index];\n            }\n        }\n    }\n    if (self.index == operation.index) {\n        [self updateDownloadValue];\n    }\n}\n\n\n@end\n\n#pragma mark - 控制器部分\n\n@interface WHC_OffLineVideoVC () <WHC_OffLineVideoCellDelegate>{\n    NSMutableArray              *     _downloadObjectArr;\n    MPMoviePlayerViewController *     playerViewController;\n    NSString                    *     _plistPath;\n}\n@property (nonatomic , strong)IBOutlet  UITableView  * offLineTableView;\n@end\n\n@implementation WHC_OffLineVideoVC\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    self.navigationItem.title = @\"离线视频中心\";\n    [self initData];\n    [self layoutUI];\n    // Do any additional setup after loading the view from its nib.\n}\n\n- (void)didReceiveMemoryWarning {\n    [super didReceiveMemoryWarning];\n    // Dispose of any resources that can be recreated.\n}\n\n- (void)viewDidAppear:(BOOL)animated{\n    [super viewDidAppear:animated];\n    [_offLineTableView reloadData];\n}\n\n- (void)viewWillDisappear:(BOOL)animated{\n    [super viewWillDisappear:animated];\n    [_offLineTableView reloadData];\n}\n\n- (void)viewDidDisappear:(BOOL)animated{\n    [super viewDidDisappear:animated];\n}\n\n- (void)layoutUI{\n    [_offLineTableView registerNib:[UINib nibWithNibName:kCellName bundle:[NSBundle mainBundle]] forCellReuseIdentifier:kCellName];\n}\n\n- (void)initData{\n    _downloadObjectArr = [NSMutableArray arrayWithArray:[WHC_DownloadObject readDiskAllCache]];\n    [_offLineTableView reloadData];\n}\n\n#pragma mark - WHC_OffLineVideoCellDelegate\n- (void)videoDownload:(NSError *)error index:(NSInteger)index strUrl:(NSString *)strUrl {\n    if (error != nil) {\n        [self.view toast:error.userInfo[NSLocalizedDescriptionKey]];\n    }\n    WHC_DownloadObject * downloadObject = _downloadObjectArr[index];\n    [downloadObject removeFromDisk];\n    [_downloadObjectArr removeObjectAtIndex:index];\n    [_offLineTableView reloadData];\n}\n\n- (void)updateDownloadValue:(WHC_DownloadObject *)downloadObject index:(NSInteger)index {\n    if (downloadObject != nil) {\n        WHC_DownloadObject * tempDownloadObject = _downloadObjectArr[index];\n        tempDownloadObject.currentDownloadLenght = downloadObject.currentDownloadLenght;\n        tempDownloadObject.totalLenght = downloadObject.totalLenght;\n        tempDownloadObject.downloadSpeed = downloadObject.downloadSpeed;\n        tempDownloadObject.downloadState = downloadObject.downloadState;\n    }\n}\n\n- (void)videoPlayerIndex:(NSInteger)index {\n    \n}\n\n-(void) playMp4:(NSString*)url{\n    WHC_FillScreenPlayerVC  * vc = [WHC_FillScreenPlayerVC new];\n    vc.playUrl = [NSURL fileURLWithPath:url];\n    [self.navigationController pushViewController:vc animated:NO];\n}\n\n- (void)movieFinishedCallback:(NSNotification *)notifiy{\n    [self.navigationController setNavigationBarHidden:NO animated:YES];\n    MPMoviePlayerController *player = [notifiy object];\n    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:player];\n    [player stop];\n    [playerViewController.navigationController  popViewControllerAnimated:YES];\n}\n\n#pragma mark - UITableViewDelegate UITableViewDataSource\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{\n    return kCellHeight;\n}\n\n- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{\n    return [UIView new];\n}\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{\n    return _downloadObjectArr.count;\n}\n\n- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{\n    return @\"删除\";\n}\n\n- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{\n    return YES;\n}\n\n-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{\n    NSInteger row = indexPath.row;\n    WHC_DownloadObject * downloadObject = _downloadObjectArr[row];\n#if WHC_BackgroundDownload\n    [[WHC_SessionDownloadManager shared] cancelDownloadWithFileName:downloadObject.fileName deleteFile:YES];\n#else\n    [[WHC_HttpManager shared] cancelDownloadWithFileName:downloadObject.fileName deleteFile:YES];\n#endif\n    [downloadObject removeFromDisk];\n    [_downloadObjectArr removeObjectAtIndex:row];\n    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{\n    WHC_OffLineVideoCell  * cell = [tableView dequeueReusableCellWithIdentifier:kCellName];\n    NSInteger row = indexPath.row;\n    cell.delegate = self;\n    [cell displayCell:_downloadObjectArr[row] index:row];\n    return cell;\n}\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{\n    [tableView deselectRowAtIndexPath:indexPath animated:NO];\n//    DownloadObject * object = _videoObjectArr[indexPath.row];\n//    WHC_Download * download = [WHCDownloadCenter downloadWithFileName:object.fileName];\n//    if(download){\n//        if(((CGFloat)download.totalLen) / kWHC_1MB >= kMinPlaySize){\n//            if(((CGFloat)download.downloadLen) / kWHC_1MB >= kMinPlaySize){//允许播放\n//                WHC_FillScreenPlayerVC * vc = [WHC_FillScreenPlayerVC new];\n//                vc.playUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@\"%@%@\",Account.videoFolder,download.saveFileName]];\n//                vc.hidesBottomBarWhenPushed = YES;\n//                [self.navigationController pushViewController:vc animated:YES];\n//            }\n//        }else{\n//            [self.view toast:@\"该文件尺寸大小无法播放\"];\n//        }\n//    }else{\n//        NSFileManager  * fm = [NSFileManager defaultManager];\n//        uint64_t actualFileLen = [[fm attributesOfItemAtPath:[NSString stringWithFormat:@\"%@%@\",Account.videoFolder,object.fileName] error:nil] fileSize];\n//        NSMutableDictionary * downloadRecordDict = [NSMutableDictionary dictionaryWithContentsOfFile:_plistPath];\n//        NSDictionary * tempDict = downloadRecordDict[object.fileName];\n//        DownloadState state = NoneState;\n//        if(tempDict){\n//            state = [tempDict[@\"state\"] integerValue];\n//        }\n//        if(((CGFloat)actualFileLen) / kWHC_1MB >= kMinPlaySize || state == DownloadCompleted){\n//            WHC_FillScreenPlayerVC * vc = [WHC_FillScreenPlayerVC new];\n//            NSString * playPath = [NSString stringWithFormat:@\"%@%@\",Account.videoFolder,object.fileName];\n//            vc.playUrl = [NSURL fileURLWithPath:playPath];\n//            vc.hidesBottomBarWhenPushed = YES;\n//            [self.navigationController pushViewController:vc animated:YES];\n//        }else{\n//            [self.view toast:@\"该文件尺寸大小无法播放请下载在播放\"];\n//        }\n//    }\n    \n}\n\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UI/WHC_OffLineVideoVC.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"7706\" systemVersion=\"14C109\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"7703\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"WHC_OffLineVideoVC\">\n            <connections>\n                <outlet property=\"offLineTableView\" destination=\"O6n-n8-fWK\" id=\"ccd-nJ-zoz\"/>\n                <outlet property=\"view\" destination=\"i5M-Pr-FkT\" id=\"sfx-zR-JGt\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view clearsContextBeforeDrawing=\"NO\" contentMode=\"scaleToFill\" id=\"i5M-Pr-FkT\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <tableView clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"44\" sectionHeaderHeight=\"1\" sectionFooterHeight=\"1\" id=\"O6n-n8-fWK\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                    <connections>\n                        <outlet property=\"dataSource\" destination=\"-1\" id=\"0h9-Jp-KEY\"/>\n                        <outlet property=\"delegate\" destination=\"-1\" id=\"ukM-qM-4cK\"/>\n                    </connections>\n                </tableView>\n            </subviews>\n            <color key=\"backgroundColor\" red=\"0.94901960780000005\" green=\"0.96078431369999995\" blue=\"0.93333333330000001\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n            <simulatedScreenMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"522\" y=\"378\"/>\n        </view>\n    </objects>\n    <simulatedMetricsContainer key=\"defaultSimulatedMetrics\">\n        <simulatedStatusBarMetrics key=\"statusBar\"/>\n        <simulatedOrientationMetrics key=\"orientation\"/>\n        <simulatedScreenMetrics key=\"destination\" type=\"retina4\"/>\n    </simulatedMetricsContainer>\n</document>\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIScrollView+WHC_PullRefresh.h",
    "content": "//\n//  UIScrollView+WHC_PullRefresh.h\n//  PhoneBookBag\n//\n//  Created by 吴海超 on 14/8/20.\n//  Copyright (c) 2014年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOS大神qq群:460122071\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <UIKit/UIKit.h>\n\ntypedef enum {\n    HeaderStyle,\n    FooterStyle,\n    AllStyle,\n    NoneStyle,\n}WHCPullRefreshStyle;\n\n\n@protocol  WHC_PullRefreshDelegate<NSObject>\n\n@optional\n\n//上拉刷新回调\n- (void)WHCUpPullRequest;\n\n//下拉刷新回调\n- (void)WHCDownPullRequest;\n\n@end\n\n\n@interface UIScrollView (WHC_PullRefresh)\n- (void)setWHCRefreshStyle:(WHCPullRefreshStyle)refreshStyle  delegate:(id<WHC_PullRefreshDelegate>)delegate;\n\n- (void)WHCDidCompletedWithRefreshIsDownPull:(BOOL)isDown;\n- (void)cancelledObsever;\n- (void)addObserver;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIScrollView+WHC_PullRefresh.m",
    "content": "//\n//  UIScrollView+WHC_PullRefresh.m\n//  PhoneBookBag\n//\n//  Created by 吴海超 on 14/8/20.\n//  Copyright (c) 2014年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOS大神qq群:460122071\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"UIScrollView+WHC_PullRefresh.h\"\n#import \"UIView+WHC_ViewProperty.h\"\n#import <objc/runtime.h>\n\n#define kWHC_Margin              (5.0)                //上下边距\n#define kWHC_WaterDropSize       (30.0)               //水滴尺寸\n#define kWHC_PullHeight          (80.0)               //下拉高度\n#define kWHC_BreakRadius         (5.0)                //断开半径\n#define kWHC_OffsetAnimationTime (0.2)                //偏移动画时间\n#define kWHC_FontSize            (14.0)               //字体大小\n#define kWHC_ContentOffset       (@\"contentOffset\")   //监听路径\n#define kWHC_ContentInset        (@\"contentInset\")\n#define kWHC_ContentSize         (@\"contentSize\")\n#define kWHC_RefreshFinishTxt    (@\"刷新完成\")\n#define kWHC_LoadMoreTxt         (@\"加载更多\")\n#define kWHC_LoadingTxt          (@\"正在加载\")\n#define kWHC_RefreshingHeight    (kWHC_WaterDropSize + 2.0 * kWHC_Margin)    //刷新视图的高度\n\n//加载器渐变开始颜色\n#define KWHC_StartColor      ([UIColor colorWithRed:255.0 / 255.0\\\n                                              green:255.0 / 255.0\\\n                                               blue:255.0 / 255.0\\\n                                               alpha:1.0].CGColor)\n//加载器渐变结束颜色\n#define KWHC_EndColor        ([UIColor colorWithRed:38.0  / 255.0\\\n                                              green:110.0 / 255.0\\\n                                              blue:239.0  / 255.0\\\n                                              alpha:1.0].CGColor)\n//水滴颜色\n#define kWHC_WaterBackColor  (([UIColor colorWithRed:38.0  / 255.0\\\n                                                green:110.0 / 255.0\\\n                                                blue:239.0  / 255.0\\\n                                                alpha:1.0].CGColor))\n\n//刷新头部提示文字颜色\n#define kWHC_HeaderLableTxtColor  ([UIColor blackColor])\n\n//刷新头部百分比标签文字颜色\n#define kWHC_HeaderPercentLabTxtColor ([UIColor whiteColor])\n\n//刷新底部提示文字颜色\n#define kWHC_FooterLableTxtColor  ([UIColor blackColor])\n\n//刷新底部百分比标签文字颜色\n#define kWHC_FooterPercentLabTxtColor ([UIColor grayColor])\ntypedef enum{\n    NoneRefresh = 3,        //没有刷新\n    WillRefresh,            //将要刷新\n    DoingRefresh,           //正在刷新\n    DidRefreshed            //完成刷新\n}WHCRefreshStatus;\n\n#pragma mark - 上拉刷新视图 -\n\n@interface WHC_PullFooterView : UIView\n@property (nonatomic , assign)BOOL                    canRequest;                 //是否能够请求\n@property (nonatomic , assign)BOOL                    isSetOffset;                //是否已经设置了偏移\n@property (nonatomic , assign)WHCRefreshStatus        currentRefreshState;        //当前刷新状态\n@property (nonatomic , assign)UIEdgeInsets            superOriginalContentInset;  //super原始偏移值\n- (void)setProgressValue:(CGFloat)progressValue;\n- (void)updatePostion;\n@end\n\n@interface WHC_PullFooterView (){\n    UIView             *           _backView;                    //背景视图\n    UILabel            *           _loadLab;                     //加载标签\n    UILabel            *           _percentLab;                  //百分比标签\n    UIImageView        *           _progressBarImageView;        //进度条\n    CAGradientLayer    *           _gradientProgressBar;         //渐变进度条层\n    CAShapeLayer       *           _progressBar;                 //进度条层\n    id                             _delegate;                    //刷新代理\n    UIScrollView       *           _superView;                   //父视图\n    \n    BOOL                           _isDidSendRequest;            //是否已经发生请求\n}\n@end\n\n@implementation WHC_PullFooterView\n\n- (instancetype)initWithFrame:(CGRect)frame  delegate:(id<WHC_PullRefreshDelegate>)delegate{\n    self = [super initWithFrame:frame];\n    if(self){\n        _delegate = delegate;\n        [self initData];\n    }\n    return self;\n}\n\n- (void)setDelegate:(id<WHC_PullRefreshDelegate>)delegate{\n    _delegate = delegate;\n}\n\n- (void)willMoveToSuperview:(UIView *)newSuperview{\n    [super willMoveToSuperview:newSuperview];\n    [_superView cancelledObsever];\n    if(newSuperview){\n        [_superView addObserver];\n    }\n}\n\n+ (CGFloat)stringWidth:(NSString *)content constrainedHeight:(CGFloat)height fontSize:(CGFloat)fontSize{\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored\"-Wdeprecated-declarations\"\n    CGSize contentSize = [content sizeWithFont:[UIFont systemFontOfSize:fontSize] constrainedToSize:CGSizeMake(MAXFLOAT , height)];\n#pragma clang diagnostic pop\n    return contentSize.width;\n}\n\n- (void)initData{\n    _canRequest = YES;\n    _currentRefreshState = NoneRefresh;\n    CGFloat   loadingLabWidth = [WHC_PullFooterView stringWidth:kWHC_LoadMoreTxt constrainedHeight:self.height fontSize:17.0];\n    CGFloat   sumWidth = loadingLabWidth + kWHC_WaterDropSize +kWHC_Margin;\n    _backView = [[UIView alloc]initWithFrame:CGRectMake((self.width - sumWidth) / 2.0, kWHC_Margin, kWHC_WaterDropSize, kWHC_WaterDropSize)];\n    _loadLab = [[UILabel alloc]initWithFrame:CGRectMake(_backView.maxX + kWHC_Margin, 0, loadingLabWidth, self.height)];\n    _loadLab.text = kWHC_LoadMoreTxt;\n    _loadLab.textColor = kWHC_FooterLableTxtColor;\n    _loadLab.font = [UIFont systemFontOfSize:kWHC_FontSize];\n    [self addSubview:_loadLab];\n    [self addSubview:_backView];\n    \n    _percentLab = [[UILabel alloc]initWithFrame:_backView.bounds];\n    _percentLab.textAlignment = NSTextAlignmentCenter;\n    _percentLab.font = [UIFont systemFontOfSize:10.0];\n    _percentLab.textColor = kWHC_FooterPercentLabTxtColor;\n    _percentLab.text = @\"0\";\n    [_backView addSubview:_percentLab];\n    \n    _gradientProgressBar = [CAGradientLayer layer];\n    _gradientProgressBar.frame = _backView.bounds;\n    _gradientProgressBar.backgroundColor = [UIColor clearColor].CGColor;\n    _gradientProgressBar.colors = @[(id)KWHC_StartColor , (id)KWHC_EndColor];\n    _gradientProgressBar.locations = @[@(0.0) , @(1.0)];\n    \n    _progressBar = [CAShapeLayer layer];\n    _progressBar.frame = _backView.bounds;\n    _progressBar.backgroundColor = [UIColor clearColor].CGColor;\n    _progressBar.fillColor = [UIColor clearColor].CGColor;\n    _progressBar.strokeColor = [UIColor blueColor].CGColor;\n    _progressBar.lineWidth = 5.0;\n    _gradientProgressBar.mask = _progressBar;\n    \n    [_backView.layer addSublayer:_gradientProgressBar];\n    \n    _progressBarImageView = [[UIImageView alloc]initWithFrame:_backView.frame];\n}\n\n- (void)updateProgressBarWithValue:(CGFloat)value{\n    value = value < 0 ? 0 : value;\n    CGFloat  endAngle = value / kWHC_RefreshingHeight;\n    if(endAngle > 1.0){\n        endAngle = 1.0;\n    }\n    CGMutablePathRef  path = CGPathCreateMutable();\n    CGPathAddArc(path, NULL,\n                 _progressBar.frame.size.width / 2.0, _progressBar.frame.size.height / 2.0, kWHC_WaterDropSize / 2.0 - 3.0, -M_PI / 2.0, endAngle * M_PI * 2.0 - M_PI / 2.0, NO);\n    _progressBar.path = path;\n    _percentLab.text = [NSString stringWithFormat:@\"%.0f\",endAngle * 100.0];\n    CGPathRelease(path);\n}\n\n- (UIImage *)getProgressBarImage{\n    UIGraphicsBeginImageContext(_gradientProgressBar.frame.size);\n    CGContextRef  context  = UIGraphicsGetCurrentContext();\n    [_gradientProgressBar renderInContext:context];\n    return UIGraphicsGetImageFromCurrentImageContext();\n}\n\n- (void)setImageProgressBarAnimation{\n    CABasicAnimation  * ba = [CABasicAnimation animationWithKeyPath:@\"transform.rotation.z\"];\n    ba.fromValue = @(0);\n    ba.toValue = @(M_PI * 2.0);\n    ba.duration = 1.0;\n    ba.cumulative = YES;\n    ba.repeatCount = INFINITY;\n    [_progressBarImageView.layer addAnimation:ba forKey:@\"\"];\n}\n- (void)setSuperView:(UIScrollView *)superView{\n    _superView = superView;\n}\n\n- (void)setUpRefreshDidFinished{\n    _canRequest = NO;\n    _isDidSendRequest = NO;\n    _currentRefreshState = DidRefreshed;\n    if([self.subviews containsObject:_progressBarImageView]){\n        [_progressBarImageView.layer removeAllAnimations];\n        [_progressBarImageView removeFromSuperview];\n    }\n    if(![self.subviews containsObject:_backView]){\n        [self addSubview:_backView];\n    }\n    self.hidden = YES;\n}\n\n- (void)resetUpRefreshState{\n    _isSetOffset = NO;\n    _canRequest = YES;\n    _currentRefreshState = NoneRefresh;\n    _loadLab.text = kWHC_LoadMoreTxt;\n}\n\n- (void)sendUpRefreshCommand{\n    if(!_isDidSendRequest){\n        _isDidSendRequest = YES;\n        if(_delegate && [_delegate respondsToSelector:@selector(WHCUpPullRequest)]){\n            [_delegate WHCUpPullRequest];\n        }\n    }\n}\n\n- (void)updatePostion{\n    CGFloat  superHeight = _superView.height - _superView.contentInset.top - _superView.contentInset.bottom;\n    self.y = MAX(superHeight, _superView.contentSize.height);\n}\n\n- (void)setProgressValue:(CGFloat)progressValue{\n    if(_canRequest){\n        if(_currentRefreshState == DoingRefresh || _currentRefreshState == DidRefreshed){\n            return;\n        }\n        _superOriginalContentInset = _superView.contentInset;\n        CGFloat  actualHeight = _superView.height - _superOriginalContentInset.bottom - _superOriginalContentInset.top;\n        CGFloat  beyondHeight = _superView.contentSize.height - actualHeight;\n        CGFloat  showFooterOffset = beyondHeight - _superOriginalContentInset.top;\n        if(beyondHeight < 0){\n            showFooterOffset = -_superOriginalContentInset.top;\n        }\n        CGFloat  actualOffset = progressValue - showFooterOffset;\n        if(actualOffset > kWHC_RefreshingHeight && _currentRefreshState == WillRefresh && _superView.isDragging){\n            _currentRefreshState = DoingRefresh;\n        }else if(_superView.isDragging){\n            if(self.hidden){\n                self.hidden = NO;\n            }\n            _currentRefreshState = WillRefresh;\n        }\n        switch (_currentRefreshState) {\n            case NoneRefresh:\n            case WillRefresh:\n                if(![self.subviews containsObject:_backView]){\n                    [self addSubview:_backView];\n                }\n                [self updateProgressBarWithValue:actualOffset];\n                break;\n            case DoingRefresh:\n                if([self.subviews containsObject:_backView]){\n                    [_backView removeFromSuperview];\n                    [self updateProgressBarWithValue:kWHC_RefreshingHeight];\n                }\n                if(![self.subviews containsObject:_progressBarImageView]){\n                    [self addSubview:_progressBarImageView];\n                    if(_progressBarImageView.image == nil){\n                        _progressBarImageView.image = [self getProgressBarImage];\n                    }\n                    [self setImageProgressBarAnimation];\n                    _loadLab.text = kWHC_LoadingTxt;\n                }\n                break;\n            default:\n                break;\n        }\n        if(_superView.isDragging && _currentRefreshState == DoingRefresh){\n            [self sendUpRefreshCommand];\n        }\n    }else{\n        if(self.hidden == NO){\n            self.hidden = YES;\n        }\n    }\n}\n\n@end\n\n#pragma mark - 下拉刷新视图 -\n\n@interface WHC_PullHeaderView : UIView\n@property (nonatomic , assign)CGFloat                 defualtOffset;              //默认偏移\n@property (nonatomic , assign)WHCRefreshStatus        currentRefreshState;        //当前刷新状态\n@property (nonatomic , assign)BOOL                    isCloseHeader;              //是否关闭头\n@property (nonatomic , assign)BOOL                    isRequestEndNOInit;         //请求结束但没有初始化\n@property (nonatomic , assign)BOOL                    canRequest;                 //可以请求\n@property (nonatomic , assign)UIEdgeInsets            superOriginalContentInset;  //super原始偏移值\n- (void)setProgressValue:(CGFloat)progressValue;\n- (void)setProgressBarEndDragPostion;\n@end\n\n@interface WHC_PullHeaderView (){\n    UIView             *   _backView;                    //背景视图\n    CAGradientLayer    *   _gradientProgressBar;         //渐变进度条层\n    CAShapeLayer       *   _progressBar;                 //进度条层\n    UIImageView        *   _progressBarImageView;        //图片进度条\n    UILabel            *   _percentLab;                  //百分比\n    UILabel            *   _refreshAlertLab;             //刷新提示\n    UIScrollView       *   _superView;                   //父视图\n    id                     _delegate;                    //刷新代理\n    BOOL                   _isBreak;                     //水滴是否断开\n    BOOL                   _isSetDefualtOffset;          //是否已经设置默认偏移\n    BOOL                   _isDidRefresh;                //已经刷新过了\n    BOOL                   _isDidSendRequest;            //是否已经发生请求\n    CGFloat                _currentRadius;               //当前水滴半径\n}\n@end\n\n@implementation WHC_PullHeaderView\n\n- (instancetype)initWithFrame:(CGRect)frame delegate:(id<WHC_PullRefreshDelegate>)delegate{\n    self = [super initWithFrame:frame];\n    if(self){\n        self.backgroundColor = [UIColor whiteColor];\n        _delegate = delegate;\n        [self initData];\n    }\n    return self;\n}\n\n- (void)setDelegate:(id<WHC_PullRefreshDelegate>)delegate{\n    _delegate = delegate;\n}\n\n- (void)willMoveToSuperview:(UIView *)newSuperview{\n    [super willMoveToSuperview:newSuperview];\n    [_superView cancelledObsever];\n    if(newSuperview){\n        [_superView addObserver];\n    }\n}\n\n- (void)setSuperView:(UIScrollView *)superView{\n    _superView = superView;\n}\n\n\n- (UIView *)createView{\n    UIView * view = [UIView new];\n    view.size = CGSizeMake(kWHC_WaterDropSize, kWHC_WaterDropSize);\n    view.center = CGPointMake(self.centerX, self.height - kWHC_WaterDropSize / 2.0);\n    view.backgroundColor = [UIColor colorWithCGColor:kWHC_WaterBackColor];\n    view.layer.cornerRadius = kWHC_WaterDropSize / 2.0;\n    view.clipsToBounds = YES;\n    return view;\n}\n\n- (void)initData{\n    _canRequest = YES;\n    _defualtOffset = 0;\n    _isSetDefualtOffset = NO;\n    _currentRadius = kWHC_WaterDropSize / 2.0;\n    _backView = [self createView];\n    [self addSubview:_backView];\n    \n    _gradientProgressBar = [CAGradientLayer layer];\n    _gradientProgressBar.frame = _backView.bounds;\n    _gradientProgressBar.backgroundColor = [UIColor clearColor].CGColor;\n    _gradientProgressBar.colors = @[(id)KWHC_StartColor , (id)KWHC_EndColor];\n    _gradientProgressBar.locations = @[@(0.0) , @(1.0)];\n    \n    _progressBar = [CAShapeLayer layer];\n    _progressBar.frame = _backView.bounds;\n    _progressBar.backgroundColor = [UIColor clearColor].CGColor;\n    _progressBar.fillColor = [UIColor clearColor].CGColor;\n    _progressBar.strokeColor = [UIColor blueColor].CGColor;\n    _progressBar.lineWidth = 5.0;\n    _gradientProgressBar.mask = _progressBar;\n    [_backView.layer addSublayer:_gradientProgressBar];\n    \n    _percentLab = [[UILabel alloc]initWithFrame:_backView.bounds];\n    _percentLab.textAlignment = NSTextAlignmentCenter;\n    _percentLab.textColor = kWHC_HeaderPercentLabTxtColor;\n    _percentLab.font = [UIFont systemFontOfSize:10.0];\n    [_backView addSubview:_percentLab];\n    \n    _progressBarImageView = [[UIImageView alloc]initWithFrame:_backView.frame];\n    _progressBarImageView.centerY = _progressBarImageView.width / 2.0;\n    \n    _refreshAlertLab = [[UILabel alloc]initWithFrame:self.bounds];\n    _refreshAlertLab.height = kWHC_WaterDropSize;\n    _refreshAlertLab.center = _backView.center;\n    _refreshAlertLab.textColor = kWHC_HeaderLableTxtColor;\n    _refreshAlertLab.font = [UIFont systemFontOfSize:kWHC_FontSize];\n    _refreshAlertLab.textAlignment = NSTextAlignmentCenter;\n    _refreshAlertLab.text = kWHC_RefreshFinishTxt;\n}\n\n- (void)updateProgressBarWithValue:(CGFloat)value{\n    CGFloat  endAngle = value / kWHC_PullHeight;\n    if(endAngle > 1.0){\n        endAngle = 1.0;\n    }\n    CGMutablePathRef  path = CGPathCreateMutable();\n    CGPathAddArc(path, NULL,\n                 _progressBar.frame.size.width / 2.0, _progressBar.frame.size.height / 2.0, kWHC_WaterDropSize / 2.0 - 2.5, M_PI / 2.0, endAngle * M_PI * 2.0 + M_PI / 2.0, NO);\n    _progressBar.path = path;\n    CGPathRelease(path);\n    _percentLab.text = [NSString stringWithFormat:@\"%.0f\",endAngle * 100.0];\n}\n\n- (UIImage *)getProgressBarImage{\n    UIGraphicsBeginImageContext(_gradientProgressBar.frame.size);\n    CGContextRef  context  = UIGraphicsGetCurrentContext();\n    [_gradientProgressBar renderInContext:context];\n    return UIGraphicsGetImageFromCurrentImageContext();\n}\n\n- (void)setImageProgressBarAnimation{\n    if(_progressBarImageView.image == nil){\n        _progressBarImageView.image = [self getProgressBarImage];\n    }\n    _progressBarImageView.centerY = _progressBarImageView.height / 2.0;\n    if(![self.subviews containsObject:_progressBarImageView]){\n        [self addSubview:_progressBarImageView];\n    }\n    CABasicAnimation  * ba = [CABasicAnimation animationWithKeyPath:@\"transform.rotation.z\"];\n    ba.fromValue = @(0);\n    ba.toValue = @(M_PI * 2.0);\n    ba.duration = 1.0;\n    ba.cumulative = YES;\n    ba.repeatCount = INFINITY;\n    [_progressBarImageView.layer addAnimation:ba forKey:@\"\"];\n}\n\n- (void)setProgressValue:(CGFloat)progressValue{\n    if(_canRequest){\n        if(_currentRefreshState != DoingRefresh && _currentRefreshState != DidRefreshed){\n            _superOriginalContentInset = _superView.contentInset;\n        }\n        CGFloat   actualOffset = progressValue + _superOriginalContentInset.top;\n        CGFloat   absActualOffset = -actualOffset;\n        if(!_superView.isDragging){\n            if(_currentRefreshState == WillRefresh || _currentRefreshState == NoneRefresh){\n                if(absActualOffset > kWHC_RefreshingHeight && absActualOffset <= kWHC_PullHeight){\n                    _backView.centerY = self.height - (absActualOffset - kWHC_RefreshingHeight) - kWHC_WaterDropSize / 2.0;\n                    _currentRadius = (1.0 - (absActualOffset - kWHC_RefreshingHeight) / (kWHC_PullHeight - kWHC_Margin)) * kWHC_WaterDropSize / 2.0;\n                }else{\n                    _currentRadius = kWHC_WaterDropSize / 2.0;\n                    _backView.centerY = self.height - kWHC_WaterDropSize / 2.0;\n                }\n            }\n            [self updateProgressBarWithValue:absActualOffset];\n            [self setNeedsDisplay];\n        }else{\n            if(actualOffset < 0 && _currentRefreshState != DoingRefresh && _currentRefreshState != DidRefreshed){\n                if(_backView.hidden){\n                    _backView.hidden = NO;\n                }\n                if(absActualOffset > kWHC_RefreshingHeight){\n                    if(absActualOffset <= kWHC_PullHeight){\n                        _isBreak = NO;\n                        _backView.centerY = self.height - (absActualOffset - kWHC_RefreshingHeight) - kWHC_WaterDropSize / 2.0;\n                        _currentRadius = (1.0 - (absActualOffset - kWHC_RefreshingHeight) / (kWHC_PullHeight - kWHC_Margin)) * kWHC_WaterDropSize / 2.0;\n                        _currentRefreshState = WillRefresh;\n                        if(_currentRadius < kWHC_BreakRadius){\n                            _isBreak = YES;\n                            _currentRefreshState = DoingRefresh;\n                            _currentRadius = kWHC_BreakRadius;\n                        }\n                    }else{\n                        _isBreak = YES;\n                        _currentRadius = kWHC_BreakRadius;\n                        _currentRefreshState = DoingRefresh;\n                        _backView.centerY = kWHC_RefreshingHeight / 2.0;\n                    }\n                    \n                }\n                [self updateProgressBarWithValue:absActualOffset];\n                [self setNeedsDisplay];\n                \n                switch (_currentRefreshState) {\n                    case NoneRefresh:\n                    case WillRefresh:\n                        if(![self.subviews containsObject:_backView]){\n                            [self addSubview:_backView];\n                        }\n                        break;\n                    case DoingRefresh:{\n                        if([self.subviews containsObject:_backView]){\n                            [_backView removeFromSuperview];\n                            [self setImageProgressBarAnimation];\n                        }\n                    }\n                        break;\n                    case DidRefreshed:\n                        break;\n                    default:\n                        break;\n                }\n                if(_superView.isDragging && _currentRefreshState == DoingRefresh){\n                    [self sendDownRefreshCommand];\n                }\n            }\n        }\n    }else{\n        if(_backView.hidden == NO){\n            _backView.hidden = YES;\n        }\n    }\n}\n\n- (void)setDefualtOffset:(CGFloat)defualtOffset{\n    if(!_isSetDefualtOffset){\n        _defualtOffset = defualtOffset;\n        _isSetDefualtOffset = YES;\n    }\n}\n\n- (void)setDownRefreshDidFinished{\n    _currentRefreshState = DidRefreshed;\n    _isDidRefresh = YES;\n    _canRequest = NO;\n    if([self.subviews containsObject:_progressBarImageView]){\n        _refreshAlertLab.centerY = _progressBarImageView.centerY;\n        [_progressBarImageView removeFromSuperview];\n        [self addSubview:_refreshAlertLab];\n    }\n}\n\n- (void)resetDownRefreshState{\n    [self updateProgressBarWithValue:0];\n    [_progressBarImageView.layer removeAllAnimations];\n    _progressBarImageView.centerY = _progressBarImageView.height / 2.0;\n    _refreshAlertLab.centerY = _refreshAlertLab.height / 2.0;\n    if([self.subviews containsObject:_progressBarImageView]){\n        [_progressBarImageView removeFromSuperview];\n    }\n    if([self.subviews containsObject:_refreshAlertLab]){\n        [_refreshAlertLab removeFromSuperview];\n    }\n    if(![self.subviews containsObject:_backView]){\n        [self addSubview:_backView];\n    }\n    _isRequestEndNOInit = NO;\n    _isDidSendRequest = NO;\n    _backView.centerY = self.height - kWHC_WaterDropSize / 2.0;\n    if(_currentRefreshState == WillRefresh){\n        _backView.hidden = NO;\n    }else if(_currentRefreshState == DidRefreshed){\n        _backView.hidden = YES;\n        _isCloseHeader = NO;\n    }\n    _isBreak = NO;\n    _currentRefreshState = NoneRefresh;\n    [self setNeedsDisplay];\n}\n\n- (void)setProgressBarEndDragPostion{\n    _progressBarImageView.centerY = self.height - kWHC_RefreshingHeight / 2.0;\n}\n\n- (void)sendDownRefreshCommand{\n    if(![self.subviews containsObject:_progressBarImageView]){\n        [self addSubview:_progressBarImageView];\n    }\n    _progressBarImageView.centerY = self.height - kWHC_RefreshingHeight / 2.0;\n    if(!_isDidSendRequest){\n        _isDidSendRequest = YES;\n        if(_delegate && [_delegate respondsToSelector:@selector(WHCDownPullRequest)]){\n            [_delegate WHCDownPullRequest];\n        }\n    }\n}\n\n- (void)drawRect:(CGRect)rect{\n    if(_isBreak && (_currentRefreshState == DoingRefresh || _currentRefreshState == DidRefreshed)){\n        return;\n    }\n    CGPoint  a     = CGPointMake(_backView.x + 0.5, _backView.centerY),\n             b     = CGPointMake(_backView.maxX - 0.5, _backView.centerY),\n             c     = CGPointMake(_backView.centerX + _currentRadius - 0.5, self.height - _currentRadius),\n             d     = CGPointMake(_backView.centerX - _currentRadius + 0.5, self.height - _currentRadius),\n             ctr1  = CGPointMake(d.x, d.y - (self.height - _currentRadius - _backView.centerY) / 2.0),\n             ctr2  = CGPointMake(c.x, c.y - (self.height - _currentRadius - _backView.centerY) / 2.0);\n    \n    UIBezierPath * bezierPath = [UIBezierPath bezierPath];\n    bezierPath.lineJoinStyle = kCGLineJoinRound;\n    bezierPath.lineCapStyle = kCGLineCapRound;\n    [bezierPath moveToPoint:a];\n    [bezierPath addQuadCurveToPoint:d controlPoint:ctr1];\n    [bezierPath addLineToPoint:c];\n    [bezierPath addQuadCurveToPoint:b controlPoint:ctr2];\n    [bezierPath moveToPoint:a];\n    [bezierPath closePath];\n    \n    CGContextRef  context = UIGraphicsGetCurrentContext();\n    CGContextSetStrokeColorWithColor(context, kWHC_WaterBackColor);\n    CGContextSetFillColorWithColor(context, kWHC_WaterBackColor);\n    CGContextSetLineWidth(context, 1.0);\n    if(_backView.hidden == NO){\n        CGContextAddArc(context, d.x + _currentRadius - 0.5, d.y, _currentRadius - 0.5, 0, M_PI * 2.0, NO);\n        CGContextDrawPath(context, kCGPathFillStroke);\n        \n        CGContextAddPath(context, bezierPath.CGPath);\n        CGContextDrawPath(context, kCGPathFillStroke);\n    }\n    UIGraphicsEndImageContext();\n}\n\n@end\n\n#pragma mark - 滚动视图分类 -\n\n@implementation UIScrollView (WHC_PullRefresh)\nconst char WHCHeaderMask = '8';\nconst char WHCFooterMask = '9';\n\n- (void)createHeaderViewWithDelegate:(id<WHC_PullRefreshDelegate>)delegate{\n    for (WHC_PullHeaderView * view in self.subviews) {\n        if([view isKindOfClass:[WHC_PullHeaderView class]]){\n            return;\n        }\n    }\n    WHC_PullHeaderView   *  headerView = [[WHC_PullHeaderView alloc]initWithFrame:CGRectMake(0, -kWHC_PullHeight, CGRectGetWidth([UIScreen mainScreen].bounds), kWHC_PullHeight) delegate:delegate];\n    headerView.backgroundColor = self.backgroundColor;\n    [headerView setSuperView:self];\n    objc_setAssociatedObject(self, &WHCHeaderMask, headerView, OBJC_ASSOCIATION_RETAIN);\n    [self insertSubview:headerView atIndex:0];\n}\n\n- (void)createFooterViewWithDelegate:(id<WHC_PullRefreshDelegate>)delegate{\n    for (WHC_PullFooterView * view in self.subviews) {\n        if([view isKindOfClass:[WHC_PullFooterView class]]){\n            return;\n        }\n    }\n    WHC_PullFooterView   *  footerView = [[WHC_PullFooterView alloc]initWithFrame:CGRectMake(0, self.height, CGRectGetWidth([UIScreen mainScreen].bounds), kWHC_RefreshingHeight) delegate:delegate];\n    [footerView setSuperView:self];\n    footerView.backgroundColor = self.backgroundColor;\n    objc_setAssociatedObject(self, &WHCFooterMask, footerView, OBJC_ASSOCIATION_RETAIN);\n    [self insertSubview:footerView atIndex:0];\n}\n\n- (void)setWHCRefreshStyle:(WHCPullRefreshStyle)refreshStyle  delegate:(id<WHC_PullRefreshDelegate>)delegate{\n    [self removeHeaderView];\n    [self removeFooterView];\n    if(refreshStyle != NoneRefresh){\n        [self addObserver];\n        switch (refreshStyle) {\n            case AllStyle:\n                [self createFooterViewWithDelegate:delegate];\n                [self createHeaderViewWithDelegate:delegate];\n                break;\n            case FooterStyle:\n                [self removeHeaderView];\n                [self createFooterViewWithDelegate:delegate];\n                break;\n            case HeaderStyle:\n                [self createHeaderViewWithDelegate:delegate];\n                break;\n            default:\n                break;\n        }\n    }\n}\n\n- (void)removeHeaderView{\n    WHC_PullHeaderView  * headerView = [self getHeaderView];\n    if(headerView){\n        self.contentInset = UIEdgeInsetsMake(self.contentInset.top, 0, self.contentInset.bottom, 0);\n        [headerView setDelegate:nil];\n        if([self.subviews containsObject:headerView]){\n            [headerView removeFromSuperview];\n            headerView = nil;\n        }\n    }\n}\n\n- (void)removeFooterView{\n    WHC_PullFooterView  * footerView = [self getFooterView];\n    if(footerView){\n        self.contentInset = UIEdgeInsetsMake(self.contentInset.top, 0, self.contentInset.bottom, 0);\n        [footerView setDelegate:nil];\n        if([self.subviews containsObject:footerView]){\n            [footerView removeFromSuperview];\n            footerView = nil;\n        }\n    }\n}\n\n- (WHC_PullHeaderView *)getHeaderView{\n    return objc_getAssociatedObject(self, &WHCHeaderMask);\n}\n\n- (WHC_PullFooterView *)getFooterView{\n    return objc_getAssociatedObject(self, &WHCFooterMask);\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{\n    if([keyPath isEqualToString:kWHC_ContentOffset]){\n        [self scrollViewDidScroll:[change[NSKeyValueChangeNewKey] CGPointValue]];\n    }else if ([keyPath isEqualToString:kWHC_ContentSize]){\n        WHC_PullFooterView  * footerView = [self getFooterView];\n        if(footerView){\n            [footerView updatePostion];\n        }\n    }\n}\n\n- (void)WHCDidCompletedWithRefreshIsDownPull:(BOOL)isDown{\n    __weak  typeof(self)  sf = self;\n    if(isDown){\n        WHC_PullHeaderView  * headerView = [self getHeaderView];\n        if(headerView){\n            [headerView setDownRefreshDidFinished];\n            double delayInSeconds = 0.3;\n            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));\n            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){\n                [UIView animateWithDuration:kWHC_OffsetAnimationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n                    sf.contentInset = UIEdgeInsetsMake(headerView.superOriginalContentInset.top, 0, headerView.superOriginalContentInset.bottom, 0);\n                } completion:^(BOOL finished) {\n                    if(!self.isDragging){\n                        [headerView resetDownRefreshState];\n                    }else{\n                        headerView.isRequestEndNOInit = YES;\n                    }\n                    headerView.canRequest = YES;\n                }];\n            });\n        }\n    }else{\n        WHC_PullFooterView  * footerView = [self getFooterView];\n        if(footerView){\n            [footerView setUpRefreshDidFinished];\n            [UIView animateWithDuration:kWHC_OffsetAnimationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n                sf.contentInset = UIEdgeInsetsMake(footerView.superOriginalContentInset.top, 0, footerView.superOriginalContentInset.bottom, 0);\n            } completion:^(BOOL finished) {\n                footerView.isSetOffset = NO;\n                if(!self.isDragging){\n                    [footerView resetUpRefreshState];\n                }\n            }];\n        }\n    }\n}\n\n- (void)scrollViewDidScroll:(CGPoint )contentOffset{\n    CGFloat  defaultOffset = 0.0;\n    WHC_PullHeaderView  * headerView = [self getHeaderView];\n    WHC_PullFooterView  * footerView = [self getFooterView];\n    if(headerView){\n        defaultOffset = headerView.superOriginalContentInset.top;\n    }else if(footerView){\n        defaultOffset = footerView.superOriginalContentInset.top;\n    }\n    __weak  typeof(self)  sf = self;\n    if(contentOffset.y < -defaultOffset && headerView){\n        if(!self.isDragging){\n            [self scrollViewDidEndDraggingWithwillDecelerate:YES isUp:NO];\n        }else{\n            if(-contentOffset.y < self.contentInset.top){\n                if(!headerView.isCloseHeader && headerView.currentRefreshState == DoingRefresh){\n                    headerView.isCloseHeader = YES;\n                    [UIView animateWithDuration:kWHC_OffsetAnimationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n                        sf.contentInset = UIEdgeInsetsMake(headerView.superOriginalContentInset.top, 0, headerView.superOriginalContentInset.bottom, 0);\n                    } completion:nil];\n                    \n                }\n            }else if(-contentOffset.y >= self.contentInset.top + kWHC_RefreshingHeight){\n                if(headerView.isCloseHeader && headerView.currentRefreshState == DoingRefresh){\n                    headerView.isCloseHeader = NO;\n                    [UIView animateWithDuration:kWHC_OffsetAnimationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n                        sf.contentInset = UIEdgeInsetsMake(headerView.superOriginalContentInset.top + kWHC_RefreshingHeight, 0, headerView.superOriginalContentInset.bottom, 0);\n                    } completion:nil];\n                }\n            }\n        }\n        if(footerView && footerView.currentRefreshState == DidRefreshed){\n            [footerView resetUpRefreshState];\n        }\n        [headerView setProgressValue:contentOffset.y];\n    }else{\n        if(!self.isDragging){\n            [self scrollViewDidEndDraggingWithwillDecelerate:YES isUp:YES];\n        }\n        \n        if(headerView && headerView.currentRefreshState == DidRefreshed){\n            [headerView resetDownRefreshState];\n        }\n        if(footerView){\n            [footerView setProgressValue:contentOffset.y];\n        }\n    }\n}\n\n- (void)scrollViewDidEndDraggingWithwillDecelerate:(BOOL)decelerate isUp:(BOOL)isUp{\n    __weak  typeof(self)  sf = self;\n    if(isUp){\n        WHC_PullFooterView  * footerView = [self getFooterView];\n        if(footerView){\n            if(footerView.currentRefreshState == DoingRefresh  && !footerView.isSetOffset){\n                footerView.isSetOffset = YES;\n                [UIView animateWithDuration:kWHC_OffsetAnimationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{\n                    sf.contentInset = UIEdgeInsetsMake(footerView.superOriginalContentInset.top, 0, kWHC_RefreshingHeight + footerView.superOriginalContentInset.bottom, 0);\n                } completion:nil];\n            }else if (!footerView.isSetOffset){\n                [footerView resetUpRefreshState];\n            }\n        }\n    }else{\n        WHC_PullHeaderView  * headerView = [self getHeaderView];\n        if(headerView){\n            if(headerView.currentRefreshState == DoingRefresh){\n                if(!headerView.isCloseHeader){\n                    sf.contentInset = UIEdgeInsetsMake(kWHC_RefreshingHeight + headerView.superOriginalContentInset.top, 0, headerView.superOriginalContentInset.bottom, 0);\n                }\n                [headerView setProgressBarEndDragPostion];\n//            }[headerView resetDownRefreshState];\n            }else if(headerView.currentRefreshState != DidRefreshed || headerView.isRequestEndNOInit){\n                [headerView resetDownRefreshState];\n            }\n        }\n    }\n}\n\n- (void)addObserver{\n    [self addObserver:self forKeyPath:kWHC_ContentOffset options:NSKeyValueObservingOptionNew context:nil];\n    [self addObserver:self forKeyPath:kWHC_ContentSize options:NSKeyValueObservingOptionNew context:nil];\n}\n\n- (void)cancelledObsever{\n\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_Loading.h",
    "content": "//\n//  UIView+WHC_Loading.h\n//  UIView+WHC_Loading\n//\n//  Created by 吴海超 on 15/3/25.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface UIView (WHC_Loading)\n\n- (void)startLoading;\n- (void)stopLoading;\n- (void)startLoadingWithTxt:(NSString*)customTitle;\n- (void)stopLoadingWithTxt;\n- (void)startLoadingWithTxtUser:(NSString*)customTitle;\n- (void)stopLoadingWithTxtUser;\n- (void)startLoadingWithUser;\n- (void)stopLoadingWithUser;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_Loading.m",
    "content": "//\n//  UIView+WHC_Loading.m\n//  UIView+WHC_Loading\n//\n//  Created by 吴海超 on 15/3/25.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n#import \"UIView+WHC_Loading.h\"\n#define KWHC_LOADING_VIEW_SIZE (50.0)\n#define KWHC_FONT_SIZE (15.0)\n#define KWHC_LOADING_VIEW_SIZE_TXT (100.0)\n#define KWHC_LOADING_LABLE_HEIGHT (15.0)\n#define KWHC_LOADING_VIEW_CORNER (10.0)\n#define KWHC_LOADING_VIEW_ALPHA (1.0)\n#define KWHC_LOADING_VIEW_TAG (10000000)\n#define KWHC_LOADING_PAD (15.0)\n#define KWHC_LOADING_TXT (@\"请稍等\")\n@implementation UIView (WHC_Loading)\n\n- (UIView *)createLoadingViewWithIsTxt:(BOOL)isTxt customTitle:(NSString *)customTitle{\n    CGSize  screenSize = [UIScreen mainScreen].bounds.size;\n    CGFloat backViewSize = KWHC_LOADING_VIEW_SIZE;\n    if(isTxt){\n        if(customTitle == nil){\n            customTitle = KWHC_LOADING_TXT;\n        }\n        if(customTitle.length == 0){\n            customTitle = KWHC_LOADING_TXT;\n        }\n        backViewSize = KWHC_LOADING_VIEW_SIZE_TXT;\n    }\n    UIView * backView = [[UIView alloc]initWithFrame:CGRectMake((screenSize.width - backViewSize) / 2.0, screenSize.height / 2.0, backViewSize, backViewSize)];\n    backView.layer.cornerRadius = KWHC_LOADING_VIEW_CORNER;\n    backView.backgroundColor = [UIColor blackColor];\n    backView.alpha = KWHC_LOADING_VIEW_ALPHA;\n    backView.clipsToBounds = YES;\n    backView.tag = KWHC_LOADING_VIEW_TAG;\n    \n    UIActivityIndicatorView  * indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];\n    if(isTxt){\n        indicatorView.center = CGPointMake(CGRectGetWidth(backView.frame) / 2.0, (CGRectGetHeight(backView.frame) - KWHC_LOADING_LABLE_HEIGHT)/ 2.0);\n    }else{\n        indicatorView.center = CGPointMake(CGRectGetWidth(backView.frame) / 2.0, CGRectGetHeight(backView.frame) / 2.0);\n    }\n    [indicatorView startAnimating];\n    [backView addSubview:indicatorView];\n    \n    if(isTxt){\n        UILabel * labTxt = [[UILabel alloc]initWithFrame:CGRectMake(KWHC_LOADING_PAD, CGRectGetHeight(indicatorView.frame) + indicatorView.frame.origin.y+ 5.0, CGRectGetWidth(backView.frame) - KWHC_LOADING_PAD * 2.0, KWHC_LOADING_LABLE_HEIGHT)];\n        labTxt.backgroundColor = [UIColor clearColor];\n        labTxt.minimumScaleFactor = 0.2;\n        labTxt.adjustsFontSizeToFitWidth = YES;\n        labTxt.text = customTitle;\n        labTxt.textAlignment = NSTextAlignmentCenter;\n        labTxt.textColor = [UIColor whiteColor];\n        [backView addSubview:labTxt];\n    }\n    return backView;\n}\n\n- (void)baseStartLoadingWithUser:(BOOL)isUser withIsTxt:(BOOL)isTxt customTitle:(NSString*)customTitle{\n    UIView * loadingView = [self viewWithTag:KWHC_LOADING_VIEW_TAG];\n    if(loadingView == nil){\n        self.alpha = 1.0;\n        self.userInteractionEnabled = isUser;\n        [self addSubview:[self createLoadingViewWithIsTxt:isTxt customTitle:customTitle]];\n    }\n}\n\n- (void)baseStopLoadingWithUser:(BOOL)isUser{\n    UIView * clearView = [self viewWithTag:KWHC_LOADING_VIEW_TAG];\n    if(clearView != nil){\n        self.alpha = 1.0;\n        self.userInteractionEnabled = isUser;\n        [clearView removeFromSuperview];\n        clearView = nil;\n    }\n}\n\n- (void)startLoading{\n    [self baseStartLoadingWithUser:NO withIsTxt:NO customTitle:nil];\n}\n\n- (void)stopLoading{\n    [self baseStopLoadingWithUser:YES];\n}\n\n- (void)startLoadingWithTxt:(NSString*)customTitle{\n    [self baseStartLoadingWithUser:NO withIsTxt:YES customTitle:customTitle];\n}\n\n- (void)stopLoadingWithTxt{\n    [self stopLoading];\n}\n\n- (void)startLoadingWithTxtUser:(NSString*)customTitle{\n    [self baseStartLoadingWithUser:YES withIsTxt:YES customTitle:customTitle];\n}\n\n- (void)stopLoadingWithTxtUser{\n    [self stopLoading];\n}\n\n- (void)startLoadingWithUser{\n    [self baseStartLoadingWithUser:YES withIsTxt:NO customTitle:nil];\n}\n\n- (void)stopLoadingWithUser{\n    [self stopLoading];\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_Toast.h",
    "content": "//\n//  UIView+WHC_Toast.h\n//  UIView+WHC_Toast\n//\n//  Created by 吴海超 on 15/3/24.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\ntypedef enum{\n    TOP,\n    MIDDLE,\n    BOTTOM\n}WHC_TOAST_POSTION;\n\ntypedef enum {\n    WHITE_FONT,\n    BLACK_FONT,\n}WHC_TOAST_TYPE;\n\n@interface UIView (WHC_Toast)\n- (void)toast:(NSString *)msg;\n- (void)toast:(NSString *)msg postion:(WHC_TOAST_POSTION)postion;\n- (void)toast:(NSString *)msg type:(WHC_TOAST_TYPE)type;\n- (void)toast:(NSString *)msg postion:(WHC_TOAST_POSTION)postion type:(WHC_TOAST_TYPE)type;\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during;\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during postion:(WHC_TOAST_POSTION)postion;\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during postion:(WHC_TOAST_POSTION)postion type:(WHC_TOAST_TYPE)type;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_Toast.m",
    "content": "//\n//  UIView+WHC_Toast.m\n//  UIView+WHC_Toast\n//\n//  Created by 吴海超 on 15/3/24.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n#import \"UIView+WHC_Toast.h\"\n#define  KWHC_FONT_SIZE (14.0)\n#define  KWHC_ANIMATION_TIME (0.1)\n#define  KWHC_DURING (1.5)\n@implementation UIView (WHC_Toast)\n- (CATransform3D)loadTransform3D:(CGFloat)z{\n    CATransform3D scale = CATransform3DIdentity;\n    scale.m34 = -1.0 / 1000.0;\n    CATransform3D transform = CATransform3DMakeTranslation(0.0, 0.0, z);\n    return CATransform3DConcat(transform,scale);\n}\n\n- (void)toast:(NSString *)msg{\n    [self toast:msg during:KWHC_DURING];\n}\n\n- (void)toast:(NSString *)msg postion:(WHC_TOAST_POSTION)postion{\n    [self toast:msg during:KWHC_DURING postion:postion];\n}\n\n- (void)toast:(NSString *)msg type:(WHC_TOAST_TYPE)type{\n    [self toast:msg during:KWHC_DURING postion:BOTTOM type:type];\n}\n\n- (void)toast:(NSString *)msg postion:(WHC_TOAST_POSTION)postion type:(WHC_TOAST_TYPE)type{\n    [self toast:msg during:KWHC_DURING postion:postion type:type];\n}\n\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during{\n    [self toast:msg during:KWHC_DURING postion:BOTTOM];\n}\n\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during postion:(WHC_TOAST_POSTION)postion{\n    [self toast:msg during:KWHC_DURING postion:postion type:WHITE_FONT];\n}\n\n- (void)toast:(NSString *)msg during:(NSTimeInterval)during postion:(WHC_TOAST_POSTION)postion type:(WHC_TOAST_TYPE)type{\n    [self createContentLabWithMessage:msg during:during postion:postion type:type];\n}\n\n\n- (UILabel*)createContentLabWithMessage:(NSString*)msg during:(NSTimeInterval)during postion:(WHC_TOAST_POSTION)postion type:(WHC_TOAST_TYPE)type{\n    self.userInteractionEnabled = NO;\n    CGSize      screenSize = [UIScreen mainScreen].bounds.size;\n    CGFloat     contentLabY = 0.0;\n    UIColor   * fontColor = nil;\n    UIColor   * backColor = nil;\n    \n    switch (postion) {\n        case TOP:\n            contentLabY = 100.0;\n            break;\n        case MIDDLE:\n            contentLabY = screenSize.height / 2.0;\n            break;\n        case BOTTOM:\n            contentLabY = screenSize.height - 100.0;\n        break;\n        default:\n            break;\n    }\n    \n    switch (type) {\n        case WHITE_FONT:\n            fontColor = [UIColor whiteColor];\n            backColor = [UIColor blackColor];\n            break;\n        case BLACK_FONT:\n            fontColor = [UIColor blackColor];\n            backColor = [UIColor colorWithRed:240 / 255.0 green:240 / 255.0 blue:240 / 255.0 alpha:1.0];\n        default:\n            break;\n    }\n    \n    CGFloat     pading = 10.0;\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored\"-Wdeprecated-declarations\"\n    CGSize      msgSize = [msg sizeWithFont:[UIFont systemFontOfSize:KWHC_FONT_SIZE]\n                          constrainedToSize:CGSizeMake(MAXFLOAT, 0)];\n#pragma clang diagnostic pop\n    CGFloat     contentLabWidth = msgSize.width + pading * 2.0;\n    NSInteger   multiple = (NSInteger)(msgSize.width / (screenSize.width - pading * 2.0)) + 1;\n    if(multiple > 1){\n        contentLabWidth = screenSize.width - pading * 2.0;\n    }\n    UILabel * contentLab = [[UILabel alloc]initWithFrame:CGRectMake((screenSize.width - contentLabWidth) / 2.0,contentLabY,contentLabWidth,multiple * msgSize.height + pading)];\n    contentLab.numberOfLines = 0;\n    contentLab.backgroundColor = backColor;\n    contentLab.textColor = fontColor;\n    contentLab.font = [UIFont systemFontOfSize:KWHC_FONT_SIZE];\n    contentLab.textAlignment = NSTextAlignmentCenter;\n    contentLab.center = CGPointMake(screenSize.width / 2.0, contentLabY);\n    contentLab.text = msg;\n    contentLab.layer.cornerRadius = 8.0;\n    contentLab.layer.masksToBounds = YES;\n    contentLab.transform = CGAffineTransformMakeScale(0.5, 0.5);\n    [self addSubview:contentLab];\n    [UIView animateWithDuration:KWHC_ANIMATION_TIME animations:^{\n        contentLab.transform = CGAffineTransformMakeScale(1.2, 1.2);\n    }completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            contentLab.transform = CGAffineTransformIdentity;\n        }completion:^(BOOL finished) {\n            [self performSelector:@selector(clearContentLab:) withObject:contentLab afterDelay:during];\n        }];\n        \n    }];\n    return contentLab;\n}\n\n- (void)clearContentLab:(UILabel *)contentLab{\n    \n    [UIView animateWithDuration:KWHC_ANIMATION_TIME animations:^{\n        contentLab.transform = CGAffineTransformMakeScale(0.5, 0.5);\n    } completion:^(BOOL finished) {\n        [contentLab removeFromSuperview];\n        self.userInteractionEnabled = YES;\n    }];\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_ViewProperty.h",
    "content": "//\n//  UIView+WHC_ViewProperty.h\n//  WHC_ ContainerView\n//\n//  Created by 吴海超 on 15/5/15.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <UIKit/UIKit.h>\n\n@interface UIView (WHC_ViewProperty)\n\n- (CGFloat)y;\n\n- (CGFloat)centerY;\n\n- (CGFloat)centerX;\n\n- (CGFloat)maxY;\n\n- (CGFloat)x;\n\n- (CGFloat)maxX;\n\n- (CGPoint)xy;\n\n- (CGFloat)width;\n\n- (CGFloat)height;\n\n- (CGSize)size;\n\n- (void)setMaxY:(CGFloat)maxY;\n\n- (void)setMaxX:(CGFloat)maxX;\n\n- (void)setY:(CGFloat)Y;\n\n- (void)setX:(CGFloat)X;\n\n- (void)setCenterX:(CGFloat)centerX;\n\n- (void)setCenterY:(CGFloat)centerY;\n\n- (void)setXy:(CGPoint)point;\n\n- (void)setSize:(CGSize)size;\n\n- (void)setWidth:(CGFloat)width;\n\n- (void)setHeight:(CGFloat)height;\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/UIUnitCore/UIView+WHC_ViewProperty.m",
    "content": "//\n//  UIView+WHC_ViewProperty.m\n//  WHC_ ContainerView\n//\n//  Created by 吴海超 on 15/5/15.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"UIView+WHC_ViewProperty.h\"\n\n@implementation UIView (WHC_ViewProperty)\n\n- (CGFloat)y{\n    return CGRectGetMinY(self.frame);\n}\n\n- (CGFloat)maxY{\n    return self.y + self.height;\n}\n\n- (void)setMaxY:(CGFloat)maxY{\n    CGFloat  y = maxY - self.height;\n    self.y = y;\n}\n\n- (CGFloat)centerY{\n    return self.center.y;\n}\n\n- (CGFloat)centerX{\n    return self.center.x;\n}\n\n- (void)setCenterX:(CGFloat)centerX{\n    CGPoint  center = self.center;\n    center.x = centerX;\n    self.center = center;\n}\n\n- (void)setCenterY:(CGFloat)centerY{\n    CGPoint  center = self.center;\n    center.y = centerY;\n    self.center = center;\n}\n\n- (CGFloat)x{\n    return CGRectGetMinX(self.frame);\n}\n\n- (CGFloat)maxX{\n    return self.x + self.width;\n}\n\n- (void)setMaxX:(CGFloat)maxX{\n    CGFloat  x = maxX - self.width;\n    self.x = x;\n}\n\n- (CGPoint)xy{\n    return CGPointMake(self.x, self.y);\n}\n\n- (CGFloat)width{\n    return CGRectGetWidth(self.frame);\n}\n\n- (CGFloat)height{\n    return CGRectGetHeight(self.frame);\n}\n\n- (CGSize)size{\n    return CGSizeMake(self.width, self.height);\n}\n\n- (void)setY:(CGFloat)Y{\n    CGRect   rc = self.frame;\n    rc.origin.y = Y;\n    self.frame = rc;\n}\n\n- (void)setX:(CGFloat)X{\n    CGRect   rc = self.frame;\n    rc.origin.x = X;\n    self.frame = rc;\n}\n\n- (void)setXy:(CGPoint)point{\n    CGRect   rc = self.frame;\n    rc.origin = point;\n    self.frame = rc;\n}\n\n- (void)setSize:(CGSize)size{\n    CGRect   rc = self.frame;\n    rc.size = size;\n    self.frame = rc;\n}\n\n- (void)setWidth:(CGFloat)width{\n    CGRect   rc = self.frame;\n    rc.size.width = width;\n    self.frame = rc;\n}\n\n- (void)setHeight:(CGFloat)height{\n    CGRect   rc = self.frame;\n    rc.size.height = height;\n    self.frame = rc;\n}\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/ViewController.h",
    "content": "//\n//  ViewController.h\n//  WHC_FileDownloadDemo\n//\n//  Created by 吴海超 on 15/7/27.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import <UIKit/UIKit.h>\n\n@interface ViewController : UIViewController\n\n\n@end\n\n"
  },
  {
    "path": "WHCNetWorkKit Example/ViewController.m",
    "content": "//\n//  ViewController.m\n//  WHC_FileDownloadDemo\n//\n//  Created by 吴海超 on 15/7/27.\n//  Copyright (c) 2015年 吴海超. All rights reserved.\n//\n\n/*\n *  qq:712641411\n *  iOSqq群:302157745\n *  gitHub:https://github.com/netyouli\n *  csdn:http://blog.csdn.net/windwhc/article/category/3117381\n */\n\n#import \"ViewController.h\"\n#import \"WHC_OffLineVideoVC.h\"\n#import \"UIView+WHC_Toast.h\"\n#import \"UIView+WHC_Loading.h\"\n#import \"UIScrollView+WHC_PullRefresh.h\"\n#import \"AppDelegate.h\"\n\n#import \"WHC_DownloadObject.h\"\n\n@import WHCNetWorkKit;\n\n#import <WHCNetWorkKit/WHC_HttpManager.h>\n#import <WHCNetWorkKit/UIButton+WHC_HttpButton.h>\n#import <WHCNetWorkKit/UIImageView+WHC_HttpImageView.h>\n\n#define kWHC_CellName             (@\"WHC：视频下载文件\")\n#define kWHC_DefaultDownloadUrl   (@\"http://dlsw.baidu.com/sw-search-sp/soft/3b/29082/ykkhdmacb0.9.1438938315.dmg\")\n\n\n@interface ViewController ()<WHC_PullRefreshDelegate>{\n    NSMutableArray  *  _fileNameArr;\n}\n@property (nonatomic , strong)IBOutlet UITableView * downloadTv;\n@end\n\n@implementation ViewController\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    [self initData];\n    [self layoutUI];\n    // Do any additional setup after loading the view, typically from a nib.\n}\n\n- (void)initData {\n    _fileNameArr = [NSMutableArray array];\n    for (NSInteger i = 0; i < 200 ; i++) {\n        [_fileNameArr addObject:[NSString stringWithFormat:@\"%@%d    (%@)\",kWHC_CellName,(int)i + 1,@\"单击下载视频文件\"]];\n    }\n}\n\n- (void)layoutUI{\n    self.navigationItem.title = @\"iOS专业级文件下载解决方案\";\n    UIBarButtonItem * rightItem = [[UIBarButtonItem alloc]initWithTitle:@\"离线视频中心\" style:UIBarButtonItemStylePlain target:self action:@selector(clickRightItem:)];\n    self.navigationItem.rightBarButtonItem = rightItem;\n    [_downloadTv setWHCRefreshStyle:AllStyle delegate:self];\n}\n\n- (void)clickRightItem:(UIBarButtonItem *)sender{\n    [self.navigationController pushViewController:[WHC_OffLineVideoVC new] animated:YES];\n}\n\n- (void)didReceiveMemoryWarning {\n    [super didReceiveMemoryWarning];\n    // Dispose of any resources that can be recreated.\n}\n\n- (void)alert:(NSString *)msg{\n    UIAlertView  * alert = [[UIAlertView alloc]initWithTitle:msg message:nil delegate:nil cancelButtonTitle:@\"确定\" otherButtonTitles:nil, nil];\n    [alert show];\n}\n\n#pragma mark - 上拉下拉刷新代理\n\n//上拉刷新回调\n- (void)WHCUpPullRequest{\n    double delayInSeconds = 2.0;\n    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));\n    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){\n        NSInteger count = _fileNameArr.count - 1;\n        for (NSInteger i = count; i < count + 3; i++) {\n            [_fileNameArr addObject:[NSString stringWithFormat:@\"%@%d    (%@)\",kWHC_CellName,(int)i + 1,@\"单击下载视频文件\"]];\n        }\n        [_downloadTv WHCDidCompletedWithRefreshIsDownPull:NO];\n        [_downloadTv reloadData];\n    });\n\n}\n\n//下拉刷新回调\n- (void)WHCDownPullRequest{\n    double delayInSeconds = 2.0;\n    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));\n    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){\n        NSInteger count = _fileNameArr.count - 1;\n        for (NSInteger i = count; i > count - 3; i--) {\n            [_fileNameArr removeObjectAtIndex:i];\n        }\n        [_downloadTv WHCDidCompletedWithRefreshIsDownPull:YES];\n        [_downloadTv reloadData];\n    });\n\n}\n- (void)viewDidAppear:(BOOL)animated {\n    [super viewDidAppear:animated];\n}\n\n#pragma mark - 列表代理方法\n#pragma mark - UITableViewDelegate UITableViewDataSource\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{\n    return 50.0;\n}\n\n- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{\n    return [UIView new];\n}\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{\n    return _fileNameArr.count;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{\n    UITableViewCell  * cell = [tableView dequeueReusableCellWithIdentifier:kWHC_CellName];\n    if(cell == nil){\n        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kWHC_CellName];\n    }\n    cell.textLabel.font = [UIFont systemFontOfSize:14.0];\n    cell.textLabel.text = _fileNameArr[indexPath.row];\n    return cell;\n}\n\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{\n    [tableView deselectRowAtIndexPath:indexPath animated:NO];\n    NSString * suffix = [[WHC_HttpManager shared] fileFormatWithUrl:kWHC_DefaultDownloadUrl];\n    NSString * fileName = [NSString stringWithFormat:@\"%@%@\",\n                           _fileNameArr[indexPath.row],\n                           suffix != nil ? suffix : @\".dmg\"];\n    __weak typeof(self) weakSelf = self;\n#if WHC_BackgroundDownload\n    [[WHC_SessionDownloadManager shared] setBundleIdentifier:@\"com.WHC.WHCNetWorkKit.backgroundsession\"];\n    WHC_DownloadSessionTask * downloadTask = [[WHC_SessionDownloadManager shared]\n          download:kWHC_DefaultDownloadUrl\n          savePath:[WHC_DownloadObject videoDirectory]\n      saveFileName:fileName\n          response:^(WHC_BaseOperation *operation, NSError *error, BOOL isOK) {\n          } process:^(WHC_BaseOperation *operation, uint64_t recvLength, uint64_t totalLength, NSString *speed) {\n              WHC_DownloadOperation * downloadOperation = (WHC_DownloadOperation*)operation;\n              if (![WHC_DownloadObject existLocalSavePath:downloadOperation.saveFileName]) {\n                  WHC_DownloadObject * downloadObject = [WHC_DownloadObject new];\n                  [weakSelf.view toast:@\"已经添加到下载队列\"];\n                  downloadObject.fileName = downloadOperation.saveFileName;\n                  downloadObject.downloadPath = downloadOperation.strUrl;\n                  downloadObject.downloadState = WHCDownloading;\n                  downloadObject.currentDownloadLenght = downloadOperation.recvDataLenght;\n                  downloadObject.totalLenght = downloadOperation.fileTotalLenght;\n                  [downloadObject writeDiskCache];\n              }\n              NSLog(@\"recvLength = %llu , totalLength = %llu , speed = %@\",recvLength , totalLength , speed);\n          } didFinished:^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n              if (isSuccess) {\n                  [weakSelf.view toast:@\"下载成功\"];\n                  [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n              }else {\n                  [weakSelf.view toast:error.userInfo[NSLocalizedDescriptionKey]];\n                  if (error != nil &&\n                      error.code == WHCCancelDownloadError) {\n                      [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                  }\n              }\n          }];\n\n#else\n    WHC_DownloadOperation * downloadTask = nil;\n    downloadTask = [[WHC_HttpManager shared] download:kWHC_DefaultDownloadUrl\n         savePath:[WHC_DownloadObject videoDirectory]\n     saveFileName:fileName\n         response:^(WHC_BaseOperation *operation, NSError *error, BOOL isOK) {\n             if (isOK) {\n                 \n                 WHC_DownloadOperation * downloadOperation = (WHC_DownloadOperation*)operation;\n                 WHC_DownloadObject * downloadObject = [WHC_DownloadObject readDiskCache:downloadOperation.saveFileName];\n                 if (downloadObject == nil) {\n                     [weakSelf.view toast:@\"已经添加到下载队列\"];\n                     downloadObject = [WHC_DownloadObject new];\n                 }\n                 downloadObject.fileName = downloadOperation.saveFileName;\n                 downloadObject.downloadPath = downloadOperation.strUrl;\n                 downloadObject.downloadState = WHCDownloading;\n                 downloadObject.currentDownloadLenght = downloadOperation.recvDataLenght;\n                 downloadObject.totalLenght = downloadOperation.fileTotalLenght;\n                 [downloadObject writeDiskCache];\n             }else {\n                 [weakSelf errorHandle:(WHC_DownloadOperation *)operation error:error];\n             }\n         } process:^(WHC_BaseOperation *operation, uint64_t recvLength, uint64_t totalLength, NSString *speed) {\n             NSLog(@\"recvLength = %llu totalLength = %llu speed = %@\",recvLength , totalLength , speed);\n         } didFinished:^(WHC_BaseOperation *operation, NSData *data, NSError *error, BOOL isSuccess) {\n             if (isSuccess) {\n                 [weakSelf.view toast:@\"下载成功\"];\n                 [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n             }else {\n                  [weakSelf errorHandle:(WHC_DownloadOperation *)operation error:error];\n                 if (error != nil &&\n                     error.code == WHCCancelDownloadError) {\n                     [weakSelf saveDownloadStateOperation:(WHC_DownloadOperation *)operation];\n                 }\n             }\n         }];\n\n    #endif\n    if (downloadTask.requestStatus == WHCHttpRequestNone) {\n#if WHC_BackgroundDownload \n        if (![[WHC_SessionDownloadManager shared] waitingDownload]) {\n            return;\n        }\n#else\n        if (![[WHC_HttpManager shared] waitingDownload]) {\n            return;\n        }\n#endif\n        WHC_DownloadObject * downloadObject = [WHC_DownloadObject readDiskCache:downloadTask.saveFileName];\n        if (downloadObject == nil) {\n            [weakSelf.view toast:@\"已经添加到下载队列\"];\n            downloadObject = [WHC_DownloadObject new];\n            downloadObject.fileName = fileName;\n            downloadObject.downloadPath = kWHC_DefaultDownloadUrl;\n            downloadObject.downloadState = WHCDownloadWaitting;\n            downloadObject.currentDownloadLenght = 0;\n            downloadObject.totalLenght = 0;\n            [downloadObject writeDiskCache];\n        }\n    }\n}\n\n- (void)saveDownloadStateOperation:(WHC_DownloadOperation *)operation {\n    WHC_DownloadObject * downloadObject = [WHC_DownloadObject readDiskCache:operation.strUrl];\n    if (downloadObject != nil) {\n        downloadObject.currentDownloadLenght = operation.recvDataLenght;\n        downloadObject.totalLenght = operation.fileTotalLenght;\n        [downloadObject writeDiskCache];\n    }\n}\n\n- (void) errorHandle:(WHC_DownloadOperation *)operation error:(NSError *)error {\n    NSString * errInfo = error.userInfo[NSLocalizedDescriptionKey];\n    if ([errInfo containsString:@\"404\"]) {\n        [self.view toast:@\"该文件不存在\"];\n        WHC_DownloadObject * downloadObject = [WHC_DownloadObject readDiskCache:operation.strUrl];\n        if (downloadObject != nil) {\n            [downloadObject removeFromDisk];\n        }\n    }else {\n        if ([errInfo containsString:@\"已经在下载中\"]) {\n            [self.view toast:errInfo];\n        }else {\n            [self.view toast:@\"下载失败\"];\n        }\n    }\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/ViewController.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"7706\" systemVersion=\"14C109\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"7703\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"ViewController\">\n            <connections>\n                <outlet property=\"downloadTv\" destination=\"WpT-kU-mS8\" id=\"dyC-vi-jDK\"/>\n                <outlet property=\"view\" destination=\"iN0-l3-epB\" id=\"j5j-UF-GxV\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <tableView clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"44\" sectionHeaderHeight=\"22\" sectionFooterHeight=\"1\" id=\"WpT-kU-mS8\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"320\" height=\"480\"/>\n                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                    <connections>\n                        <outlet property=\"dataSource\" destination=\"-1\" id=\"8tS-fr-pac\"/>\n                        <outlet property=\"delegate\" destination=\"-1\" id=\"UBg-zo-6jM\"/>\n                    </connections>\n                </tableView>\n            </subviews>\n            <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n            <simulatedScreenMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"353\" y=\"411\"/>\n        </view>\n    </objects>\n    <simulatedMetricsContainer key=\"defaultSimulatedMetrics\">\n        <simulatedStatusBarMetrics key=\"statusBar\"/>\n        <simulatedOrientationMetrics key=\"orientation\"/>\n        <simulatedScreenMetrics key=\"destination\" type=\"retina4\"/>\n    </simulatedMetricsContainer>\n</document>\n"
  },
  {
    "path": "WHCNetWorkKit Example/WHC_DownloadObject.h",
    "content": "//\n//  WHC_DownloadObject.h\n//  WHC_FileDownloadDemo\n//\n//  Created by 吴海超 on 15/11/27.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef NS_OPTIONS(NSUInteger, WHCDownloadState) {\n    WHCNone = 1 << 0,\n    WHCDownloading = 1 << 1,\n    WHCDownloadCompleted = 1 << 2,\n    WHCDownloadCanceled = 1 << 3,\n    WHCDownloadWaitting = 1 << 4\n};\n\n@interface WHC_DownloadObject : NSObject<NSCoding>\n\n@property (nonatomic , copy) NSString * fileName;\n@property (nonatomic , copy) NSString * downloadSpeed;\n@property (nonatomic , copy) NSString * downloadPath;\n@property (nonatomic , assign) UInt64 totalLenght;\n@property (nonatomic , assign) UInt64 currentDownloadLenght;\n@property (nonatomic , assign , readonly) float downloadProcessValue;\n@property (nonatomic , assign) WHCDownloadState downloadState;\n@property (nonatomic , copy , readonly)NSString * currentDownloadLenghtToString;\n@property (nonatomic , copy , readonly)NSString * totalLenghtToString;\n@property (nonatomic , copy , readonly)NSString * downloadProcessText;\n@property (nonatomic , copy) NSString * etag;\n+ (NSString *)cacheDirectory;\n+ (NSString *)cachePlistDirectory;\n+ (NSString *)cachePlistPath;\n+ (NSString *)videoDirectory;\n\n+ (WHC_DownloadObject *)readDiskCache:(NSString *)downloadPath;\n\n+ (NSArray *)readDiskAllCache;\n\n- (void)writeDiskCache;\n\n- (void)removeFromDisk;\n\n+ (BOOL)existLocalSavePath:(NSString *)downloadPath;\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/WHC_DownloadObject.m",
    "content": "//\n//  WHC_DownloadObject.m\n//  WHC_FileDownloadDemo\n//\n//  Created by 吴海超 on 15/11/27.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import \"WHC_DownloadObject.h\"\n#import <CommonCrypto/CommonDigest.h>\nconst static double k1MB = 1024 * 1024;\n\n@implementation WHC_DownloadObject \n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _downloadSpeed = @\"0KB/s\";\n        _downloadState = WHCNone;\n    }\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)aCoder {\n    [aCoder encodeObject:_etag forKey:@\"etag\"];\n    [aCoder encodeObject:_fileName forKey:@\"fileName\"];\n    [aCoder encodeObject:_downloadPath forKey:@\"downloadPath\"];\n    [aCoder encodeInt64:_totalLenght forKey:@\"totalLenght\"];\n    [aCoder encodeInt64:_currentDownloadLenght forKey:@\"currentDownloadLenght\"];\n}\n- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {\n    self = [super init];\n    if (self) {\n        _etag = [aDecoder decodeObjectForKey:@\"fileName\"];\n        _downloadSpeed = @\"0KB/s\";\n        _fileName = [aDecoder decodeObjectForKey:@\"fileName\"];\n        _downloadPath = [aDecoder decodeObjectForKey:@\"downloadPath\"];\n        _currentDownloadLenght = [aDecoder decodeInt64ForKey:@\"currentDownloadLenght\"];\n        _totalLenght = [aDecoder decodeInt64ForKey:@\"totalLenght\"];\n        _downloadState = _totalLenght != 0 ? (self.currentDownloadLenght == self.totalLenght ? WHCDownloadCompleted : WHCDownloadCanceled) : WHCNone;\n    }\n    return self;\n}\n\n+ (NSString *)cacheDirectory {\n    return [NSString stringWithFormat:@\"%@/Library/Caches/WHCDownloadObjectCache/\",NSHomeDirectory()];\n}\n\n+ (NSString *)cachePlistDirectory {\n    return [NSString stringWithFormat:@\"%@/Library/Caches/WHCCachePlistDirectory/\",NSHomeDirectory()];\n}\n\n+ (NSString *)cachePlistPath {\n    return [NSString stringWithFormat:@\"%@WHCDownloadCache.plist\",[WHC_DownloadObject cachePlistDirectory]];\n}\n\n+ (NSString *)videoDirectory {\n    return [NSString stringWithFormat:@\"%@/Library/Caches/WHCVideos/\",NSHomeDirectory()];\n}\n\n+ (WHC_DownloadObject *)readDiskCache:(NSString *)downloadPath {\n    return [NSKeyedUnarchiver unarchiveObjectWithFile:[WHC_DownloadObject getCachedFileName:downloadPath]];\n}\n\n+ (BOOL)existLocalSavePath:(NSString *)downloadPath {\n    NSFileManager * fm = [NSFileManager defaultManager];\n    BOOL isDirectory = NO;\n    return [fm fileExistsAtPath:[WHC_DownloadObject getCachedFileName:downloadPath] isDirectory:&isDirectory];\n}\n\n+ (NSArray *)readDiskAllCache {\n    NSMutableArray * downloadObjectArr = [NSMutableArray array];\n    NSMutableDictionary * cacheDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:[WHC_DownloadObject cachePlistPath]];\n    if (cacheDictionary != nil) {\n        NSArray * allKeys = [cacheDictionary allKeys];\n        for (NSString * path in allKeys) {\n            [downloadObjectArr addObject:[WHC_DownloadObject readDiskCache:path]];\n        }\n    }\n    return downloadObjectArr;\n}\n\n+ (NSString *)getCachedFileName:(NSString *)name {\n    NSMutableString * cachedFileName = [NSMutableString string];\n    if (name != nil) {\n        const char * cStr = name.UTF8String;\n        unsigned char buffer[CC_MD5_DIGEST_LENGTH];\n        memset(buffer, 0x00, CC_MD5_DIGEST_LENGTH);\n        CC_MD5(cStr, (CC_LONG)(strlen(cStr)), buffer);\n        for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {\n            [cachedFileName appendFormat:@\"%02x\",buffer[i]];\n        }\n        return [NSString stringWithFormat:@\"%@%@\",[WHC_DownloadObject cacheDirectory],cachedFileName];\n    }\n    return [NSString stringWithFormat:@\"%@WHC\",[WHC_DownloadObject cacheDirectory]];\n}\n\n- (float)downloadProcessValue {\n    return (double)_currentDownloadLenght / ((double)_totalLenght == 0 ? 1 : _totalLenght);\n}\n\n- (NSString *)currentDownloadLenghtToString {\n    return [NSString stringWithFormat:@\"%.1fMB\",(double)_currentDownloadLenght / k1MB];\n}\n\n- (NSString *)totalLenghtToString {\n    return [NSString stringWithFormat:@\"%.1fMB\",(double)_totalLenght / k1MB];\n}\n\n- (NSString *)downloadProcessText {\n    return [NSString stringWithFormat:@\"%@/%@\",self.totalLenghtToString , self.currentDownloadLenghtToString];\n}\n\n- (void)createCacheDirectory:(NSString *)path {\n    NSFileManager * fm = [NSFileManager defaultManager];\n    BOOL isDirectory = YES;\n    if (![fm fileExistsAtPath:path isDirectory:&isDirectory]) {\n        [fm createDirectoryAtPath:path\n      withIntermediateDirectories:YES\n                       attributes:@{NSFileProtectionKey:NSFileProtectionNone} error:nil];\n    }\n}\n\n- (void)writeDiskCache {\n    if (_downloadPath != nil) {\n        [self createCacheDirectory:[WHC_DownloadObject cacheDirectory]];\n        [NSKeyedArchiver archiveRootObject:self\n                                    toFile:[WHC_DownloadObject getCachedFileName:_fileName]];//_downloadPath\n        [self createCacheDirectory:[WHC_DownloadObject cachePlistDirectory]];\n        NSMutableDictionary * cacheDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:[WHC_DownloadObject cachePlistPath]];\n        if (cacheDictionary == nil) {\n            cacheDictionary = [NSMutableDictionary dictionary];\n        }\n        [cacheDictionary setObject:@\"WHC\" forKey:_fileName];//_downloadPath\n        [cacheDictionary writeToFile:[WHC_DownloadObject cachePlistPath] atomically:YES];\n    }\n}\n\n- (void)removeFromDisk {\n    NSFileManager * fm = [NSFileManager defaultManager];\n    if ([fm fileExistsAtPath:[WHC_DownloadObject getCachedFileName:_fileName]]) {//_downloadPath\n        [fm removeItemAtPath:[WHC_DownloadObject getCachedFileName:_fileName] error:nil];//_downloadPath\n        NSMutableDictionary * cacheDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:[WHC_DownloadObject cachePlistPath]];\n        if (cacheDictionary != nil) {\n            [cacheDictionary removeObjectForKey:_fileName];//_downloadPath\n            [cacheDictionary writeToFile:[WHC_DownloadObject cachePlistPath] atomically:YES];\n        }\n        if ([fm fileExistsAtPath:[NSString stringWithFormat:@\"%@%@\",[WHC_DownloadObject videoDirectory],_fileName]]) {\n            [fm removeItemAtPath:[NSString stringWithFormat:@\"%@%@\",[WHC_DownloadObject videoDirectory],_fileName] error:nil];\n        }\n    }\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit Example/main.m",
    "content": "//\n//  main.m\n//  WHCNetWorkKit Example\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tC3A7FC1F1C1BFAA300C3EAE0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C3A7FC1E1C1BFAA300C3EAE0 /* ViewController.m */; };\n\t\tC3FFA98A1C1BCD7B00C08B80 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9891C1BCD7B00C08B80 /* main.m */; };\n\t\tC3FFA98D1C1BCD7B00C08B80 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA98C1C1BCD7B00C08B80 /* AppDelegate.m */; };\n\t\tC3FFA9951C1BCD7B00C08B80 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3FFA9941C1BCD7B00C08B80 /* Assets.xcassets */; };\n\t\tC3FFA9981C1BCD7B00C08B80 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C3FFA9961C1BCD7B00C08B80 /* LaunchScreen.storyboard */; };\n\t\tC3FFA9A31C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9A21C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleTests.m */; };\n\t\tC3FFA9AE1C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9AD1C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleUITests.m */; };\n\t\tC3FFA9BC1C1BD09300C08B80 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3FFA9BB1C1BD09300C08B80 /* ViewController.xib */; };\n\t\tC3FFA9D61C1BD10900C08B80 /* WHC_FillScreenPlayerVC.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9C61C1BD10900C08B80 /* WHC_FillScreenPlayerVC.m */; };\n\t\tC3FFA9D71C1BD10900C08B80 /* WHC_OffLineVideoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3FFA9C71C1BD10900C08B80 /* WHC_OffLineVideoCell.xib */; };\n\t\tC3FFA9D81C1BD10900C08B80 /* WHC_OffLineVideoVC.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9C91C1BD10900C08B80 /* WHC_OffLineVideoVC.m */; };\n\t\tC3FFA9D91C1BD10900C08B80 /* WHC_OffLineVideoVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = C3FFA9CA1C1BD10900C08B80 /* WHC_OffLineVideoVC.xib */; };\n\t\tC3FFA9DA1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9CD1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.m */; };\n\t\tC3FFA9DB1C1BD10900C08B80 /* UIView+WHC_Loading.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9CF1C1BD10900C08B80 /* UIView+WHC_Loading.m */; };\n\t\tC3FFA9DC1C1BD10900C08B80 /* UIView+WHC_Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9D11C1BD10900C08B80 /* UIView+WHC_Toast.m */; };\n\t\tC3FFA9DD1C1BD10900C08B80 /* UIView+WHC_ViewProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9D31C1BD10900C08B80 /* UIView+WHC_ViewProperty.m */; };\n\t\tC3FFA9DE1C1BD10900C08B80 /* WHC_DownloadObject.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9D51C1BD10900C08B80 /* WHC_DownloadObject.m */; };\n\t\tC3FFA9E01C1BDDF300C08B80 /* WHCNetWorkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3FFA9DF1C1BDDF300C08B80 /* WHCNetWorkKit.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tC3FFA99F1C1BCD7B00C08B80 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = C3FFA97D1C1BCD7B00C08B80 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = C3FFA9841C1BCD7B00C08B80;\n\t\t\tremoteInfo = \"WHCNetWorkKit Example\";\n\t\t};\n\t\tC3FFA9AA1C1BCD7B00C08B80 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = C3FFA97D1C1BCD7B00C08B80 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = C3FFA9841C1BCD7B00C08B80;\n\t\t\tremoteInfo = \"WHCNetWorkKit Example\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tC3A7FC1E1C1BFAA300C3EAE0 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9851C1BCD7B00C08B80 /* WHCNetWorkKit Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"WHCNetWorkKit Example.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC3FFA9891C1BCD7B00C08B80 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\tC3FFA98B1C1BCD7B00C08B80 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\tC3FFA98C1C1BCD7B00C08B80 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\tC3FFA98E1C1BCD7B00C08B80 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9941C1BCD7B00C08B80 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tC3FFA9971C1BCD7B00C08B80 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tC3FFA9991C1BCD7B00C08B80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tC3FFA99E1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"WHCNetWorkKit ExampleTests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC3FFA9A21C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WHCNetWorkKit_ExampleTests.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9A41C1BCD7B00C08B80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tC3FFA9A91C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"WHCNetWorkKit ExampleUITests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC3FFA9AD1C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WHCNetWorkKit_ExampleUITests.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9AF1C1BCD7B00C08B80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tC3FFA9BB1C1BD09300C08B80 /* ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ViewController.xib; sourceTree = \"<group>\"; };\n\t\tC3FFA9C51C1BD10900C08B80 /* WHC_FillScreenPlayerVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_FillScreenPlayerVC.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9C61C1BD10900C08B80 /* WHC_FillScreenPlayerVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_FillScreenPlayerVC.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9C71C1BD10900C08B80 /* WHC_OffLineVideoCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WHC_OffLineVideoCell.xib; sourceTree = \"<group>\"; };\n\t\tC3FFA9C81C1BD10900C08B80 /* WHC_OffLineVideoVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_OffLineVideoVC.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9C91C1BD10900C08B80 /* WHC_OffLineVideoVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_OffLineVideoVC.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9CA1C1BD10900C08B80 /* WHC_OffLineVideoVC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WHC_OffLineVideoVC.xib; sourceTree = \"<group>\"; };\n\t\tC3FFA9CC1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIScrollView+WHC_PullRefresh.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9CD1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIScrollView+WHC_PullRefresh.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9CE1C1BD10900C08B80 /* UIView+WHC_Loading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIView+WHC_Loading.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9CF1C1BD10900C08B80 /* UIView+WHC_Loading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIView+WHC_Loading.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9D01C1BD10900C08B80 /* UIView+WHC_Toast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIView+WHC_Toast.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9D11C1BD10900C08B80 /* UIView+WHC_Toast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIView+WHC_Toast.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9D21C1BD10900C08B80 /* UIView+WHC_ViewProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIView+WHC_ViewProperty.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9D31C1BD10900C08B80 /* UIView+WHC_ViewProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIView+WHC_ViewProperty.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9D41C1BD10900C08B80 /* WHC_DownloadObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_DownloadObject.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9D51C1BD10900C08B80 /* WHC_DownloadObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_DownloadObject.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9DF1C1BDDF300C08B80 /* WHCNetWorkKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WHCNetWorkKit.framework; path = \"../WHCNetWorkKit/build/Debug-iphoneos/WHCNetWorkKit.framework\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tC3FFA9821C1BCD7B00C08B80 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9E01C1BDDF300C08B80 /* WHCNetWorkKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA99B1C1BCD7B00C08B80 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA9A61C1BCD7B00C08B80 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tC3FFA97C1C1BCD7B00C08B80 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9DF1C1BDDF300C08B80 /* WHCNetWorkKit.framework */,\n\t\t\t\tC3FFA9871C1BCD7B00C08B80 /* WHCNetWorkKit Example */,\n\t\t\t\tC3FFA9A11C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests */,\n\t\t\t\tC3FFA9AC1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests */,\n\t\t\t\tC3FFA9861C1BCD7B00C08B80 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9861C1BCD7B00C08B80 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9851C1BCD7B00C08B80 /* WHCNetWorkKit Example.app */,\n\t\t\t\tC3FFA99E1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests.xctest */,\n\t\t\t\tC3FFA9A91C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9871C1BCD7B00C08B80 /* WHCNetWorkKit Example */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9C41C1BD10900C08B80 /* UI */,\n\t\t\t\tC3FFA9CB1C1BD10900C08B80 /* UIUnitCore */,\n\t\t\t\tC3FFA9D41C1BD10900C08B80 /* WHC_DownloadObject.h */,\n\t\t\t\tC3FFA9D51C1BD10900C08B80 /* WHC_DownloadObject.m */,\n\t\t\t\tC3FFA98B1C1BCD7B00C08B80 /* AppDelegate.h */,\n\t\t\t\tC3FFA98C1C1BCD7B00C08B80 /* AppDelegate.m */,\n\t\t\t\tC3FFA98E1C1BCD7B00C08B80 /* ViewController.h */,\n\t\t\t\tC3A7FC1E1C1BFAA300C3EAE0 /* ViewController.m */,\n\t\t\t\tC3FFA9BB1C1BD09300C08B80 /* ViewController.xib */,\n\t\t\t\tC3FFA9941C1BCD7B00C08B80 /* Assets.xcassets */,\n\t\t\t\tC3FFA9961C1BCD7B00C08B80 /* LaunchScreen.storyboard */,\n\t\t\t\tC3FFA9991C1BCD7B00C08B80 /* Info.plist */,\n\t\t\t\tC3FFA9881C1BCD7B00C08B80 /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = \"WHCNetWorkKit Example\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9881C1BCD7B00C08B80 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9891C1BCD7B00C08B80 /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9A11C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9A21C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleTests.m */,\n\t\t\t\tC3FFA9A41C1BCD7B00C08B80 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = \"WHCNetWorkKit ExampleTests\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9AC1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9AD1C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleUITests.m */,\n\t\t\t\tC3FFA9AF1C1BCD7B00C08B80 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = \"WHCNetWorkKit ExampleUITests\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9C41C1BD10900C08B80 /* UI */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9C51C1BD10900C08B80 /* WHC_FillScreenPlayerVC.h */,\n\t\t\t\tC3FFA9C61C1BD10900C08B80 /* WHC_FillScreenPlayerVC.m */,\n\t\t\t\tC3FFA9C71C1BD10900C08B80 /* WHC_OffLineVideoCell.xib */,\n\t\t\t\tC3FFA9C81C1BD10900C08B80 /* WHC_OffLineVideoVC.h */,\n\t\t\t\tC3FFA9C91C1BD10900C08B80 /* WHC_OffLineVideoVC.m */,\n\t\t\t\tC3FFA9CA1C1BD10900C08B80 /* WHC_OffLineVideoVC.xib */,\n\t\t\t);\n\t\t\tpath = UI;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9CB1C1BD10900C08B80 /* UIUnitCore */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9CC1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.h */,\n\t\t\t\tC3FFA9CD1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.m */,\n\t\t\t\tC3FFA9CE1C1BD10900C08B80 /* UIView+WHC_Loading.h */,\n\t\t\t\tC3FFA9CF1C1BD10900C08B80 /* UIView+WHC_Loading.m */,\n\t\t\t\tC3FFA9D01C1BD10900C08B80 /* UIView+WHC_Toast.h */,\n\t\t\t\tC3FFA9D11C1BD10900C08B80 /* UIView+WHC_Toast.m */,\n\t\t\t\tC3FFA9D21C1BD10900C08B80 /* UIView+WHC_ViewProperty.h */,\n\t\t\t\tC3FFA9D31C1BD10900C08B80 /* UIView+WHC_ViewProperty.m */,\n\t\t\t);\n\t\t\tpath = UIUnitCore;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tC3FFA9841C1BCD7B00C08B80 /* WHCNetWorkKit Example */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C3FFA9B21C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit Example\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC3FFA9811C1BCD7B00C08B80 /* Sources */,\n\t\t\t\tC3FFA9821C1BCD7B00C08B80 /* Frameworks */,\n\t\t\t\tC3FFA9831C1BCD7B00C08B80 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"WHCNetWorkKit Example\";\n\t\t\tproductName = \"WHCNetWorkKit Example\";\n\t\t\tproductReference = C3FFA9851C1BCD7B00C08B80 /* WHCNetWorkKit Example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\tC3FFA99D1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C3FFA9B51C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit ExampleTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC3FFA99A1C1BCD7B00C08B80 /* Sources */,\n\t\t\t\tC3FFA99B1C1BCD7B00C08B80 /* Frameworks */,\n\t\t\t\tC3FFA99C1C1BCD7B00C08B80 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tC3FFA9A01C1BCD7B00C08B80 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"WHCNetWorkKit ExampleTests\";\n\t\t\tproductName = \"WHCNetWorkKit ExampleTests\";\n\t\t\tproductReference = C3FFA99E1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tC3FFA9A81C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C3FFA9B81C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit ExampleUITests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC3FFA9A51C1BCD7B00C08B80 /* Sources */,\n\t\t\t\tC3FFA9A61C1BCD7B00C08B80 /* Frameworks */,\n\t\t\t\tC3FFA9A71C1BCD7B00C08B80 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tC3FFA9AB1C1BCD7B00C08B80 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"WHCNetWorkKit ExampleUITests\";\n\t\t\tproductName = \"WHCNetWorkKit ExampleUITests\";\n\t\t\tproductReference = C3FFA9A91C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.ui-testing\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tC3FFA97D1C1BCD7B00C08B80 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0710;\n\t\t\t\tORGANIZATIONNAME = \"吴海超\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tC3FFA9841C1BCD7B00C08B80 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1.1;\n\t\t\t\t\t};\n\t\t\t\t\tC3FFA99D1C1BCD7B00C08B80 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1.1;\n\t\t\t\t\t\tTestTargetID = C3FFA9841C1BCD7B00C08B80;\n\t\t\t\t\t};\n\t\t\t\t\tC3FFA9A81C1BCD7B00C08B80 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1.1;\n\t\t\t\t\t\tTestTargetID = C3FFA9841C1BCD7B00C08B80;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = C3FFA9801C1BCD7B00C08B80 /* Build configuration list for PBXProject \"WHCNetWorkKit Example\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = C3FFA97C1C1BCD7B00C08B80;\n\t\t\tproductRefGroup = C3FFA9861C1BCD7B00C08B80 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tC3FFA9841C1BCD7B00C08B80 /* WHCNetWorkKit Example */,\n\t\t\t\tC3FFA99D1C1BCD7B00C08B80 /* WHCNetWorkKit ExampleTests */,\n\t\t\t\tC3FFA9A81C1BCD7B00C08B80 /* WHCNetWorkKit ExampleUITests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tC3FFA9831C1BCD7B00C08B80 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9D91C1BD10900C08B80 /* WHC_OffLineVideoVC.xib in Resources */,\n\t\t\t\tC3FFA9D71C1BD10900C08B80 /* WHC_OffLineVideoCell.xib in Resources */,\n\t\t\t\tC3FFA9981C1BCD7B00C08B80 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\tC3FFA9BC1C1BD09300C08B80 /* ViewController.xib in Resources */,\n\t\t\t\tC3FFA9951C1BCD7B00C08B80 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA99C1C1BCD7B00C08B80 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA9A71C1BCD7B00C08B80 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tC3FFA9811C1BCD7B00C08B80 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9D61C1BD10900C08B80 /* WHC_FillScreenPlayerVC.m in Sources */,\n\t\t\t\tC3FFA98D1C1BCD7B00C08B80 /* AppDelegate.m in Sources */,\n\t\t\t\tC3FFA9DE1C1BD10900C08B80 /* WHC_DownloadObject.m in Sources */,\n\t\t\t\tC3FFA9DA1C1BD10900C08B80 /* UIScrollView+WHC_PullRefresh.m in Sources */,\n\t\t\t\tC3A7FC1F1C1BFAA300C3EAE0 /* ViewController.m in Sources */,\n\t\t\t\tC3FFA9DB1C1BD10900C08B80 /* UIView+WHC_Loading.m in Sources */,\n\t\t\t\tC3FFA9DD1C1BD10900C08B80 /* UIView+WHC_ViewProperty.m in Sources */,\n\t\t\t\tC3FFA9DC1C1BD10900C08B80 /* UIView+WHC_Toast.m in Sources */,\n\t\t\t\tC3FFA98A1C1BCD7B00C08B80 /* main.m in Sources */,\n\t\t\t\tC3FFA9D81C1BD10900C08B80 /* WHC_OffLineVideoVC.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA99A1C1BCD7B00C08B80 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9A31C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA9A51C1BCD7B00C08B80 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9AE1C1BCD7B00C08B80 /* WHCNetWorkKit_ExampleUITests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tC3FFA9A01C1BCD7B00C08B80 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = C3FFA9841C1BCD7B00C08B80 /* WHCNetWorkKit Example */;\n\t\t\ttargetProxy = C3FFA99F1C1BCD7B00C08B80 /* PBXContainerItemProxy */;\n\t\t};\n\t\tC3FFA9AB1C1BCD7B00C08B80 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = C3FFA9841C1BCD7B00C08B80 /* WHCNetWorkKit Example */;\n\t\t\ttargetProxy = C3FFA9AA1C1BCD7B00C08B80 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tC3FFA9961C1BCD7B00C08B80 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9971C1BCD7B00C08B80 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tC3FFA9B01C1BCD7B00C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9B11C1BCD7B00C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC3FFA9B31C1BCD7B00C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit Example/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.WHC.WHCNetWorkKit;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9B41C1BCD7B00C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit Example/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.WHC.WHCNetWorkKit;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC3FFA9B61C1BCD7B00C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit ExampleTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit-ExampleTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/WHCNetWorkKit Example.app/WHCNetWorkKit Example\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9B71C1BCD7B00C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit ExampleTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit-ExampleTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/WHCNetWorkKit Example.app/WHCNetWorkKit Example\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC3FFA9B91C1BCD7B00C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit ExampleUITests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit-ExampleUITests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = \"WHCNetWorkKit Example\";\n\t\t\t\tUSES_XCTRUNNER = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9BA1C1BCD7B00C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = \"WHCNetWorkKit ExampleUITests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit-ExampleUITests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = \"WHCNetWorkKit Example\";\n\t\t\t\tUSES_XCTRUNNER = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tC3FFA9801C1BCD7B00C08B80 /* Build configuration list for PBXProject \"WHCNetWorkKit Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9B01C1BCD7B00C08B80 /* Debug */,\n\t\t\t\tC3FFA9B11C1BCD7B00C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC3FFA9B21C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9B31C1BCD7B00C08B80 /* Debug */,\n\t\t\t\tC3FFA9B41C1BCD7B00C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC3FFA9B51C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit ExampleTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9B61C1BCD7B00C08B80 /* Debug */,\n\t\t\t\tC3FFA9B71C1BCD7B00C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC3FFA9B81C1BCD7B00C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit ExampleUITests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9B91C1BCD7B00C08B80 /* Debug */,\n\t\t\t\tC3FFA9BA1C1BCD7B00C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = C3FFA97D1C1BCD7B00C08B80 /* Project object */;\n}\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:WHCNetWorkKit Example.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/WHCNetWorkKit Example.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit Example.app\"\n               BlueprintName = \"WHCNetWorkKit Example\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA99D1C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit ExampleTests.xctest\"\n               BlueprintName = \"WHCNetWorkKit ExampleTests\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9A81C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit ExampleUITests.xctest\"\n               BlueprintName = \"WHCNetWorkKit ExampleUITests\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>WHCNetWorkKit Example.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>C3FFA9841C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA99D1C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA9A81C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/WHCNetWorkKit Example.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0710\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"NO\"\n      buildImplicitDependencies = \"NO\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit Example.app\"\n               BlueprintName = \"WHCNetWorkKit Example\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA99D1C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit ExampleTests.xctest\"\n               BlueprintName = \"WHCNetWorkKit ExampleTests\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9A81C1BCD7B00C08B80\"\n               BuildableName = \"WHCNetWorkKit ExampleUITests.xctest\"\n               BlueprintName = \"WHCNetWorkKit ExampleUITests\"\n               ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9841C1BCD7B00C08B80\"\n            BuildableName = \"WHCNetWorkKit Example.app\"\n            BlueprintName = \"WHCNetWorkKit Example\"\n            ReferencedContainer = \"container:WHCNetWorkKit Example.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "WHCNetWorkKit Example.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>WHCNetWorkKit Example.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>C3FFA9841C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA99D1C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA9A81C1BCD7B00C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit ExampleTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit ExampleTests/WHCNetWorkKit_ExampleTests.m",
    "content": "//\n//  WHCNetWorkKit_ExampleTests.m\n//  WHCNetWorkKit ExampleTests\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface WHCNetWorkKit_ExampleTests : XCTestCase\n\n@end\n\n@implementation WHCNetWorkKit_ExampleTests\n\n- (void)setUp {\n    [super setUp];\n    // Put setup code here. This method is called before the invocation of each test method in the class.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // This is an example of a functional test case.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n- (void)testPerformanceExample {\n    // This is an example of a performance test case.\n    [self measureBlock:^{\n        // Put the code you want to measure the time of here.\n    }];\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit ExampleUITests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit ExampleUITests/WHCNetWorkKit_ExampleUITests.m",
    "content": "//\n//  WHCNetWorkKit_ExampleUITests.m\n//  WHCNetWorkKit ExampleUITests\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface WHCNetWorkKit_ExampleUITests : XCTestCase\n\n@end\n\n@implementation WHCNetWorkKit_ExampleUITests\n\n- (void)setUp {\n    [super setUp];\n    \n    // Put setup code here. This method is called before the invocation of each test method in the class.\n    \n    // In UI tests it is usually best to stop immediately when a failure occurs.\n    self.continueAfterFailure = NO;\n    // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.\n    [[[XCUIApplication alloc] init] launch];\n    \n    // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // Use recording to get started writing UI tests.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n@end\n"
  },
  {
    "path": "WHCNetWorkKit.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name         = 'WHCNetWorkKit'\n  s.version      = '0.0.3'\n  s.summary      = 'WHCNetWorkKit 是http网络请求开源库(支持GET/POST 文件上传 后台文件下载 UIButton UIImageView 控件设置网络图片 网络数据工具json/xml 转模型类对象 网络状态监听)'\n  s.homepage     = 'https://github.com/netyouli/WHCNetWorkKit'\n  #s.screenshots  = 'https://github.com/netyouli/WHCNetWorkKit/blob/master/show.gif'\n  s.license      = 'MIT'\n  s.author             = { '吴海超' => '712641411@qq.com' }\n  s.platform     = :ios, '7.0'\n  s.ios.deployment_target = '7.0'\n  #s.osx.deployment_target = '10.8'\n  #s.watchos.deployment_target = '2.0'\n  #s.tvos.deployment_target = '9.0'\n\n\n\n  s.source       = { :git => 'https://github.com/netyouli/WHCNetWorkKit.git', :tag => s.version, :submodules => true}\n\n  s.source_files  = 'WHCNetWorkKit/*.h'\n\n  s.public_header_files = 'WHCNetWorkKit/*.h'\n\n  s.subspec 'Reachability' do |ss|\n    ss.source_files = 'WHCNetWorkKit/Reachability/*.{h,m}'\n    ss.public_header_files = 'WHCNetWorkKit/Reachability/*.h'\n  end\n\n  s.subspec 'NSURLConnection' do |ss|\n    ss.dependency 'WHCNetWorkKit/Reachability'\n    ss.source_files = 'WHCNetWorkKit/NSURLConnection/*.{h,m}'\n    ss.public_header_files = 'WHCNetWorkKit/NSURLConnection/*.h'\n  end\n\n  s.subspec 'NSURLSession' do |ss|\n    ss.dependency 'WHCNetWorkKit/NSURLConnection'\n    ss.source_files = 'WHCNetWorkKit/NSURLSession/*.{h,m}'\n    ss.public_header_files = 'WHCNetWorkKit/NSURLSession/*.h'\n  end\n\n  s.subspec 'UIKit' do |ss|\n    ss.dependency 'WHCNetWorkKit/NSURLConnection'\n    ss.source_files = 'WHCNetWorkKit/UIKit+WHCNetWorkKit/*.{h,m}'\n    ss.public_header_files = 'WHCNetWorkKit/UIKit+WHCNetWorkKit/*.h'\n  end\n\n  s.subspec 'UtillKit' do |ss|\n    ss.source_files = 'WHCNetWorkKit/UtilKit+WHCNetWorkKit/*.{h,m}'\n    ss.public_header_files = 'WHCNetWorkKit/UtilKit+WHCNetWorkKit/*.h'\n  end\n\n  s.requires_arc = true\n\nend\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tC3A7FC231C1BFC1800C3EAE0 /* WHCNetWorkKit.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A7FC221C1BFC1800C3EAE0 /* WHCNetWorkKit.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA90D1C1BC9D900C08B80 /* WHCNetWorkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3FFA9021C1BC9D900C08B80 /* WHCNetWorkKit.framework */; };\n\t\tC3FFA9121C1BC9D900C08B80 /* WHCNetWorkKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9111C1BC9D900C08B80 /* WHCNetWorkKitTests.m */; };\n\t\tC3FFA93E1C1BCA1100C08B80 /* WHC_BaseOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA91D1C1BCA1100C08B80 /* WHC_BaseOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA93F1C1BCA1100C08B80 /* WHC_BaseOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA91E1C1BCA1100C08B80 /* WHC_BaseOperation.m */; };\n\t\tC3FFA9401C1BCA1100C08B80 /* WHC_DownloadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA91F1C1BCA1100C08B80 /* WHC_DownloadOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9411C1BCA1100C08B80 /* WHC_DownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9201C1BCA1100C08B80 /* WHC_DownloadOperation.m */; };\n\t\tC3FFA9421C1BCA1100C08B80 /* WHC_HttpManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9211C1BCA1100C08B80 /* WHC_HttpManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9431C1BCA1100C08B80 /* WHC_HttpManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9221C1BCA1100C08B80 /* WHC_HttpManager.m */; };\n\t\tC3FFA9441C1BCA1100C08B80 /* WHC_HttpOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9231C1BCA1100C08B80 /* WHC_HttpOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9451C1BCA1100C08B80 /* WHC_HttpOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9241C1BCA1100C08B80 /* WHC_HttpOperation.m */; };\n\t\tC3FFA9461C1BCA1100C08B80 /* WHC_DownloadSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9261C1BCA1100C08B80 /* WHC_DownloadSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9471C1BCA1100C08B80 /* WHC_DownloadSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9271C1BCA1100C08B80 /* WHC_DownloadSessionTask.m */; };\n\t\tC3FFA9481C1BCA1100C08B80 /* WHC_SessionDownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9281C1BCA1100C08B80 /* WHC_SessionDownloadManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9491C1BCA1100C08B80 /* WHC_SessionDownloadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9291C1BCA1100C08B80 /* WHC_SessionDownloadManager.m */; };\n\t\tC3FFA94A1C1BCA1100C08B80 /* Reachability.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA92B1C1BCA1100C08B80 /* Reachability.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA94B1C1BCA1100C08B80 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA92C1C1BCA1100C08B80 /* Reachability.m */; };\n\t\tC3FFA94C1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA92E1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA94D1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA92F1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.m */; };\n\t\tC3FFA94E1C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9301C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA94F1C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9311C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.m */; };\n\t\tC3FFA9501C1BCA1100C08B80 /* WHC_ImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9321C1BCA1100C08B80 /* WHC_ImageCache.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9511C1BCA1100C08B80 /* WHC_ImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9331C1BCA1100C08B80 /* WHC_ImageCache.m */; };\n\t\tC3FFA9741C1BCB3200C08B80 /* WHC_DataModel.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA96C1C1BCB3200C08B80 /* WHC_DataModel.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9751C1BCB3200C08B80 /* WHC_DataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA96D1C1BCB3200C08B80 /* WHC_DataModel.m */; };\n\t\tC3FFA9761C1BCB3200C08B80 /* WHC_Json.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA96E1C1BCB3200C08B80 /* WHC_Json.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9771C1BCB3200C08B80 /* WHC_Json.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA96F1C1BCB3200C08B80 /* WHC_Json.m */; };\n\t\tC3FFA9781C1BCB3200C08B80 /* WHC_Xml.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9701C1BCB3200C08B80 /* WHC_Xml.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA9791C1BCB3200C08B80 /* WHC_Xml.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9711C1BCB3200C08B80 /* WHC_Xml.m */; };\n\t\tC3FFA97A1C1BCB3200C08B80 /* WHC_XMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = C3FFA9721C1BCB3200C08B80 /* WHC_XMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tC3FFA97B1C1BCB3200C08B80 /* WHC_XMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C3FFA9731C1BCB3200C08B80 /* WHC_XMLParser.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tC3FFA90E1C1BC9D900C08B80 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = C3FFA8F91C1BC9D900C08B80 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = C3FFA9011C1BC9D900C08B80;\n\t\t\tremoteInfo = WHCNetWorkKit;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tC3A7FC221C1BFC1800C3EAE0 /* WHCNetWorkKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHCNetWorkKit.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9021C1BC9D900C08B80 /* WHCNetWorkKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WHCNetWorkKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC3FFA9071C1BC9D900C08B80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tC3FFA90C1C1BC9D900C08B80 /* WHCNetWorkKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WHCNetWorkKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC3FFA9111C1BC9D900C08B80 /* WHCNetWorkKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WHCNetWorkKitTests.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9131C1BC9D900C08B80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tC3FFA91D1C1BCA1100C08B80 /* WHC_BaseOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_BaseOperation.h; sourceTree = \"<group>\"; };\n\t\tC3FFA91E1C1BCA1100C08B80 /* WHC_BaseOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_BaseOperation.m; sourceTree = \"<group>\"; };\n\t\tC3FFA91F1C1BCA1100C08B80 /* WHC_DownloadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_DownloadOperation.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9201C1BCA1100C08B80 /* WHC_DownloadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_DownloadOperation.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9211C1BCA1100C08B80 /* WHC_HttpManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_HttpManager.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9221C1BCA1100C08B80 /* WHC_HttpManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_HttpManager.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9231C1BCA1100C08B80 /* WHC_HttpOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_HttpOperation.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9241C1BCA1100C08B80 /* WHC_HttpOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_HttpOperation.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9261C1BCA1100C08B80 /* WHC_DownloadSessionTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_DownloadSessionTask.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9271C1BCA1100C08B80 /* WHC_DownloadSessionTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_DownloadSessionTask.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9281C1BCA1100C08B80 /* WHC_SessionDownloadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_SessionDownloadManager.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9291C1BCA1100C08B80 /* WHC_SessionDownloadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_SessionDownloadManager.m; sourceTree = \"<group>\"; };\n\t\tC3FFA92B1C1BCA1100C08B80 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = \"<group>\"; };\n\t\tC3FFA92C1C1BCA1100C08B80 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = \"<group>\"; };\n\t\tC3FFA92E1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIButton+WHC_HttpButton.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA92F1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIButton+WHC_HttpButton.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9301C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIImageView+WHC_HttpImageView.h\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9311C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIImageView+WHC_HttpImageView.m\"; sourceTree = \"<group>\"; };\n\t\tC3FFA9321C1BCA1100C08B80 /* WHC_ImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_ImageCache.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9331C1BCA1100C08B80 /* WHC_ImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_ImageCache.m; sourceTree = \"<group>\"; };\n\t\tC3FFA96C1C1BCB3200C08B80 /* WHC_DataModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_DataModel.h; sourceTree = \"<group>\"; };\n\t\tC3FFA96D1C1BCB3200C08B80 /* WHC_DataModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_DataModel.m; sourceTree = \"<group>\"; };\n\t\tC3FFA96E1C1BCB3200C08B80 /* WHC_Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_Json.h; sourceTree = \"<group>\"; };\n\t\tC3FFA96F1C1BCB3200C08B80 /* WHC_Json.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_Json.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9701C1BCB3200C08B80 /* WHC_Xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_Xml.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9711C1BCB3200C08B80 /* WHC_Xml.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_Xml.m; sourceTree = \"<group>\"; };\n\t\tC3FFA9721C1BCB3200C08B80 /* WHC_XMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_XMLParser.h; sourceTree = \"<group>\"; };\n\t\tC3FFA9731C1BCB3200C08B80 /* WHC_XMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_XMLParser.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tC3FFA8FE1C1BC9D900C08B80 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA9091C1BC9D900C08B80 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA90D1C1BC9D900C08B80 /* WHCNetWorkKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tC3FFA8F81C1BC9D900C08B80 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9041C1BC9D900C08B80 /* WHCNetWorkKit */,\n\t\t\t\tC3FFA9101C1BC9D900C08B80 /* WHCNetWorkKitTests */,\n\t\t\t\tC3FFA9031C1BC9D900C08B80 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9031C1BC9D900C08B80 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9021C1BC9D900C08B80 /* WHCNetWorkKit.framework */,\n\t\t\t\tC3FFA90C1C1BC9D900C08B80 /* WHCNetWorkKitTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9041C1BC9D900C08B80 /* WHCNetWorkKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA91C1C1BCA1100C08B80 /* NSURLConnection */,\n\t\t\t\tC3FFA9251C1BCA1100C08B80 /* NSURLSession */,\n\t\t\t\tC3FFA92A1C1BCA1100C08B80 /* Reachability */,\n\t\t\t\tC3FFA92D1C1BCA1100C08B80 /* UIKit+WHCNetWorkKit */,\n\t\t\t\tC3FFA96B1C1BCB3200C08B80 /* UtilKit+WHCNetWorkKit */,\n\t\t\t\tC3FFA9071C1BC9D900C08B80 /* Info.plist */,\n\t\t\t\tC3A7FC221C1BFC1800C3EAE0 /* WHCNetWorkKit.h */,\n\t\t\t);\n\t\t\tpath = WHCNetWorkKit;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9101C1BC9D900C08B80 /* WHCNetWorkKitTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9111C1BC9D900C08B80 /* WHCNetWorkKitTests.m */,\n\t\t\t\tC3FFA9131C1BC9D900C08B80 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = WHCNetWorkKitTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA91C1C1BCA1100C08B80 /* NSURLConnection */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA91D1C1BCA1100C08B80 /* WHC_BaseOperation.h */,\n\t\t\t\tC3FFA91E1C1BCA1100C08B80 /* WHC_BaseOperation.m */,\n\t\t\t\tC3FFA91F1C1BCA1100C08B80 /* WHC_DownloadOperation.h */,\n\t\t\t\tC3FFA9201C1BCA1100C08B80 /* WHC_DownloadOperation.m */,\n\t\t\t\tC3FFA9211C1BCA1100C08B80 /* WHC_HttpManager.h */,\n\t\t\t\tC3FFA9221C1BCA1100C08B80 /* WHC_HttpManager.m */,\n\t\t\t\tC3FFA9231C1BCA1100C08B80 /* WHC_HttpOperation.h */,\n\t\t\t\tC3FFA9241C1BCA1100C08B80 /* WHC_HttpOperation.m */,\n\t\t\t);\n\t\t\tpath = NSURLConnection;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA9251C1BCA1100C08B80 /* NSURLSession */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA9261C1BCA1100C08B80 /* WHC_DownloadSessionTask.h */,\n\t\t\t\tC3FFA9271C1BCA1100C08B80 /* WHC_DownloadSessionTask.m */,\n\t\t\t\tC3FFA9281C1BCA1100C08B80 /* WHC_SessionDownloadManager.h */,\n\t\t\t\tC3FFA9291C1BCA1100C08B80 /* WHC_SessionDownloadManager.m */,\n\t\t\t);\n\t\t\tpath = NSURLSession;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA92A1C1BCA1100C08B80 /* Reachability */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA92B1C1BCA1100C08B80 /* Reachability.h */,\n\t\t\t\tC3FFA92C1C1BCA1100C08B80 /* Reachability.m */,\n\t\t\t);\n\t\t\tpath = Reachability;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA92D1C1BCA1100C08B80 /* UIKit+WHCNetWorkKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA92E1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.h */,\n\t\t\t\tC3FFA92F1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.m */,\n\t\t\t\tC3FFA9301C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.h */,\n\t\t\t\tC3FFA9311C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.m */,\n\t\t\t\tC3FFA9321C1BCA1100C08B80 /* WHC_ImageCache.h */,\n\t\t\t\tC3FFA9331C1BCA1100C08B80 /* WHC_ImageCache.m */,\n\t\t\t);\n\t\t\tpath = \"UIKit+WHCNetWorkKit\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC3FFA96B1C1BCB3200C08B80 /* UtilKit+WHCNetWorkKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC3FFA96C1C1BCB3200C08B80 /* WHC_DataModel.h */,\n\t\t\t\tC3FFA96D1C1BCB3200C08B80 /* WHC_DataModel.m */,\n\t\t\t\tC3FFA96E1C1BCB3200C08B80 /* WHC_Json.h */,\n\t\t\t\tC3FFA96F1C1BCB3200C08B80 /* WHC_Json.m */,\n\t\t\t\tC3FFA9701C1BCB3200C08B80 /* WHC_Xml.h */,\n\t\t\t\tC3FFA9711C1BCB3200C08B80 /* WHC_Xml.m */,\n\t\t\t\tC3FFA9721C1BCB3200C08B80 /* WHC_XMLParser.h */,\n\t\t\t\tC3FFA9731C1BCB3200C08B80 /* WHC_XMLParser.m */,\n\t\t\t);\n\t\t\tpath = \"UtilKit+WHCNetWorkKit\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\tC3FFA8FF1C1BC9D900C08B80 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9741C1BCB3200C08B80 /* WHC_DataModel.h in Headers */,\n\t\t\t\tC3FFA9501C1BCA1100C08B80 /* WHC_ImageCache.h in Headers */,\n\t\t\t\tC3FFA9481C1BCA1100C08B80 /* WHC_SessionDownloadManager.h in Headers */,\n\t\t\t\tC3FFA97A1C1BCB3200C08B80 /* WHC_XMLParser.h in Headers */,\n\t\t\t\tC3FFA9441C1BCA1100C08B80 /* WHC_HttpOperation.h in Headers */,\n\t\t\t\tC3FFA9401C1BCA1100C08B80 /* WHC_DownloadOperation.h in Headers */,\n\t\t\t\tC3FFA93E1C1BCA1100C08B80 /* WHC_BaseOperation.h in Headers */,\n\t\t\t\tC3FFA9781C1BCB3200C08B80 /* WHC_Xml.h in Headers */,\n\t\t\t\tC3FFA94C1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.h in Headers */,\n\t\t\t\tC3FFA9461C1BCA1100C08B80 /* WHC_DownloadSessionTask.h in Headers */,\n\t\t\t\tC3FFA94A1C1BCA1100C08B80 /* Reachability.h in Headers */,\n\t\t\t\tC3FFA9421C1BCA1100C08B80 /* WHC_HttpManager.h in Headers */,\n\t\t\t\tC3FFA94E1C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.h in Headers */,\n\t\t\t\tC3FFA9761C1BCB3200C08B80 /* WHC_Json.h in Headers */,\n\t\t\t\tC3A7FC231C1BFC1800C3EAE0 /* WHCNetWorkKit.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\tC3FFA9011C1BC9D900C08B80 /* WHCNetWorkKit */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C3FFA9161C1BC9D900C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC3FFA8FD1C1BC9D900C08B80 /* Sources */,\n\t\t\t\tC3FFA8FE1C1BC9D900C08B80 /* Frameworks */,\n\t\t\t\tC3FFA8FF1C1BC9D900C08B80 /* Headers */,\n\t\t\t\tC3FFA9001C1BC9D900C08B80 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = WHCNetWorkKit;\n\t\t\tproductName = WHCNetWorkKit;\n\t\t\tproductReference = C3FFA9021C1BC9D900C08B80 /* WHCNetWorkKit.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tC3FFA90B1C1BC9D900C08B80 /* WHCNetWorkKitTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C3FFA9191C1BC9D900C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKitTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC3FFA9081C1BC9D900C08B80 /* Sources */,\n\t\t\t\tC3FFA9091C1BC9D900C08B80 /* Frameworks */,\n\t\t\t\tC3FFA90A1C1BC9D900C08B80 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tC3FFA90F1C1BC9D900C08B80 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = WHCNetWorkKitTests;\n\t\t\tproductName = WHCNetWorkKitTests;\n\t\t\tproductReference = C3FFA90C1C1BC9D900C08B80 /* WHCNetWorkKitTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tC3FFA8F91C1BC9D900C08B80 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0710;\n\t\t\t\tORGANIZATIONNAME = \"吴海超\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tC3FFA9011C1BC9D900C08B80 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1.1;\n\t\t\t\t\t};\n\t\t\t\t\tC3FFA90B1C1BC9D900C08B80 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = C3FFA8FC1C1BC9D900C08B80 /* Build configuration list for PBXProject \"WHCNetWorkKit\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = C3FFA8F81C1BC9D900C08B80;\n\t\t\tproductRefGroup = C3FFA9031C1BC9D900C08B80 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tC3FFA9011C1BC9D900C08B80 /* WHCNetWorkKit */,\n\t\t\t\tC3FFA90B1C1BC9D900C08B80 /* WHCNetWorkKitTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tC3FFA9001C1BC9D900C08B80 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA90A1C1BC9D900C08B80 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tC3FFA8FD1C1BC9D900C08B80 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9771C1BCB3200C08B80 /* WHC_Json.m in Sources */,\n\t\t\t\tC3FFA9451C1BCA1100C08B80 /* WHC_HttpOperation.m in Sources */,\n\t\t\t\tC3FFA9511C1BCA1100C08B80 /* WHC_ImageCache.m in Sources */,\n\t\t\t\tC3FFA9431C1BCA1100C08B80 /* WHC_HttpManager.m in Sources */,\n\t\t\t\tC3FFA9471C1BCA1100C08B80 /* WHC_DownloadSessionTask.m in Sources */,\n\t\t\t\tC3FFA97B1C1BCB3200C08B80 /* WHC_XMLParser.m in Sources */,\n\t\t\t\tC3FFA94F1C1BCA1100C08B80 /* UIImageView+WHC_HttpImageView.m in Sources */,\n\t\t\t\tC3FFA94B1C1BCA1100C08B80 /* Reachability.m in Sources */,\n\t\t\t\tC3FFA9751C1BCB3200C08B80 /* WHC_DataModel.m in Sources */,\n\t\t\t\tC3FFA9491C1BCA1100C08B80 /* WHC_SessionDownloadManager.m in Sources */,\n\t\t\t\tC3FFA9411C1BCA1100C08B80 /* WHC_DownloadOperation.m in Sources */,\n\t\t\t\tC3FFA9791C1BCB3200C08B80 /* WHC_Xml.m in Sources */,\n\t\t\t\tC3FFA94D1C1BCA1100C08B80 /* UIButton+WHC_HttpButton.m in Sources */,\n\t\t\t\tC3FFA93F1C1BCA1100C08B80 /* WHC_BaseOperation.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tC3FFA9081C1BC9D900C08B80 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC3FFA9121C1BC9D900C08B80 /* WHCNetWorkKitTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tC3FFA90F1C1BC9D900C08B80 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = C3FFA9011C1BC9D900C08B80 /* WHCNetWorkKit */;\n\t\t\ttargetProxy = C3FFA90E1C1BC9D900C08B80 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\tC3FFA9141C1BC9D900C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9151C1BC9D900C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC3FFA9171C1BC9D900C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = WHCNetWorkKit/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA9181C1BC9D900C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = WHCNetWorkKit/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKit\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC3FFA91A1C1BC9D900C08B80 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = WHCNetWorkKitTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKitTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC3FFA91B1C1BC9D900C08B80 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = WHCNetWorkKitTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"---.WHCNetWorkKitTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tC3FFA8FC1C1BC9D900C08B80 /* Build configuration list for PBXProject \"WHCNetWorkKit\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9141C1BC9D900C08B80 /* Debug */,\n\t\t\t\tC3FFA9151C1BC9D900C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC3FFA9161C1BC9D900C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKit\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA9171C1BC9D900C08B80 /* Debug */,\n\t\t\t\tC3FFA9181C1BC9D900C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC3FFA9191C1BC9D900C08B80 /* Build configuration list for PBXNativeTarget \"WHCNetWorkKitTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC3FFA91A1C1BC9D900C08B80 /* Debug */,\n\t\t\t\tC3FFA91B1C1BC9D900C08B80 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = C3FFA8F91C1BC9D900C08B80 /* Project object */;\n}\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:WHCNetWorkKit.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/WHCNetWorkKit.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0730\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n               BuildableName = \"WHCNetWorkKit.framework\"\n               BlueprintName = \"WHCNetWorkKit\"\n               ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA90B1C1BC9D900C08B80\"\n               BuildableName = \"WHCNetWorkKitTests.xctest\"\n               BlueprintName = \"WHCNetWorkKitTests\"\n               ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>WHCNetWorkKit.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>C3FFA9011C1BC9D900C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA90B1C1BC9D900C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/WHCNetWorkKit.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0710\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n               BuildableName = \"WHCNetWorkKit.framework\"\n               BlueprintName = \"WHCNetWorkKit\"\n               ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C3FFA90B1C1BC9D900C08B80\"\n               BuildableName = \"WHCNetWorkKitTests.xctest\"\n               BlueprintName = \"WHCNetWorkKitTests\"\n               ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C3FFA9011C1BC9D900C08B80\"\n            BuildableName = \"WHCNetWorkKit.framework\"\n            BlueprintName = \"WHCNetWorkKit\"\n            ReferencedContainer = \"container:WHCNetWorkKit.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "WHCNetWorkKit.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>WHCNetWorkKit.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>C3FFA9011C1BC9D900C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>C3FFA90B1C1BC9D900C08B80</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKit.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:WHCNetWorkKit.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:WHCNetWorkKit Example.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "WHCNetWorkKit.xcworkspace/xcuserdata/WHC.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   type = \"0\"\n   version = \"2.0\">\n   <Breakpoints>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.FileBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\"\n            filePath = \"WHCNetWorkKit/NSURLConnection/WHC_DownloadOperation.m\"\n            timestampString = \"489927952.83445\"\n            startingColumnNumber = \"9223372036854775807\"\n            endingColumnNumber = \"9223372036854775807\"\n            startingLineNumber = \"219\"\n            endingLineNumber = \"219\"\n            landmarkName = \"-connectionDidFinishLoading:\"\n            landmarkType = \"5\">\n         </BreakpointContent>\n      </BreakpointProxy>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.FileBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\"\n            filePath = \"WHCNetWorkKit/NSURLConnection/WHC_DownloadOperation.m\"\n            timestampString = \"489927957.452497\"\n            startingColumnNumber = \"9223372036854775807\"\n            endingColumnNumber = \"9223372036854775807\"\n            startingLineNumber = \"237\"\n            endingLineNumber = \"237\"\n            landmarkName = \"-connection:didFailWithError:\"\n            landmarkType = \"5\">\n         </BreakpointContent>\n      </BreakpointProxy>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.FileBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\"\n            filePath = \"WHCNetWorkKit/NSURLConnection/WHC_DownloadOperation.m\"\n            timestampString = \"490098067.097733\"\n            startingColumnNumber = \"9223372036854775807\"\n            endingColumnNumber = \"9223372036854775807\"\n            startingLineNumber = \"160\"\n            endingLineNumber = \"160\"\n            landmarkName = \"-connection:didReceiveResponse:\"\n            landmarkType = \"5\">\n         </BreakpointContent>\n      </BreakpointProxy>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.FileBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\"\n            filePath = \"WHCNetWorkKit/NSURLSession/WHC_SessionDownloadManager.m\"\n            timestampString = \"490098096.429464\"\n            startingColumnNumber = \"9223372036854775807\"\n            endingColumnNumber = \"9223372036854775807\"\n            startingLineNumber = \"507\"\n            endingLineNumber = \"507\"\n            landmarkName = \"-URLSession:dataTask:didReceiveResponse:completionHandler:\"\n            landmarkType = \"5\">\n         </BreakpointContent>\n      </BreakpointProxy>\n   </Breakpoints>\n</Bucket>\n"
  },
  {
    "path": "WHCNetWorkKit.xcworkspace/xcuserdata/wuhaichao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   type = \"0\"\n   version = \"2.0\">\n</Bucket>\n"
  },
  {
    "path": "WHCNetWorkKit.xcworkspace/xcuserdata/wuhaichao.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict/>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKitTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "WHCNetWorkKitTests/WHCNetWorkKitTests.m",
    "content": "//\n//  WHCNetWorkKitTests.m\n//  WHCNetWorkKitTests\n//\n//  Created by 吴海超 on 15/12/12.\n//  Copyright © 2015年 吴海超. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface WHCNetWorkKitTests : XCTestCase\n\n@end\n\n@implementation WHCNetWorkKitTests\n\n- (void)setUp {\n    [super setUp];\n    // Put setup code here. This method is called before the invocation of each test method in the class.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // This is an example of a functional test case.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n- (void)testPerformanceExample {\n    // This is an example of a performance test case.\n    [self measureBlock:^{\n        // Put the code you want to measure the time of here.\n    }];\n}\n\n@end\n"
  }
]