├── .gitignore ├── DEMO.png ├── LICENSE ├── README.md ├── XHNetworkCache.podspec ├── XHNetworkCache ├── XHNetworkCache.h └── XHNetworkCache.m └── XHNetworkCacheExample ├── XHNetworkCacheExample.xcodeproj └── project.pbxproj └── XHNetworkCacheExample ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj └── LaunchScreen.storyboard ├── Info.plist ├── Network ├── Network.h ├── Network.m └── Test.json ├── ViewController.h ├── ViewController.m ├── ViewController.xib └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Xcode 3 | # 4 | build/ 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | project.xcworkspace 14 | !default.xcworkspace 15 | xcuserdata 16 | *.xccheckout 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | *.xcuserstate 22 | *.xcscmblueprint 23 | 24 | # CocoaPods 25 | # 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | Pods/ 31 | Podfile.lock 32 | 33 | .DS_Store -------------------------------------------------------------------------------- /DEMO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderZhuXH/XHNetworkCache/f8dad5488af8a106b675530af4eba601880fcfa5/DEMO.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 XHNetworkCache (https://github.com/CoderZhuXH/XHNetworkCache) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XHNetworkCache 2 | #### 一行代码持久化网络数据
3 | 4 | [![AppVeyor](https://img.shields.io/appveyor/ci/gruntjs/grunt.svg?maxAge=2592000)](https://github.com/CoderZhuXH/XHNetworkCache) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/CoderZhuXH/XHNetworkCache) 6 | [![Version Status](https://img.shields.io/cocoapods/v/XHNetworkCache.svg?style=flat)](http://cocoadocs.org/docsets/XHNetworkCache) 7 | [![Support](https://img.shields.io/badge/support-iOS%207%2B-brightgreen.svg)](https://github.com/CoderZhuXH/XHNetworkCache) 8 | [![Pod Platform](https://img.shields.io/cocoapods/p/XHNetworkCache.svg?style=flat)](http://cocoadocs.org/docsets/XHNetworkCache) 9 | [![Pod License](https://img.shields.io/cocoapods/l/XHNetworkCache.svg?style=flat)](https://github.com/CoderZhuXH/XHNetworkCache/blob/master/LICENSE) 10 | 11 | ============== 12 | 13 | #### Swift版本请戳这里>>> https://github.com/CoderZhuXH/XHNetworkCacheSwift 14 | 15 | ### 技术交流群(群号:537476189) 16 | 17 | 18 | ### 更新记录: 19 | 20 | * 2020.01.10 -- v1.5.0 -->增加检测该数据是否已缓存接口... 21 | * 2017.09.30 -- v1.4.0 -->已知问题修复及优化... 22 | * 2017.06.16 -- v1.3.0 -->缓存及获取缓存接口增加请求参数(可选)... 23 | * 2016.09.04 -- v1.2.3 -->增加+(NSString *)cacheSizeFormat方法... 24 | * 2016.08.12 -- v1.2.1 -->增加获取缓存路径接口...
25 | * 2016.07.06 -- v1.2 -->增加异步写入/更新缓存接口...
26 | * 2016.07.01 -- v1.1 -->1.增加手动清除缓存接口;2.增加获取缓存大小接口...
27 | * 2016.06.24 -- v1.0 28 | 29 | ## 使用方法: 30 | ### 1.(同步)写入/更新 31 | ```objc 32 | //将数据(同步)写入磁盘缓存(参数1:服务器返回的JSON数据, 参数2:数据请求URL,参数3:数据请求参数(没有传nil) 33 | //[按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 34 | BOOL result = [XHNetworkCache saveJsonResponseToCacheFile:self.responseObject andURL:self.URL params:self.params]; 35 | if(result) 36 | { 37 | NSLog(@"(同步)写入/更新缓存数据 成功"); 38 | } 39 | else 40 | { 41 | NSLog(@"(同步)写入/更新缓存数据 失败"); 42 | } 43 | 44 | ``` 45 | ### 2.(异步)写入/更新 46 | ```objc 47 | //将数据(异步)写入磁盘缓存(参数1:服务器返回的JSON数据, 参数2:数据请求URL,参数3:数据请求参数(没有传nil) 48 | //[按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 49 | [XHNetworkCache save_asyncJsonResponseToCacheFile:self.responseObject andURL:self.URL params:self.params completed:^(BOOL result) { 50 | 51 | if(result) 52 | { 53 | NSLog(@"(异步)写入/更新缓存数据 成功"); 54 | } 55 | else 56 | { 57 | NSLog(@"(异步)写入/更新缓存数据 失败"); 58 | } 59 | 60 | }]; 61 | 62 | ``` 63 | 64 | ### 3.该数据是否已缓存 65 | ```objc 66 | //获取缓存数据(参数1:请求URL,参数2:请求参数,返回:YES已缓存,NO未缓存) 67 | BOOL result = [XHNetworkCache checkCacheWithURL:self.URL params:self.params]; 68 | 69 | ``` 70 | 71 | ### 4.获取缓存数据 72 | ```objc 73 | //获取缓存数据(参数1:请求URL,参数2:请求参数,返回:JSON数据) 74 | id JsonCache = [XHNetworkCache cacheJsonWithURL:self.URL params:self.params]; 75 | 76 | ``` 77 | ### 5.获取缓存路径 78 | ```objc 79 | //获取缓存路径 80 | NSString *path = [XHNetworkCache cachePath]; 81 | 82 | ``` 83 | ### 6.清除缓存 84 | ```objc 85 | //清除缓存 86 | [XHNetworkCache clearCache]; 87 | 88 | ``` 89 | 90 | ### 7.获取缓存总大小(M) 91 | ```objc 92 | //获取缓存大小(M) 93 | float cacheSize = [XHNetworkCache cacheSize]; 94 | //或者(以..kb/..M)形式获取 95 | NSString *cacheSizeFormat = [XHNetworkCache cacheSizeFormat]; 96 | ``` 97 | ## 安装 98 | ### 1.手动添加:
99 | * 1.将 XHNetworkCache 文件夹添加到工程目录中
100 | * 2.导入 XHNetworkCache.h 101 | 102 | ### 2.CocoaPods:
103 | * 1.在 Podfile 中添加 pod 'XHNetworkCache'
104 | * 2.执行 pod install 或 pod update
105 | * 3.导入 XHNetworkCache.h 106 | 107 | ### 3.Tips 108 | * 1.如果发现pod search XHLaunchAd 搜索出来的不是最新版本,需要在终端执行pod repo update命令更新本地spec缓存(需要几分钟),然后再搜索就可以了 109 | * 2.如果你发现你执行pod install后,导入的不是最新版本,请删除Podfile.lock文件,在执行一次 pod install 110 | 111 | ## 系统要求 112 | * 该项目最低支持 iOS 7.0 和 Xcode 7.0 113 | 114 | ## 许可证 115 | XHNetworkCache 使用 MIT 许可证,详情见 LICENSE 文件 -------------------------------------------------------------------------------- /XHNetworkCache.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'XHNetworkCache' 3 | s.version = '1.5.0' 4 | s.summary = '一行代码将网络数据持久化 - 支持数据同步/异步写入及更新、缓存数据读取、获取缓存数据大小、缓存数据清除' 5 | s.homepage = 'https://github.com/CoderZhuXH/XHNetworkCache' 6 | s.license = 'MIT' 7 | s.authors = { 'Zhu Xiaohui' => '977950862@qq.com'} 8 | s.platform = :ios, '7.0' 9 | s.source = { :git => 'https://github.com/CoderZhuXH/XHNetworkCache.git', :tag => s.version } 10 | s.source_files = 'XHNetworkCache/**/*.{h,m}' 11 | s.requires_arc = true 12 | 13 | end 14 | -------------------------------------------------------------------------------- /XHNetworkCache/XHNetworkCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // XHNetworkCache.h 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHNetworkCache 8 | 9 | #import 10 | 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef void(^XHNetworkCacheCompletionBlock)(BOOL result); 15 | 16 | @interface XHNetworkCache : NSObject 17 | 18 | /** 19 | * 写入/更新缓存(同步) [按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 20 | * 21 | * @param jsonResponse 要写入的数据(JSON) 22 | * @param URL 数据请求URL 23 | * 24 | * @return 是否写入成功 25 | */ 26 | +(BOOL)saveJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL; 27 | 28 | 29 | /** 30 | * 写入/更新缓存(同步) [按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 31 | * 32 | * @param jsonResponse 要写入的数据(JSON) 33 | * @param URL 数据请求URL 34 | * @param params 数据请求参数(没有传nil) 35 | * 36 | * @return 是否写入成功 37 | */ 38 | +(BOOL)saveJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL params:(nullable NSDictionary *)params; 39 | 40 | 41 | /** 42 | * 写入/更新缓存(异步) [按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 43 | * 44 | * @param jsonResponse 要写入的数据(JSON) 45 | * @param URL 数据请求URL 46 | * @param completedBlock 异步完成回调(主线程回调) 47 | */ 48 | +(void)save_asyncJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL completed:(nullable XHNetworkCacheCompletionBlock)completedBlock; 49 | 50 | /** 51 | * 写入/更新缓存(异步) [按APP版本号缓存,不同版本APP,同一接口缓存数据互不干扰] 52 | * 53 | * @param jsonResponse 要写入的数据(JSON) 54 | * @param URL 数据请求URL 55 | * @param params 数据请求参数(没有传nil) 56 | * @param completedBlock 异步完成回调(主线程回调) 57 | */ 58 | +(void)save_asyncJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL params:(nullable NSDictionary *)params completed:(nullable XHNetworkCacheCompletionBlock)completedBlock; 59 | 60 | /** 61 | * 获取缓存的对象(同步) 62 | * 63 | * @param URL 数据请求URL 64 | * 65 | * @return 缓存对象 66 | */ 67 | +(id )cacheJsonWithURL:(NSString *)URL; 68 | 69 | 70 | /** 71 | * 获取缓存的对象(同步) 72 | * 73 | * @param URL 数据请求URL 74 | * @param params 数据请求参数 75 | * 76 | * @return 缓存对象 77 | */ 78 | +(id )cacheJsonWithURL:(NSString *)URL params:(nullable NSDictionary *)params; 79 | 80 | 81 | /// 检测是否已缓存该数据 82 | /// @param URL 数据请求URL 83 | /// @return YES已缓存, NO未缓存 84 | +(BOOL)checkCacheWithURL:(NSString *)URL; 85 | 86 | 87 | /// 检测是否已缓存该数据 88 | /// @param URL 数据请求URL 89 | /// @param params 数据请求参数 90 | /// @return YES已缓存, NO未缓存 91 | +(BOOL)checkCacheWithURL:(NSString *)URL params:(nullable NSDictionary *)params; 92 | 93 | 94 | /** 95 | * 获取缓存路径 96 | * 97 | * @return 缓存路径 98 | */ 99 | +(NSString *)cachePath; 100 | 101 | /** 102 | * 清除缓存 103 | */ 104 | +(BOOL)clearCache; 105 | 106 | /** 107 | * 获取缓存大小(单位:M) 108 | * 109 | * @return 缓存大小 110 | */ 111 | + (float)cacheSize; 112 | 113 | /** 114 | * 获取缓存大小,(以..kb/..M)形式获取 115 | * 小于1M,以kb形式返回,大于1M,以M形式返回 116 | * @return 缓存大小+单位 117 | */ 118 | +(NSString *)cacheSizeFormat; 119 | 120 | @end 121 | 122 | NS_ASSUME_NONNULL_END 123 | 124 | -------------------------------------------------------------------------------- /XHNetworkCache/XHNetworkCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // XHNetworkCache.m 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHNetworkCache 8 | 9 | #import "XHNetworkCache.h" 10 | #import 11 | 12 | #ifdef DEBUG 13 | #define DebugLog(...) NSLog(__VA_ARGS__) 14 | #else 15 | #define DebugLog(...) 16 | #endif 17 | 18 | @implementation XHNetworkCache 19 | 20 | +(BOOL)saveJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL{ 21 | 22 | return [self saveJsonResponseToCacheFile:jsonResponse andURL:URL params:nil]; 23 | } 24 | 25 | +(BOOL)saveJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL params:(nullable NSDictionary *)params{ 26 | 27 | if(jsonResponse==nil || URL.length==0) return NO; 28 | NSData * data= [self jsonToData:jsonResponse]; 29 | return[[NSFileManager defaultManager] createFileAtPath:[self cacheFilePathWithURL:URL params:params] contents:data attributes:nil]; 30 | } 31 | 32 | +(void)save_asyncJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL completed:(nullable XHNetworkCacheCompletionBlock)completedBlock;{ 33 | 34 | [self save_asyncJsonResponseToCacheFile:jsonResponse andURL:URL params:nil completed:completedBlock]; 35 | } 36 | 37 | +(void)save_asyncJsonResponseToCacheFile:(id)jsonResponse andURL:(NSString *)URL params:(nullable NSDictionary *)params completed:(nullable XHNetworkCacheCompletionBlock)completedBlock{ 38 | 39 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 40 | 41 | BOOL result=[self saveJsonResponseToCacheFile:jsonResponse andURL:URL params:params]; 42 | 43 | dispatch_async(dispatch_get_main_queue(), ^{ 44 | 45 | if(completedBlock) completedBlock(result); 46 | 47 | }); 48 | }); 49 | } 50 | 51 | +(id)cacheJsonWithURL:(NSString *)URL{ 52 | 53 | return [self cacheJsonWithURL:URL params:nil]; 54 | 55 | } 56 | 57 | +(id )cacheJsonWithURL:(NSString *)URL params:(nullable NSDictionary *)params{ 58 | 59 | if(URL==nil) return nil; 60 | NSString *path = [self cacheFilePathWithURL:URL params:params]; 61 | NSFileManager *fileManager = [NSFileManager defaultManager]; 62 | if([self checkCacheWithURL:URL params:params]){ 63 | NSData *data = [fileManager contentsAtPath:path]; 64 | return [self dataToJson:data]; 65 | } 66 | return nil; 67 | } 68 | 69 | 70 | +(BOOL)checkCacheWithURL:(NSString *)URL{ 71 | 72 | return [self checkCacheWithURL:URL params:nil]; 73 | } 74 | 75 | +(BOOL)checkCacheWithURL:(NSString *)URL params:(nullable NSDictionary *)params{ 76 | if(URL==nil) return NO; 77 | NSString *path = [self cacheFilePathWithURL:URL params:params]; 78 | NSFileManager *fileManager = [NSFileManager defaultManager]; 79 | return [fileManager fileExistsAtPath:path isDirectory:nil]; 80 | } 81 | 82 | 83 | +(BOOL)clearCache 84 | { 85 | NSFileManager *fileManager = [NSFileManager defaultManager]; 86 | NSString *path = [self cachePath]; 87 | BOOL result = [fileManager removeItemAtPath:path error:nil]; 88 | [self checkDirectory:[self cachePath]]; 89 | return result; 90 | } 91 | 92 | + (float)cacheSize{ 93 | NSString *directoryPath = [self cachePath]; 94 | BOOL isDir = NO; 95 | unsigned long long total = 0; 96 | 97 | if ([[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:&isDir]) { 98 | if (isDir) { 99 | NSError *error = nil; 100 | NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:&error]; 101 | 102 | if (error == nil) { 103 | for (NSString *subpath in array) { 104 | NSString *path = [directoryPath stringByAppendingPathComponent:subpath]; 105 | NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:path 106 | error:&error]; 107 | if (!error) { 108 | total += [dict[NSFileSize] unsignedIntegerValue]; 109 | } 110 | } 111 | } 112 | } 113 | } 114 | return total/(1024.0*1024.0); 115 | } 116 | 117 | +(NSString *)cacheSizeFormat 118 | { 119 | NSString *sizeUnitString; 120 | float size = [self cacheSize]; 121 | if(size < 1) 122 | { 123 | size *= 1024.0;//小于1M转化为kb 124 | sizeUnitString = [NSString stringWithFormat:@"%.1fkb",size]; 125 | } 126 | else{ 127 | 128 | sizeUnitString = [NSString stringWithFormat:@"%.1fM",size]; 129 | } 130 | 131 | return sizeUnitString; 132 | } 133 | 134 | #pragma mark - private 135 | + (NSString *)cacheFilePathWithURL:(NSString *)URL params:(NSDictionary *)params{ 136 | 137 | NSString *path = [self cachePath]; 138 | //checkDirectory 139 | [self checkDirectory:path]; 140 | //fileName 141 | NSString *cacheFileName = [self cacheFileNameWithURL:URL params:params]; 142 | path = [path stringByAppendingPathComponent:cacheFileName]; 143 | return path; 144 | } 145 | 146 | +(NSData *)jsonToData:(id)jsonResponse 147 | { 148 | if(jsonResponse==nil) return nil; 149 | NSError *error; 150 | NSData *data =[NSJSONSerialization dataWithJSONObject:jsonResponse options:NSJSONWritingPrettyPrinted error:&error]; 151 | if (error) { 152 | DebugLog(@"ERROR, faild to get json data"); 153 | return nil; 154 | } 155 | return data; 156 | } 157 | 158 | +(id)dataToJson:(NSData *)data 159 | { 160 | if(data==nil) return nil; 161 | return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; 162 | } 163 | 164 | +(NSString *)cachePath 165 | { 166 | NSString *pathOfLibrary = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 167 | NSString *path = [pathOfLibrary stringByAppendingPathComponent:@"XHNetworkCache"]; 168 | return path; 169 | } 170 | 171 | +(NSString *)cacheFileNameWithURL:(NSString *)URL params:(NSDictionary *)params 172 | { 173 | if(URL== nil || URL.length == 0) return nil; 174 | NSString *fileName = [NSString stringWithFormat:@"URL:%@%@ AppVersion:%@",URL,[self paramsStringWithParams:params],[self appVersionString]]; 175 | //DebugLog(@"flieName=%@",fileName); 176 | return [self md5StringFromString:fileName]; 177 | } 178 | +(NSString *)paramsStringWithParams:(NSDictionary *)params 179 | { 180 | if(params==nil) return @""; 181 | NSArray *keyArray = [params allKeys]; 182 | NSArray *sortArray = [keyArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { 183 | return [obj1 compare:obj2 options:NSNumericSearch]; 184 | }]; 185 | NSMutableArray *valueArray = [NSMutableArray array]; 186 | for (NSString *sortString in sortArray) { 187 | [valueArray addObject:[params objectForKey:sortString]]; 188 | } 189 | NSMutableArray *keyValueArray = [NSMutableArray array]; 190 | for (int i = 0; i < sortArray.count; i++) { 191 | NSString *keyValueStr = [NSString stringWithFormat:@"%@=%@",sortArray[i],valueArray[i]]; 192 | [keyValueArray addObject:keyValueStr]; 193 | } 194 | return [NSString stringWithFormat:@"?%@",[keyValueArray componentsJoinedByString:@"&"]]; 195 | } 196 | +(void)checkDirectory:(NSString *)path { 197 | NSFileManager *fileManager = [NSFileManager defaultManager]; 198 | BOOL isDir; 199 | if (![fileManager fileExistsAtPath:path isDirectory:&isDir]) { 200 | [self createBaseDirectoryAtPath:path]; 201 | } else { 202 | 203 | if (!isDir) { 204 | NSError *error = nil; 205 | [fileManager removeItemAtPath:path error:&error]; 206 | [self createBaseDirectoryAtPath:path]; 207 | } 208 | } 209 | } 210 | 211 | + (void)createBaseDirectoryAtPath:(NSString *)path { 212 | __autoreleasing NSError *error = nil; 213 | [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES 214 | attributes:nil error:&error]; 215 | if (error) { 216 | DebugLog(@"create cache directory failed, error = %@", error); 217 | } else { 218 | 219 | DebugLog(@"path = %@",path); 220 | [self addDoNotBackupAttribute:path]; 221 | } 222 | } 223 | 224 | + (void)addDoNotBackupAttribute:(NSString *)path { 225 | NSURL *url = [NSURL fileURLWithPath:path]; 226 | NSError *error = nil; 227 | [url setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error]; 228 | if (error) { 229 | DebugLog(@"error to set do not backup attribute, error = %@", error); 230 | } 231 | } 232 | 233 | + (NSString *)md5StringFromString:(NSString *)string { 234 | 235 | if(string == nil || [string length] == 0) return nil; 236 | 237 | const char *value = [string UTF8String]; 238 | 239 | unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH]; 240 | CC_MD5(value, (CC_LONG)strlen(value), outputBuffer); 241 | 242 | NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; 243 | for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){ 244 | [outputString appendFormat:@"%02x",outputBuffer[count]]; 245 | } 246 | 247 | return outputString; 248 | } 249 | 250 | + (NSString *)appVersionString { 251 | 252 | return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 253 | } 254 | 255 | @end 256 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0CABAFB91EF3AC7F0091B659 /* Network.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CABAFB81EF3AC7F0091B659 /* Network.m */; }; 11 | 0CABAFBD1EF3AD700091B659 /* Test.json in Resources */ = {isa = PBXBuildFile; fileRef = 0CABAFBC1EF3AD700091B659 /* Test.json */; }; 12 | 4BE4D6751D1E296300CC4624 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4D6741D1E296300CC4624 /* main.m */; }; 13 | 4BE4D6781D1E296300CC4624 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4D6771D1E296300CC4624 /* AppDelegate.m */; }; 14 | 4BE4D67A1D1E296300CC4624 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BE4D6791D1E296300CC4624 /* Assets.xcassets */; }; 15 | 4BE4D67D1D1E296300CC4624 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BE4D67B1D1E296300CC4624 /* LaunchScreen.storyboard */; }; 16 | 4BE4D68A1D1E2BCF00CC4624 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4D6891D1E2BCF00CC4624 /* ViewController.m */; }; 17 | 4BE4D6C31D1E31B900CC4624 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BE4D6C21D1E31B900CC4624 /* ViewController.xib */; }; 18 | 6023A91D1FB53F7100712C1B /* XHNetworkCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6023A91C1FB53F7100712C1B /* XHNetworkCache.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 0CABAFB71EF3AC7F0091B659 /* Network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Network.h; sourceTree = ""; }; 23 | 0CABAFB81EF3AC7F0091B659 /* Network.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Network.m; sourceTree = ""; }; 24 | 0CABAFBC1EF3AD700091B659 /* Test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Test.json; sourceTree = ""; }; 25 | 4BE4D6701D1E296300CC4624 /* XHNetworkCacheExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XHNetworkCacheExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 4BE4D6741D1E296300CC4624 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 27 | 4BE4D6761D1E296300CC4624 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 28 | 4BE4D6771D1E296300CC4624 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 29 | 4BE4D6791D1E296300CC4624 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 30 | 4BE4D67C1D1E296300CC4624 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 31 | 4BE4D67E1D1E296300CC4624 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 4BE4D6881D1E2BCF00CC4624 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 33 | 4BE4D6891D1E2BCF00CC4624 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 34 | 4BE4D6C21D1E31B900CC4624 /* ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ViewController.xib; sourceTree = ""; }; 35 | 6023A91B1FB53F7100712C1B /* XHNetworkCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XHNetworkCache.h; sourceTree = ""; }; 36 | 6023A91C1FB53F7100712C1B /* XHNetworkCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XHNetworkCache.m; sourceTree = ""; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 4BE4D66D1D1E296300CC4624 /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 0CABAFB61EF3AC7F0091B659 /* Network */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 0CABAFBC1EF3AD700091B659 /* Test.json */, 54 | 0CABAFB71EF3AC7F0091B659 /* Network.h */, 55 | 0CABAFB81EF3AC7F0091B659 /* Network.m */, 56 | ); 57 | path = Network; 58 | sourceTree = ""; 59 | }; 60 | 4BE4D6671D1E296300CC4624 = { 61 | isa = PBXGroup; 62 | children = ( 63 | 4BE4D6721D1E296300CC4624 /* XHNetworkCacheExample */, 64 | 6023A91A1FB53F7100712C1B /* XHNetworkCache */, 65 | 4BE4D6711D1E296300CC4624 /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 4BE4D6711D1E296300CC4624 /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 4BE4D6701D1E296300CC4624 /* XHNetworkCacheExample.app */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | 4BE4D6721D1E296300CC4624 /* XHNetworkCacheExample */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 0CABAFB61EF3AC7F0091B659 /* Network */, 81 | 4BE4D6761D1E296300CC4624 /* AppDelegate.h */, 82 | 4BE4D6771D1E296300CC4624 /* AppDelegate.m */, 83 | 4BE4D6881D1E2BCF00CC4624 /* ViewController.h */, 84 | 4BE4D6891D1E2BCF00CC4624 /* ViewController.m */, 85 | 4BE4D6C21D1E31B900CC4624 /* ViewController.xib */, 86 | 4BE4D6791D1E296300CC4624 /* Assets.xcassets */, 87 | 4BE4D67B1D1E296300CC4624 /* LaunchScreen.storyboard */, 88 | 4BE4D67E1D1E296300CC4624 /* Info.plist */, 89 | 4BE4D6731D1E296300CC4624 /* Supporting Files */, 90 | ); 91 | path = XHNetworkCacheExample; 92 | sourceTree = ""; 93 | }; 94 | 4BE4D6731D1E296300CC4624 /* Supporting Files */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 4BE4D6741D1E296300CC4624 /* main.m */, 98 | ); 99 | name = "Supporting Files"; 100 | sourceTree = ""; 101 | }; 102 | 6023A91A1FB53F7100712C1B /* XHNetworkCache */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 6023A91B1FB53F7100712C1B /* XHNetworkCache.h */, 106 | 6023A91C1FB53F7100712C1B /* XHNetworkCache.m */, 107 | ); 108 | name = XHNetworkCache; 109 | path = ../XHNetworkCache; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | 4BE4D66F1D1E296300CC4624 /* XHNetworkCacheExample */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = 4BE4D6811D1E296300CC4624 /* Build configuration list for PBXNativeTarget "XHNetworkCacheExample" */; 118 | buildPhases = ( 119 | 4BE4D66C1D1E296300CC4624 /* Sources */, 120 | 4BE4D66D1D1E296300CC4624 /* Frameworks */, 121 | 4BE4D66E1D1E296300CC4624 /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = XHNetworkCacheExample; 128 | productName = XHNetworkCacheExample; 129 | productReference = 4BE4D6701D1E296300CC4624 /* XHNetworkCacheExample.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | 4BE4D6681D1E296300CC4624 /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastUpgradeCheck = 0730; 139 | ORGANIZATIONNAME = qiantou; 140 | TargetAttributes = { 141 | 4BE4D66F1D1E296300CC4624 = { 142 | CreatedOnToolsVersion = 7.3.1; 143 | DevelopmentTeam = 8X3PW6P5H6; 144 | }; 145 | }; 146 | }; 147 | buildConfigurationList = 4BE4D66B1D1E296300CC4624 /* Build configuration list for PBXProject "XHNetworkCacheExample" */; 148 | compatibilityVersion = "Xcode 3.2"; 149 | developmentRegion = English; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | English, 153 | en, 154 | Base, 155 | ); 156 | mainGroup = 4BE4D6671D1E296300CC4624; 157 | productRefGroup = 4BE4D6711D1E296300CC4624 /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 4BE4D66F1D1E296300CC4624 /* XHNetworkCacheExample */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | 4BE4D66E1D1E296300CC4624 /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 0CABAFBD1EF3AD700091B659 /* Test.json in Resources */, 172 | 4BE4D67A1D1E296300CC4624 /* Assets.xcassets in Resources */, 173 | 4BE4D6C31D1E31B900CC4624 /* ViewController.xib in Resources */, 174 | 4BE4D67D1D1E296300CC4624 /* LaunchScreen.storyboard in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | 4BE4D66C1D1E296300CC4624 /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | 4BE4D6781D1E296300CC4624 /* AppDelegate.m in Sources */, 186 | 0CABAFB91EF3AC7F0091B659 /* Network.m in Sources */, 187 | 6023A91D1FB53F7100712C1B /* XHNetworkCache.m in Sources */, 188 | 4BE4D68A1D1E2BCF00CC4624 /* ViewController.m in Sources */, 189 | 4BE4D6751D1E296300CC4624 /* main.m in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXSourcesBuildPhase section */ 194 | 195 | /* Begin PBXVariantGroup section */ 196 | 4BE4D67B1D1E296300CC4624 /* LaunchScreen.storyboard */ = { 197 | isa = PBXVariantGroup; 198 | children = ( 199 | 4BE4D67C1D1E296300CC4624 /* Base */, 200 | ); 201 | name = LaunchScreen.storyboard; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXVariantGroup section */ 205 | 206 | /* Begin XCBuildConfiguration section */ 207 | 4BE4D67F1D1E296300CC4624 /* Debug */ = { 208 | isa = XCBuildConfiguration; 209 | buildSettings = { 210 | ALWAYS_SEARCH_USER_PATHS = NO; 211 | CLANG_ANALYZER_NONNULL = YES; 212 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 213 | CLANG_CXX_LIBRARY = "libc++"; 214 | CLANG_ENABLE_MODULES = YES; 215 | CLANG_ENABLE_OBJC_ARC = YES; 216 | CLANG_WARN_BOOL_CONVERSION = YES; 217 | CLANG_WARN_CONSTANT_CONVERSION = YES; 218 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 219 | CLANG_WARN_EMPTY_BODY = YES; 220 | CLANG_WARN_ENUM_CONVERSION = YES; 221 | CLANG_WARN_INT_CONVERSION = YES; 222 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 223 | CLANG_WARN_UNREACHABLE_CODE = YES; 224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 225 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 226 | COPY_PHASE_STRIP = NO; 227 | DEBUG_INFORMATION_FORMAT = dwarf; 228 | ENABLE_STRICT_OBJC_MSGSEND = YES; 229 | ENABLE_TESTABILITY = YES; 230 | GCC_C_LANGUAGE_STANDARD = gnu99; 231 | GCC_DYNAMIC_NO_PIC = NO; 232 | GCC_NO_COMMON_BLOCKS = YES; 233 | GCC_OPTIMIZATION_LEVEL = 0; 234 | GCC_PREPROCESSOR_DEFINITIONS = ( 235 | "DEBUG=1", 236 | "$(inherited)", 237 | ); 238 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 239 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 240 | GCC_WARN_UNDECLARED_SELECTOR = YES; 241 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 242 | GCC_WARN_UNUSED_FUNCTION = YES; 243 | GCC_WARN_UNUSED_VARIABLE = YES; 244 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 245 | MTL_ENABLE_DEBUG_INFO = YES; 246 | ONLY_ACTIVE_ARCH = YES; 247 | SDKROOT = iphoneos; 248 | }; 249 | name = Debug; 250 | }; 251 | 4BE4D6801D1E296300CC4624 /* Release */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_ANALYZER_NONNULL = YES; 256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 257 | CLANG_CXX_LIBRARY = "libc++"; 258 | CLANG_ENABLE_MODULES = YES; 259 | CLANG_ENABLE_OBJC_ARC = YES; 260 | CLANG_WARN_BOOL_CONVERSION = YES; 261 | CLANG_WARN_CONSTANT_CONVERSION = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_EMPTY_BODY = YES; 264 | CLANG_WARN_ENUM_CONVERSION = YES; 265 | CLANG_WARN_INT_CONVERSION = YES; 266 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 267 | CLANG_WARN_UNREACHABLE_CODE = YES; 268 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 269 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 270 | COPY_PHASE_STRIP = NO; 271 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 272 | ENABLE_NS_ASSERTIONS = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_NO_COMMON_BLOCKS = YES; 276 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 277 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 278 | GCC_WARN_UNDECLARED_SELECTOR = YES; 279 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 280 | GCC_WARN_UNUSED_FUNCTION = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 283 | MTL_ENABLE_DEBUG_INFO = NO; 284 | SDKROOT = iphoneos; 285 | VALIDATE_PRODUCT = YES; 286 | }; 287 | name = Release; 288 | }; 289 | 4BE4D6821D1E296300CC4624 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 293 | DEVELOPMENT_TEAM = 8X3PW6P5H6; 294 | INFOPLIST_FILE = XHNetworkCacheExample/Info.plist; 295 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 296 | PRODUCT_BUNDLE_IDENTIFIER = com.it7090.XHNetworkCacheExample; 297 | PRODUCT_NAME = "$(TARGET_NAME)"; 298 | }; 299 | name = Debug; 300 | }; 301 | 4BE4D6831D1E296300CC4624 /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 305 | DEVELOPMENT_TEAM = 8X3PW6P5H6; 306 | INFOPLIST_FILE = XHNetworkCacheExample/Info.plist; 307 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 308 | PRODUCT_BUNDLE_IDENTIFIER = com.it7090.XHNetworkCacheExample; 309 | PRODUCT_NAME = "$(TARGET_NAME)"; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | 4BE4D66B1D1E296300CC4624 /* Build configuration list for PBXProject "XHNetworkCacheExample" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | 4BE4D67F1D1E296300CC4624 /* Debug */, 320 | 4BE4D6801D1E296300CC4624 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | 4BE4D6811D1E296300CC4624 /* Build configuration list for PBXNativeTarget "XHNetworkCacheExample" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | 4BE4D6821D1E296300CC4624 /* Debug */, 329 | 4BE4D6831D1E296300CC4624 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = 4BE4D6681D1E296300CC4624 /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHNetworkCache 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.window.backgroundColor = [UIColor whiteColor]; 23 | 24 | 25 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]]; 26 | 27 | [self.window makeKeyAndVisible]; 28 | return YES; 29 | } 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application { 32 | // 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. 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application { 37 | // 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. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application { 46 | // 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. 47 | } 48 | 49 | - (void)applicationWillTerminate:(UIApplication *)application { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Network/Network.h: -------------------------------------------------------------------------------- 1 | // 2 | // Network.h 3 | // XHLaunchAdExample 4 | // 5 | // Created by zhu zhuxiaohui on 2016/6/28. 6 | // Copyright © 2016年 it7090.com. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHLaunchAd 8 | // 数据请求类 9 | 10 | #import 11 | 12 | typedef void(^NetworkSucess) (id response); 13 | typedef void(^NetworkFailure) (NSError *error); 14 | 15 | @interface Network : NSObject 16 | 17 | /** 18 | GET请求 19 | */ 20 | +(void)getWithURL:(NSString *)URL params:(NSDictionary *)params success:(NetworkSucess)success failure:(NetworkFailure)failure; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Network/Network.m: -------------------------------------------------------------------------------- 1 | // 2 | // Network.m 3 | // XHLaunchAdExample 4 | // 5 | // Created by zhu zhuxiaohui on 2016/6/28. 6 | // Copyright © 2016年 it7090.com. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHLaunchAd 8 | // 数据请求类 9 | #import "Network.h" 10 | 11 | @implementation Network 12 | 13 | 14 | /** 15 | GET请求 16 | */ 17 | +(void)getWithURL:(NSString *)URL params:(NSDictionary *)params success:(NetworkSucess)success failure:(NetworkFailure)failure 18 | { 19 | //此处仅做模拟请求,实际开发中请做真是请求 20 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 21 | 22 | NSData *JSONData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Test" ofType:@"json"]]; 23 | NSDictionary *json = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingAllowFragments error:nil]; 24 | if(success) success(json); 25 | }); 26 | 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/Network/Test.json: -------------------------------------------------------------------------------- 1 | { 2 | "code":200, 3 | "msg":"success", 4 | "data":{ 5 | "time" : "1444524177", 6 | "isauth" : "0", 7 | "openid" : "1728484287", 8 | "sex" : "男", 9 | "city" : "", 10 | "cover" : "http://tp4.sinaimg.cn/1728484287/180/5736236738/1", 11 | "logintime" : "1445267749", 12 | "name" : "", 13 | "group" : "3", 14 | "loginhit" : "4", 15 | "id" : "234328", 16 | "phone" : "", 17 | "nicheng" : "辉Allen", 18 | "apptoken" : "bae4c30113151270174f724f450779bc", 19 | "face" : "http://tp4.sinaimg.cn/1728484287/180/5736236738/1", 20 | "desc" : "比你牛B的人都在努力,你还有什么理由偷懒!", 21 | "infoverify" : "1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHNetworkCache 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 代码地址:https://github.com/CoderZhuXH/XHNetworkCache 8 | 9 | #import "ViewController.h" 10 | #import "XHNetworkCache.h" 11 | #import "Network.h" 12 | 13 | @interface ViewController () 14 | 15 | /** 16 | * 模拟数据请求URL 17 | */ 18 | @property (nonatomic, copy) NSString *URL; 19 | 20 | /** 21 | 请求参数 22 | */ 23 | @property(nonatomic,strong)NSDictionary *params; 24 | 25 | /** 26 | * 服务器返回数据 27 | */ 28 | @property (nonatomic, strong) id responseObject; 29 | 30 | @property (weak, nonatomic) IBOutlet UILabel *textLab; 31 | 32 | @end 33 | 34 | @implementation ViewController 35 | 36 | - (void)viewDidLoad { 37 | [super viewDidLoad]; 38 | 39 | self.navigationItem.title = @"XHNetworkCache"; 40 | self.textLab.text = [NSString stringWithFormat:@"请看控制台打印\n 详情见:Github:https://github.com/CoderZhuXH/XHNetworkCache"]; 41 | 42 | self.URL = @"http://www.it7090.com/Api/getUserInfo"; 43 | self.params =@{@"userId":@"10001"}; 44 | [Network getWithURL:self.URL params:self.params success:^(id response) { 45 | 46 | self.responseObject = response; 47 | 48 | } failure:^(NSError *error) { 49 | 50 | }]; 51 | 52 | } 53 | #pragma mark-Action 54 | /** 55 | * (同步)写入/更新缓存数据 56 | */ 57 | - (IBAction)save:(UIButton *)sender { 58 | 59 | //(同步)写入/更新缓存数据 60 | //参数1:JSON数据,参数2:数据请求URL,参数3:数据请求参数(没有传nil) 61 | BOOL result = [XHNetworkCache saveJsonResponseToCacheFile:self.responseObject andURL:self.URL params:self.params]; 62 | if(result) 63 | { 64 | NSLog(@"(同步)写入/更新缓存数据 成功"); 65 | } 66 | else 67 | { 68 | NSLog(@"(同步)写入/更新缓存数据 失败"); 69 | } 70 | } 71 | /** 72 | * (异步)写入/更新缓存数据 73 | */ 74 | - (IBAction)save_async:(id)sender { 75 | 76 | //(异步步)写入/更新缓存数据 77 | //参数1:JSON数据,参数2:数据请求URL,参数3:数据请求参数(没有传nil) 78 | [XHNetworkCache save_asyncJsonResponseToCacheFile:self.responseObject andURL:self.URL params:self.params completed:^(BOOL result) { 79 | 80 | if(result) 81 | { 82 | NSLog(@"(异步)写入/更新缓存数据 成功"); 83 | } 84 | else 85 | { 86 | NSLog(@"(异步)写入/更新缓存数据 失败"); 87 | } 88 | 89 | }]; 90 | } 91 | /** 92 | * 获取缓存数据 93 | */ 94 | - (IBAction)getCache:(id)sender{ 95 | 96 | //获取缓存数据 97 | //参数1:数据请求URL,参数2:数据请求参数(没有传nil) 98 | id cacheJson = [XHNetworkCache cacheJsonWithURL:self.URL params:self.params]; 99 | NSLog(@"缓存数据:%@",cacheJson); 100 | } 101 | 102 | /** 103 | * 检测数据是否已缓存 104 | */ 105 | - (IBAction)checkCache:(UIButton *)sender { 106 | 107 | BOOL result = [XHNetworkCache checkCacheWithURL:self.URL params:self.params]; 108 | if(result){ 109 | NSLog(@"该数据已缓存"); 110 | }else{ 111 | NSLog(@"该数据未缓存"); 112 | } 113 | } 114 | 115 | 116 | 117 | /** 118 | * 缓存数据大小(M) 119 | */ 120 | - (IBAction)cacheSize:(id)sender { 121 | 122 | float size = [XHNetworkCache cacheSize]; 123 | NSLog(@"type1,缓存大小:%fM",size); 124 | 125 | //或者(以..kb/..M)形式获取 126 | NSString *sizeFormat = [XHNetworkCache cacheSizeFormat]; 127 | NSLog(@"type2,缓存大小:%@",sizeFormat); 128 | 129 | } 130 | /** 131 | * 缓存路径 132 | */ 133 | - (IBAction)cachePath:(id)sender { 134 | 135 | NSString *path = [XHNetworkCache cachePath]; 136 | 137 | NSLog(@"path=%@",path); 138 | } 139 | /** 140 | * 清除缓存 141 | */ 142 | - (IBAction)clearCache:(id)sender { 143 | 144 | BOOL result = [XHNetworkCache clearCache]; 145 | if(result) NSLog(@"缓存清除成功"); 146 | } 147 | 148 | - (void)didReceiveMemoryWarning { 149 | [super didReceiveMemoryWarning]; 150 | // Dispose of any resources that can be recreated. 151 | } 152 | 153 | /* 154 | #pragma mark - Navigation 155 | 156 | // In a storyboard-based application, you will often want to do a little preparation before navigation 157 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 158 | // Get the new view controller using [segue destinationViewController]. 159 | // Pass the selected object to the new view controller. 160 | } 161 | */ 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 44 | 58 | 72 | 86 | 106 | 120 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /XHNetworkCacheExample/XHNetworkCacheExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // XHNetworkCacheExample 4 | // 5 | // Created by zhuxiaohui on 16/6/25. 6 | // Copyright © 2016年 it7090. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------