-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImageCache.m
167 lines (109 loc) · 4.12 KB
/
ImageCache.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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
//
// ImageCache.m
//
// Licensed by ruralcoder.com under the
// Creative Commons Attribution-ShareAlike 3.0 Unported License
#import "ImageCache.h"
#import "ImageCacheDelegate.h"
#import "Application.h"
#import "NSStringExtension.h"
#import "ImageObservers.h"
#import "Observer.h"
#define MAX_AGE_OF_CACHED_FILE 15 // days
#define SECONDS_IN_A_DAY 86400 // seconds
static NSString *cachePath = nil;
@interface ImageCache ()
@property (nonatomic, readonly) NSFileManager *fs;
@property (nonatomic, retain) NSMutableDictionary *observers;
@end
@implementation ImageCache
@synthesize observers;
+ (ImageCache*) instance
{
@synchronized(self)
{
static ImageCache *singleton = nil;
if (singleton)
return singleton;
singleton = [[ImageCache alloc] init];
return singleton;
}
}
- (NSFileManager *)fs
{
return [NSFileManager defaultManager];
}
+ (id) fileInImagesCache:(id)filename withExtension:(id)extension
{
if (cachePath == nil)
cachePath = [[Application fileInCache:@"images"] retain];
NSString *absolutePath = [cachePath stringByAppendingPathComponent:filename];
if (extension && [extension length] > 0)
absolutePath = [absolutePath stringByAppendingPathExtension:extension];
return absolutePath;
}
- (id) init
{
self = [super init];
self.observers = [NSMutableDictionary dictionary];
NSString *imagesPath = [Application fileInCache:@"images"];
if ([self.fs fileExistsAtPath:imagesPath] == NO)
{
[self.fs createDirectoryAtPath:imagesPath
withIntermediateDirectories:YES
attributes:nil
error:nil];
}
return self;
}
+ (UIImage*) imageFromCacheWithUrl:(NSURL*)url cookie:(id)object target:(id)target
{
if (url == nil)
return nil;
// Client can be null is the case where no events are needed (e.g. building caches of categories)
// IndexPath can be null in the case of the business details image in the header.
NSString *digest = [[url absoluteString] digest];
NSString *absolutePath = [ImageCache fileInImagesCache:digest withExtension:[url pathExtension]];
NSFileManager *fs = [NSFileManager defaultManager];
NSData *cachedData = nil;
BOOL needsFetching = YES;
if ([fs fileExistsAtPath:absolutePath])
{
cachedData = [NSData dataWithContentsOfFile:absolutePath];
NSDictionary *attributes = [fs attributesOfItemAtPath:absolutePath error:nil];
NSDate *timestamp = [attributes objectForKey:NSFileCreationDate];
NSTimeInterval ageInSecs = [[NSDate date] timeIntervalSinceDate:timestamp ];
double ageInDays = (ageInSecs / SECONDS_IN_A_DAY);
needsFetching = (ageInDays > MAX_AGE_OF_CACHED_FILE);
AppLog(@"INFO: File '%@' age %.1f days", digest, ageInDays);
if (cachedData == nil)
return nil;
return [UIImage imageWithData:cachedData];
}
if (needsFetching)
{
ImageCache *cacher = [ImageCache instance];
ImageObservers *imageObservers = [cacher.observers objectForKey:url];
if (imageObservers == nil)
{
imageObservers = [ImageObservers createObserverWithFilename:absolutePath andUrl:url];
[cacher.observers setObject:imageObservers forKey:url];
}
Observer *observer = [Observer createObserverWithTarget:target andCookie:object];
[imageObservers addObserver:observer];
[imageObservers start];
}
return nil;
}
+ (UIImage*) imageFromCacheWithUrl:(NSURL*)url
{
if (url == nil)
return nil;
NSString *digest = [[url absoluteString] digest];
NSString *absolutePath = [ImageCache fileInImagesCache:digest withExtension:[url pathExtension]];
if ([[NSFileManager defaultManager] fileExistsAtPath:absolutePath] == NO)
return nil;
NSData *data = [NSData dataWithContentsOfFile:absolutePath];
return [UIImage imageWithData:data];
}
@end