Skip to content

Commit 997b084

Browse files
author
Jasper
committed
new
1 parent ac6357d commit 997b084

File tree

27 files changed

+782
-101
lines changed

27 files changed

+782
-101
lines changed

CYUtilProject/.DS_Store

2 KB
Binary file not shown.

CYUtilProject/CYCache/CYImageDownloader.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTas
8787

8888
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
8989

90-
if ([task isKindOfClass:[NSURLSessionDownloadTask class]]) {
90+
if ([task isKindOfClass:[NSURLSessionDownloadTask class]]
91+
&& error) {
9192

9293
NSURLRequest *request = task.originalRequest ? : task.currentRequest;
9394
CYImageDownloadCompletion completion = request.completion;

CYUtilProject/CYCache/CYPersistenceCache.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,23 @@
88

99
#import <UIKit/UIKit.h>
1010

11+
typedef NS_ENUM(NSInteger, CYPersistenceCachePolicy) {
12+
13+
// every other 30 days clear
14+
// all the file that more than 30 days which unread will be deleted
15+
CYPersistenceCachePolicyDefault,
16+
// CYPersistenceCachePolicyRemoveRestart,
17+
// CYPersistenceCachePolicyRemoveAfterDays,
18+
// CYPersistenceCachePolicyNoneRemove
19+
};
20+
1121
@interface CYPersistenceCache : NSCache
1222

1323
@property (nonatomic, strong, readonly) NSString *cacheNamespace;
24+
@property (nonatomic, assign, readonly) CYPersistenceCachePolicy cachePolicy;
1425

15-
- (id)initWithNamespace:(NSString *)ns;
26+
- (instancetype)initWithNamespace:(NSString *)ns;
27+
- (instancetype)initWithNamespace:(NSString *)ns cachePolicy:(CYPersistenceCachePolicy)cachePolicy;
1628

1729
- (void)setImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
1830
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;

CYUtilProject/CYCache/CYPersistenceCache.m

Lines changed: 146 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import <CommonCrypto/CommonDigest.h>
1010
#import <UIKit/UIKit.h>
11+
#import <sys/xattr.h>
1112

1213
#import "CYPersistenceCache.h"
1314

@@ -24,24 +25,33 @@ - (instancetype)init {
2425
return [self initWithNamespace:nil];
2526
}
2627

27-
- (id)initWithNamespace:(NSString *)ns {
28+
- (instancetype)initWithNamespace:(NSString *)ns {
2829

30+
return [self initWithNamespace:ns cachePolicy:CYPersistenceCachePolicyDefault];
31+
}
32+
33+
- (instancetype)initWithNamespace:(NSString *)ns cachePolicy:(CYPersistenceCachePolicy)cachePolicy {
34+
2935
if (self = [super init]) {
30-
36+
3137
_cacheNamespace = ns;
32-
38+
_cachePolicy = cachePolicy;
39+
3340
if (!_cacheNamespace) {
34-
41+
3542
_cacheNamespace = @"default";
3643
}
37-
44+
3845
NSString *fullNamespace = [NSString stringWithFormat:@"com.xiaoniuapp.cache.%@", _cacheNamespace];
3946
_diskCachePath = [self makeDiskCachePath:fullNamespace];
4047
self.totalCostLimit = 100 * 1024 * 1024;
48+
49+
[self startClearCacheAsyncIfNeeded];
4150
}
4251
return self;
4352
}
4453

54+
#pragma mark - save image
4555
- (void)setImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk {
4656
[self setObject:image forKey:key cost:(image.size.width * image.size.height * 8)];
4757

@@ -83,7 +93,7 @@ - (void)saveImageToDisk:(UIImage *)image forKey:(NSString *)key {
8393
}
8494

8595
NSString *savePath = [self defaultCachePathForKey:key];
86-
NSFileManager *manager = [NSFileManager defaultManager];
96+
NSFileManager *manager = [CYPersistenceCache persistanceSharedManager];
8797

8898
if (![manager fileExistsAtPath:_diskCachePath]) {
8999

@@ -99,7 +109,10 @@ - (void)saveImageToDisk:(UIImage *)image forKey:(NSString *)key {
99109
}
100110

101111
[manager createFileAtPath:savePath contents:imageData attributes:nil];
102-
112+
113+
// refresh last read date
114+
[self refreshFileLastReadDate:savePath];
115+
103116
// 不备份
104117
[[NSURL fileURLWithPath:savePath] setResourceValue:[NSNumber numberWithBool:YES]
105118
forKey:NSURLIsExcludedFromBackupKey
@@ -112,7 +125,7 @@ - (void)removeImageFromDiskForKey:(NSString *)key {
112125
return;
113126
}
114127
NSString *savePath = [self defaultCachePathForKey:key];
115-
NSFileManager *manager = [NSFileManager defaultManager];
128+
NSFileManager *manager = [CYPersistenceCache persistanceSharedManager];
116129
[manager removeItemAtPath:savePath error:NULL];
117130
}
118131

@@ -121,16 +134,69 @@ - (UIImage *)imageForKeyFromDisk:(NSString *)key {
121134
if (!key) {
122135
return nil;
123136
}
124-
137+
125138
NSString *savePath = [self defaultCachePathForKey:key];
126139
NSData *data = [NSData dataWithContentsOfFile:savePath];
127140
if (data) {
128-
141+
142+
// refresh read date
143+
[self refreshFileLastReadDate:savePath];
129144
return [UIImage imageWithData:data];
130145
}
131146
return nil;
132147
}
133148

149+
static NSString *const fileLastReadDateAttributeKey = @"kCYLastReadDate";
150+
- (void)refreshFileLastReadDate:(NSString *)filePath {
151+
152+
NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
153+
const char *value = [[NSString stringWithFormat:@"%.0f", time] UTF8String];
154+
setxattr([filePath fileSystemRepresentation],
155+
[fileLastReadDateAttributeKey UTF8String],
156+
value,
157+
strlen(value),
158+
0,
159+
0);
160+
}
161+
162+
- (NSDate *)fileLastReadDate:(NSString *)filePath {
163+
164+
const char *filePathC = [filePath fileSystemRepresentation];
165+
const char *attrName = [fileLastReadDateAttributeKey UTF8String];
166+
167+
// get size of needed buffer
168+
int bufferLength = getxattr(filePathC,
169+
attrName,
170+
NULL,
171+
0,
172+
0,
173+
0);
174+
175+
// make a buffer of sufficient length
176+
char *buffer = malloc(bufferLength);
177+
178+
// now actually get the attribute string
179+
getxattr(filePathC, attrName, buffer, 255, 0, 0);
180+
181+
// convert to NSString
182+
NSString *retString = [[NSString alloc] initWithBytes:buffer
183+
length:bufferLength
184+
encoding:NSUTF8StringEncoding];
185+
186+
// release buffer
187+
free(buffer);
188+
189+
if (retString) {
190+
191+
NSTimeInterval time = (NSTimeInterval)[retString doubleValue];
192+
if (time > 0) {
193+
194+
return [NSDate dateWithTimeIntervalSince1970:time];
195+
}
196+
}
197+
return nil;
198+
}
199+
134200
#pragma mark - private save path
135201
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path {
136202
NSString *filename = [self cachedFileNameForKey:key];
@@ -160,6 +226,76 @@ - (NSString *)makeDiskCachePath:(NSString*)fullNamespace{
160226
return [paths[0] stringByAppendingPathComponent:fullNamespace];
161227
}
162228

229+
#pragma mark - clear cache
230+
static NSString *const CYPersistenceCacheLastDeleteCacheDateKey = @"CYPersistenceCacheLastDeleteCacheDateKey";
231+
232+
- (void)startClearCacheAsyncIfNeeded {
233+
234+
NSDate *currentDate = [NSDate date];
235+
236+
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
237+
NSDate *lastDeleteDate = [userDefaults objectForKey:CYPersistenceCacheLastDeleteCacheDateKey];
238+
239+
if (!lastDeleteDate) {
240+
241+
// if haven't an last delete date, save now
242+
[userDefaults setObject:[NSDate date]
243+
forKey:CYPersistenceCacheLastDeleteCacheDateKey];
244+
[userDefaults synchronize];
245+
return;
246+
}
247+
// every other 30 days clear
248+
if (lastDeleteDate
249+
&& [lastDeleteDate isKindOfClass:[NSDate class]]
250+
&& [currentDate timeIntervalSinceDate:lastDeleteDate] > 30l * 24 * 60 * 60) {
251+
252+
[self clearCacheAsync];
253+
}
254+
}
255+
256+
- (void)clearCacheAsync {
257+
258+
NSDate *currentDate = [NSDate date];
259+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
260+
261+
NSFileManager *fileManager = [CYPersistenceCache persistanceSharedManager];
262+
// get file enumerator from current cache directory
263+
NSDirectoryEnumerator<NSString *> *enumerator = [fileManager enumeratorAtPath:self.diskCachePath];
264+
265+
// enumerate all cached file, remove the items that the last read date more than 30 days util now
266+
NSMutableArray *removeFile = [NSMutableArray array];
267+
NSString *filePath = nil;
268+
while ((filePath = enumerator.nextObject)) {
269+
270+
NSDate *lastReadDate = [self fileLastReadDate:filePath];
271+
if (lastReadDate
272+
&& [currentDate timeIntervalSinceDate:lastReadDate] > 30l * 24 * 60 * 60) {
273+
274+
[removeFile addObject:filePath];
275+
}
276+
}
277+
278+
// remove all the items which should delete
279+
[removeFile enumerateObjectsUsingBlock:^(NSString *path, NSUInteger idx, BOOL * _Nonnull stop) {
280+
281+
[fileManager removeItemAtPath:path
282+
error:nil];
283+
}];
284+
});
285+
}
286+
287+
#pragma mark - static file manager
288+
+ (NSFileManager *)persistanceSharedManager {
289+
290+
static NSFileManager *fileManager = nil;
291+
static dispatch_once_t onceToken;
292+
dispatch_once(&onceToken, ^ {
293+
294+
fileManager = [[NSFileManager alloc] init];
295+
});
296+
return fileManager;
297+
}
298+
163299
#pragma mark - default cache
164300
+ (instancetype)defaultCache {
165301

CYUtilProject/CYCache/CYWebImageCache.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ - (void)imageWithURL:(NSURL *)url
6363
UIImage *cachedImage = [_persistenceCache imageForKey:url.absoluteString];
6464
if (cachedImage) {
6565

66-
if (completion){
66+
if (completion) {
6767

6868
dispatch_async(dispatch_get_main_queue(), ^{
6969

CYUtilProject/CYDeviceUtils/CYDeviceUtils.h

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,36 @@
88

99
#import <Foundation/Foundation.h>
1010

11-
typedef NS_ENUM(NSInteger, CYDeviceScreenType) {
12-
13-
CYDeviceScreenType_Unknown, // 未知
14-
CYDeviceScreenType_3_5, // 3.5寸屏
15-
CYDeviceScreenType_4_0, // 4寸屏
16-
CYDeviceScreenType_4_7, // 4.7寸屏
17-
CYDeviceScreenType_5_5, // 5.5寸屏
18-
CYDeviceScreenType_iPad // ipad屏
19-
};
11+
//typedef NS_ENUM(NSInteger, CYDeviceScreenType) {
12+
//
13+
// CYDeviceScreenType_Unknown, // 未知
14+
// CYDeviceScreenType_3_5, // 3.5寸屏
15+
// CYDeviceScreenType_4_0, // 4寸屏
16+
// CYDeviceScreenType_4_7, // 4.7寸屏
17+
// CYDeviceScreenType_5_5, // 5.5寸屏
18+
// CYDeviceScreenType_iPad // ipad屏
19+
//};
2020

2121
@interface CYDeviceUtils : NSObject
2222

23-
// 当前设备屏幕尺寸类型,详见CYDeviceScreenType
24-
+ (CYDeviceScreenType)currentDeviceScreenType;
25-
26-
// 屏幕长边的长度
27-
+ (CGFloat)screenLongerSideLength;
28-
// 屏幕短边的长度
29-
+ (CGFloat)screenShorterSideLength;
30-
31-
// 屏幕宽度
32-
+ (CGFloat)screenWidth;
33-
34-
// 屏幕高度
35-
+ (CGFloat)screenHeight;
36-
37-
// 当前设备系统是否为8.0或更新
38-
+ (BOOL)systemIsIos8AndLater;
39-
40-
// 当前app版本号
41-
+ (NSString *)currentAppVersion;
23+
//// 当前设备屏幕尺寸类型,详见CYDeviceScreenType
24+
//+ (CYDeviceScreenType)currentDeviceScreenType;
25+
//
26+
//// 屏幕长边的长度
27+
//+ (CGFloat)screenLongerSideLength;
28+
//// 屏幕短边的长度
29+
//+ (CGFloat)screenShorterSideLength;
30+
//
31+
//// 屏幕宽度
32+
//+ (CGFloat)screenWidth;
33+
//
34+
//// 屏幕高度
35+
//+ (CGFloat)screenHeight;
36+
//
37+
//// 当前设备系统是否为8.0或更新
38+
//+ (BOOL)systemIsIos8AndLater;
39+
//
40+
//// 当前app版本号
41+
//+ (NSString *)currentAppVersion;
4242

4343
@end

0 commit comments

Comments
 (0)