对一些首页的网络加载的数据进行本地缓存,提升用户体验,不至于每次进入首页都是一片空白,这里使用的是文件读写的方式,直接将网络请求返回的json数据进行读写操作
YWDataCache.h
文件
#import <Foundation/Foundation.h>
// 主缓存路径,默认放在 /Library/Caches/default 这个路径下
#define YWCachePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingString:@"/default"]
// 日志打印
#ifdef DEBUG
# define YWLog(fmt, ...) NSLog((@"\n⭐️⭐️⭐️: %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define YWLog(...)
#endif
@interface YWDataCache : NSObject
/**
普通json缓存 - 写入缓存
@param fileName 缓存文件名称(读取时保持一致)
@param dataSource 要缓存的数据源
@return 返回写入结果 YES Or NO
*/
+ (BOOL)writeDataToCacheWithFileName:(NSString *)fileName dataSource:(id)dataSource;
/**
普通json缓存 - 读取缓存
@param fileName 缓存文件名称(读写要保持一致)
@return 返回读取结果
*/
+ (nullable id)getCacheWithFileName:(NSString *)fileName;
/**
HTML缓存 - 写入缓存
@param urlString 网页链接Url
@return 返回写入结果 YES Or NO
*/
+ (BOOL)writeToHTMLCache:(NSString *)urlString;
/**
HTML缓存 - 读取缓存
@param urlString 网页链接Url
@return 返回html标签文件
*/
+ (NSString *)getHTMLCacheWithUrlString:(NSString *)urlString;
/**
*
@param urlString 图片url
@return 返回写入结果 YES Or NO
*/
/**
网络图片缓存 - 写入缓存
@param urlString 图片url
@param successBlock 成功回调
@param errorBlock 失败回调
*/
+ (void)writeImageToLocalCache:(NSString *)urlString successBlock:(void (^)(UIImage *))successBlock errorBlock:(void (^)(void))errorBlock;
/**
网络图片缓存 - 读取缓存
@param urlString 图片url
@return 返回读取结果
*/
+ (UIImage *)getImageWithImageUrl:(NSString *)urlString;
/**
获取path路径下文件夹的大小
@param path 要获取的文件夹 路径
@return 返回path路径下缓存文件大小
*/
+ (NSString *)getCacheSizeWithFilePath:(NSString *)path;
/**
清除path路径下文件夹的缓存
@param path 要清除缓存的文件夹 路径
@return 返回是否清除成功
*/
+ (BOOL)clearCacheWithFilePath:(NSString *)path;
/**
数据大小转换(bytes转 MB、KB、B)
@param dataLength 数据长度
@return 返回大小字符串
*/
+ (NSString *)getBytesFromDataLength:(NSInteger)dataLength;
@end
YWDataCache.m
文件
#import "YWDataCache.h"
@implementation YWDataCache
#pragma mark - * * * * * 普通json缓存 * * * * *
// 普通json缓存 - 写入缓存
+ (BOOL)writeDataToCacheWithFileName:(NSString *)fileName dataSource:(id)dataSource {
// 检查文件夹是否存在
[self checkFolderIsExistsWithFilePath:nil];
// 拼接缓存路径
NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.json", YWCachePath, fileName];
NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:dataSource options:NSJSONWritingPrettyPrinted error:&error];
BOOL isTureWrite = [data writeToFile:cachesPath atomically:YES];
if (isTureWrite) {
YWLog(@"数据写入成功,缓存路径:%@", cachesPath);
return YES;
}
YWLog(@"数据写入失败,错误消息:%@,%@", fileName, error);
return NO;
}
// 普通json缓存 - 读取缓存
+ (nullable id)getCacheWithFileName:(NSString *)fileName {
// 检查文件夹是否存在
[self checkFolderIsExistsWithFilePath:nil];
// 拼接缓存路径
NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.json", YWCachePath, fileName];
NSData *data = [NSData dataWithContentsOfFile:cachesPath];
if (data) {
NSError *error;
id dataSource = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
if (!error) {
return dataSource;
}
YWLog(@"数据读取失败,错误消息:%@,%@", fileName, error);
}
YWLog(@"暂无缓存数据");
return nil;
}
#pragma mark - * * * * * 网页缓存 * * * * *
// 网页缓存写入文件
+ (BOOL)writeToHTMLCache:(NSString *)urlString {
// 检查文件夹是否存在
[self checkFolderIsExistsWithFilePath:nil];
// 拼接缓存路径
NSString *cachesPath = [NSString stringWithFormat:@"%@/%lu.html", YWCachePath, (unsigned long)[urlString hash]];
// URL编码
NSString * htmlResponseStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSUTF8StringEncoding error:Nil];
// 将文件写入缓存
NSError *error;
BOOL isTureWrite = [htmlResponseStr writeToFile:cachesPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (isTureWrite) {
YWLog(@"网页数据写入成功,缓存路径:%@", cachesPath);
return YES;
}
YWLog(@"网页数据写入失败,错误消息:%@,%@", urlString, error);
return NO;
}
// 读取网页缓存
+ (NSString *)getHTMLCacheWithUrlString:(NSString *)urlString {
// 检查文件夹是否存在
[self checkFolderIsExistsWithFilePath:nil];
// 拼接缓存路径
NSString *cachesPath = [NSString stringWithFormat:@"%@/%lu.html", YWCachePath, (unsigned long)[urlString hash]];
// 读取缓存文件
NSError *error;
NSString *htmlStr = [NSString stringWithContentsOfFile:cachesPath encoding:NSUTF8StringEncoding error:nil];
if (!error) {
return htmlStr;
}
YWLog(@"网页数据读取失败,错误消息:%@,%@", urlString, error);
return nil;
}
#pragma mark - * * * * * 网络图片缓存 * * * * *
+ (void)writeImageToLocalCache:(NSString *)urlString successBlock:(void (^)(UIImage *image))successBlock errorBlock:(void (^)(void))errorBlock {
if (!urlString && errorBlock) {
errorBlock();
}
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^(void) {
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]];
UIImage *image = [[UIImage alloc] initWithData:data];
dispatch_async( dispatch_get_main_queue(), ^(void){
if(image && successBlock) {
NSString *imageFilePath = [NSString stringWithFormat:@"%@/%@.jpg", YWCachePath, [urlString qmui_md5]];
//写入本地文件
if ([UIImageJPEGRepresentation(image, 1.0f) writeToFile:imageFilePath atomically:YES]) {
successBlock(image);
}
}else {
if (errorBlock) errorBlock();
}
});
});
}
// 读取缓存图片
+ (UIImage *)getImageWithImageUrl:(NSString *)urlString {
if (!urlString) {
YWLog(@"暂无缓存数据");
return nil;
}
// 拼接缓存路径
NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.jpg", YWCachePath, [urlString qmui_md5]];
NSData *data = [NSData dataWithContentsOfFile:cachesPath];
if (data) {
UIImage *image = [[UIImage alloc] initWithData:data];
if (image) {
return image;
}
}
YWLog(@"暂无缓存数据");
return nil;
}
#pragma mark - 获取path路径下文件夹大小
+ (NSString *)getCacheSizeWithFilePath:(NSString *)path {
// 如果传入的路径为空,则直接统计 默认路径:YWCachePath 的缓存
if (!path || [path isEqualToString:@""]) {
path = YWCachePath;
}
// 获取“path”文件夹下的所有文件
NSArray *subPathArr = [[NSFileManager defaultManager] subpathsAtPath:path];
NSString *filePath = nil;
NSInteger totleSize = 0;
for (NSString *subPath in subPathArr){
// 1. 拼接每一个文件的全路径
filePath =[path stringByAppendingPathComponent:subPath];
// 2. 是否是文件夹,默认不是
BOOL isDirectory = NO;
// 3. 判断文件是否存在
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory];
// 4. 以上判断目的是忽略不需要计算的文件
if (!isExist || isDirectory || [filePath containsString:@".DS"]){
// 过滤: 1. 文件夹不存在 2. 过滤文件夹 3. 隐藏文件
continue;
}
// 5. 指定路径,获取这个路径的属性
NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
/**
attributesOfItemAtPath: 文件夹路径
该方法只能获取文件的属性, 无法获取文件夹属性, 所以也是需要遍历文件夹的每一个文件的原因
*/
// 6. 获取每一个文件的大小
NSInteger size = [dict[@"NSFileSize"] integerValue];
// 7. 计算总大小
totleSize += size;
}
//8. 将文件夹大小转换为 M/KB/B
NSString *totleStr = totleSize ? [self getBytesFromDataLength:totleSize] : @"0.00MB";
return totleStr;
}
#pragma mark - 清除path文件夹下缓存大小
+ (BOOL)clearCacheWithFilePath:(NSString *)path{
// 如果传入的路径为空,则直接清除 默认路径:YWCachePath 的缓存
if (!path || [path isEqualToString:@""]) {
path = YWCachePath;
}
//拿到path路径的下一级目录的子文件夹
NSArray *subPathArr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSString *filePath = nil;
NSError *error = nil;
if (!subPathArr) {
// 直接清理指定路径下的文件
[[NSFileManager defaultManager] removeItemAtPath:path error:&error];
}else {
for (NSString *subPath in subPathArr) {
filePath = [path stringByAppendingPathComponent:subPath];
if (![filePath containsString:@"/Caches/Snapshots"]) {
//删除子文件
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
}
}
}
if (!error) {
YWLog(@"缓存清除成功");
return YES;
}
YWLog(@"缓存清除失败,错误信息:%@",error);
return NO;
}
+ (NSString *)getBytesFromDataLength:(NSInteger)dataLength {
NSString *bytes;
if (dataLength >= 0.5 * (1024 * 1024 * 1024)) {
bytes = [NSString stringWithFormat:@"%0.2fGB",dataLength/1024/1024.0/1024.0];
} else if (dataLength >= 0.5 * (1024 * 1024)) {
bytes = [NSString stringWithFormat:@"%0.2fMB",dataLength/1024/1024.0];
} else if (dataLength >= 1024) {
bytes = [NSString stringWithFormat:@"%0.2fKB",dataLength/1024.0];
} else {
bytes = [NSString stringWithFormat:@"%zdB",dataLength];
}
return bytes;
}
#pragma mark - * * * * * private * * * * *
// 检查文件夹是否存在
+ (BOOL)checkFolderIsExistsWithFilePath:(NSString *)path {
// 如果传入的路径为空,则直接清除 默认路径:YWCachePath 的缓存
if (!path || [path isEqualToString:@""]) {
path = YWCachePath;
}
// 创建一个文件管理器
NSFileManager *manager = [NSFileManager defaultManager];
// 检查文件夹是否存在
BOOL isExists = [manager fileExistsAtPath:path];
if (!isExists) {
// 创建文件夹
return [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
return YES;
}
@end
网友评论