Digital PCT265 story MVAPCT-48 - Minor cache code cleanup

This commit is contained in:
Scott Pfeil 2024-03-27 13:38:13 -04:00
parent 3b410fb522
commit 4bdd93dbe5
3 changed files with 73 additions and 77 deletions

View File

@ -46,60 +46,51 @@ public class CachedData: Codable {
} }
} }
@objc public class DataCacheManager: NSObject { @objc public class PersistentCacheManager: NSObject {
@objc public static let shared = DataCacheManager() @objc public static let shared = PersistentCacheManager()
// private let cache = NSCache<NSString, CachedData>() private let fileManager = FileManager.default
private let fileManager = FileManager.default private lazy var documentsDirectory = { fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! }()
private lazy var documentsDirectory = { fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! }()
public override init() {} private override init() {}
@objc public func save(data: [String: AnyHashable], forKey key: String, cacheDuration: TimeInterval, shouldPersist: Bool = true) throws { @objc public func save(data: [String: AnyHashable], forKey key: String, expirationDate: Date) throws {
let expirationDate = Date().addingTimeInterval(cacheDuration) let cachedData = CachedData(data: data, expirationDate: expirationDate)
let cachedData = CachedData(data: data, expirationDate: expirationDate) let filePath = self.filePath(forKey: key)
// cache.setObject(cachedData, forKey: NSString(string: key)) do {
if shouldPersist { let dataToSave = try JSONEncoder().encode(cachedData)
let filePath = self.filePath(forKey: key) try dataToSave.write(to: filePath, options: .atomicWrite)
do { } catch let error as EncodingError {
let dataToSave = try JSONEncoder().encode(cachedData) throw CacheError.serializationFailed
try dataToSave.write(to: filePath, options: .atomicWrite) } catch {
} catch let error as EncodingError { throw CacheError.saveFailed(error)
throw CacheError.serializationFailed }
} catch {
throw CacheError.saveFailed(error)
}
} }
}
@objc public func load(forKey key: String) throws -> [String: AnyHashable] { @objc public func load(forKey key: String) throws -> [String: AnyHashable] {
let keyNSString = NSString(string: key) let keyNSString = NSString(string: key)
// if let cachedObject = cache.object(forKey: keyNSString), let filePath = self.filePath(forKey: key)
// Date() < cachedObject.expirationDate { do {
// return cachedObject.data let data = try Data(contentsOf: filePath)
// } else { let decodedCachedData = try JSONDecoder().decode(CachedData.self, from: data)
let filePath = self.filePath(forKey: key) if Date() < decodedCachedData.expirationDate {
do { return decodedCachedData.data
let data = try Data(contentsOf: filePath) } else {
let decodedCachedData = try JSONDecoder().decode(CachedData.self, from: data) MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: EXPIRED, key:\(key)")
if Date() < decodedCachedData.expirationDate { throw CacheError.dataExpired
// cache.setObject(decodedCachedData, forKey: keyNSString) }
return decodedCachedData.data } catch {
} else { // Remove item from the cache on any failure.
throw CacheError.dataExpired try fileManager.removeItem(at: filePath)
}
} catch { switch error {
// Remove item from the cache on any failure. case is DecodingError:
try fileManager.removeItem(at: filePath) throw CacheError.deserializationFailed
default:
throw CacheError.loadFailed(error)
}
}
}
switch error {
case is DecodingError:
throw CacheError.deserializationFailed
default:
throw CacheError.loadFailed(error)
}
}
// }
}
@objc public func remove(forKey key: String) throws { @objc public func remove(forKey key: String) throws {
let filePath = self.filePath(forKey: key) let filePath = self.filePath(forKey: key)
try fileManager.removeItem(at: filePath) try fileManager.removeItem(at: filePath)
@ -109,12 +100,13 @@ public class CachedData: Codable {
let fileURLs = try fileManager.contentsOfDirectory(at: documentsDirectory, let fileURLs = try fileManager.contentsOfDirectory(at: documentsDirectory,
includingPropertiesForKeys: nil, includingPropertiesForKeys: nil,
options: .skipsHiddenFiles) options: .skipsHiddenFiles)
for fileURL in fileURLs where fileURL.pathExtension == "json" {
try FileManager.default.removeItem(at: fileURL) for fileURL in fileURLs where fileURL.pathExtension == "json" {
} try FileManager.default.removeItem(at: fileURL)
}
} }
private func filePath(forKey key: String) -> URL { private func filePath(forKey key: String) -> URL {
return documentsDirectory.appendingPathComponent("\(key).json") return documentsDirectory.appendingPathComponent("\(key).json")
} }
} }

View File

@ -40,7 +40,7 @@ typedef void(^MVMCoreGetImageBlock)(UIImage * _Nullable, NSData * _Nullable, BOO
- (BOOL)isJSONExpired:(nonnull NSDictionary *)jsonDictionary; - (BOOL)isJSONExpired:(nonnull NSDictionary *)jsonDictionary;
/// Returns the expiry time for the object. /// Returns the expiry time for the object.
- (NSTimeInterval)getExpiryForJSON:(nonnull NSDictionary *)jsonDictionary; - (nonnull NSDate *)getExpirationDateForJSON:(nonnull NSDictionary *)jsonDictionary;
/// Checks if the page is to be persistently cached. /// Checks if the page is to be persistently cached.
- (BOOL)shouldPersistentlyCachePage:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType; - (BOOL)shouldPersistentlyCachePage:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType;
@ -94,7 +94,10 @@ typedef void(^MVMCoreGetImageBlock)(UIImage * _Nullable, NSData * _Nullable, BOO
- (void)addModulesToCache:(nonnull NSDictionary *)jsonDictionary; - (void)addModulesToCache:(nonnull NSDictionary *)jsonDictionary;
/// Adds the json to the persistent cache by pageType. /// Adds the json to the persistent cache by pageType.
- (void)addPageToPersistentCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType expiry:(NSTimeInterval)expiry; - (void)addPageToPersistentCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType expirationDate:(nonnull NSDate *)expirationDate;
/// Adds the json to the persistent cache by module.
- (void)addModuleToPersistentCache:(nonnull NSDictionary *)jsonDictionary moduleName:(nonnull NSString *)moduleName expirationDate:(nonnull NSDate *)expirationDate;
#pragma mark - Advanced Insertion #pragma mark - Advanced Insertion

View File

@ -104,17 +104,18 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
} }
- (BOOL)isJSONExpired:(nonnull NSDictionary *)jsonDictionary { - (BOOL)isJSONExpired:(nonnull NSDictionary *)jsonDictionary {
NSTimeInterval expiryTime = [self getExpiryForJSON:jsonDictionary]; NSDate *expirationDate = [self getExpirationDateForJSON:jsonDictionary];
NSTimeInterval timeSinceUnixEpoc = [[NSDate date] timeIntervalSince1970]; NSDate *today = [NSDate date];
if (timeSinceUnixEpoc > expiryTime) { if (today > expirationDate) {
[MVMCoreLoggingHandler logDebugMessageWithDelegate:[NSString stringWithFormat:@"CACHEDFEED: EXPIRED %@ %@ %f %f",[jsonDictionary stringForKey:KeyPageType],[jsonDictionary stringForKey:@"moduleName"],timeSinceUnixEpoc,expiryTime]]; [MVMCoreLoggingHandler logDebugMessageWithDelegate:[NSString stringWithFormat:@"CACHEDFEED: NEW DATA ALREADY EXPIRED %@ %@ %@ %@",[jsonDictionary stringForKey:KeyPageType],[jsonDictionary stringForKey:@"moduleName"],today,expirationDate]];
} }
return timeSinceUnixEpoc > expiryTime; return today > expirationDate;
} }
- (NSTimeInterval)getExpiryForJSON:(nonnull NSDictionary *)jsonDictionary { - (nonnull NSDate *)getExpirationDateForJSON:(nonnull NSDictionary *)jsonDictionary {
NSDictionary *cachePolicy = [jsonDictionary dict:@"cachePolicy"]; NSDictionary *cachePolicy = [jsonDictionary dict:@"cachePolicy"];
return [[cachePolicy dict:@"expiry"] doubleValue] * 1000.0; NSTimeInterval interval = [[cachePolicy string:@"expiry"] doubleValue] / 1000;
return [NSDate dateWithTimeIntervalSince1970:interval];
} }
- (BOOL)shouldPersistentlyCacheJSON:(nonnull NSDictionary *)jsonDictionary { - (BOOL)shouldPersistentlyCacheJSON:(nonnull NSDictionary *)jsonDictionary {
@ -161,12 +162,12 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
- (NSDictionary * _Nullable)fetchPageFromPersistentCache:(nonnull NSString *)pageType { - (NSDictionary * _Nullable)fetchPageFromPersistentCache:(nonnull NSString *)pageType {
NSError *error = nil; NSError *error = nil;
return [[DataCacheManager shared] loadForKey:pageType error:&error]; return [[PersistentCacheManager shared] loadForKey:pageType error:&error];
} }
- (NSDictionary * _Nullable)fetchModuleFromPersistentCache:(nonnull NSString *)moduleName { - (NSDictionary * _Nullable)fetchModuleFromPersistentCache:(nonnull NSString *)moduleName {
NSError *error = nil; NSError *error = nil;
return [[DataCacheManager shared] loadForKey:moduleName error:&error]; return [[PersistentCacheManager shared] loadForKey:moduleName error:&error];
} }
#pragma mark - Advanced Fetch #pragma mark - Advanced Fetch
@ -258,14 +259,14 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
[self addModulesToCache:jsonDictionary queue:nil waitUntilFinished:NO completionBlock:NULL]; [self addModulesToCache:jsonDictionary queue:nil waitUntilFinished:NO completionBlock:NULL];
} }
- (void)addPageToPersistentCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType expiry:(NSTimeInterval)expiry { - (void)addPageToPersistentCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType expirationDate:(nonnull NSDate *)expirationDate {
NSError *error = nil; NSError *error = nil;
[[DataCacheManager shared] saveWithData:jsonDictionary forKey:pageType cacheDuration:expiry shouldPersist:YES error:&error]; [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:pageType expirationDate:expirationDate error:&error];
} }
- (void)addModuleToPersistentCache:(nonnull NSDictionary *)jsonDictionary moduleName:(nonnull NSString *)moduleName expiry:(NSTimeInterval)expiry { - (void)addModuleToPersistentCache:(nonnull NSDictionary *)jsonDictionary moduleName:(nonnull NSString *)moduleName expirationDate:(nonnull NSDate *)expirationDate {
NSError *error = nil; NSError *error = nil;
[[DataCacheManager shared] saveWithData:jsonDictionary forKey:moduleName cacheDuration:expiry shouldPersist:YES error:&error]; [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:moduleName expirationDate:expirationDate error:&error];
} }
#pragma mark - Advanced Insertion #pragma mark - Advanced Insertion
@ -297,10 +298,10 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
[weakSelf.pageTypeCache setObject:jsonDictionary forKey:pageType]; [weakSelf.pageTypeCache setObject:jsonDictionary forKey:pageType];
if (![self shouldPersistentlyCachePage:jsonDictionary pageType:pageType]) { if (![self shouldPersistentlyCachePage:jsonDictionary pageType:pageType]) {
[[DataCacheManager shared] removeForKey:pageType error:nil]; [[PersistentCacheManager shared] removeForKey:pageType error:nil];
return; return;
} }
[self addPageToPersistentCache:jsonDictionary pageType:pageType expiry:[self getExpiryForJSON:jsonDictionary]]; [self addPageToPersistentCache:jsonDictionary pageType:pageType expirationDate:[self getExpirationDateForJSON:jsonDictionary]];
} }
} }
if (completionBlock) { if (completionBlock) {
@ -333,10 +334,10 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
[weakSelf.moduleCache setObject:jsonDictionary forKey:module]; [weakSelf.moduleCache setObject:jsonDictionary forKey:module];
if (![self shouldPersistentlyCacheModule:jsonDictionary module:module]) { if (![self shouldPersistentlyCacheModule:jsonDictionary module:module]) {
[[DataCacheManager shared] removeForKey:module error:nil]; [[PersistentCacheManager shared] removeForKey:module error:nil];
return; return;
} }
[self addModuleToPersistentCache:jsonDictionary moduleName:module expiry:[self getExpiryForJSON:jsonDictionary]]; [self addModuleToPersistentCache:jsonDictionary moduleName:module expirationDate:[self getExpirationDateForJSON:jsonDictionary]];
} }
if (completionBlock) { if (completionBlock) {
[(queue ?: weakSelf.completionQueue) addOperations:@[[NSBlockOperation blockOperationWithBlock:completionBlock]] waitUntilFinished:waitUntilFinished]; [(queue ?: weakSelf.completionQueue) addOperations:@[[NSBlockOperation blockOperationWithBlock:completionBlock]] waitUntilFinished:waitUntilFinished];
@ -372,7 +373,7 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
} }
- (void)clearPersistentJSONCache { - (void)clearPersistentJSONCache {
[[DataCacheManager shared] removeAllAndReturnError:nil]; [[PersistentCacheManager shared] removeAllAndReturnError:nil];
} }
- (void)clearMFCache { - (void)clearMFCache {
@ -412,7 +413,7 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
} }
}]; }];
[self.pageTypeQueue addOperations:@[removeOperation] waitUntilFinished:waitUntilFinished]; [self.pageTypeQueue addOperations:@[removeOperation] waitUntilFinished:waitUntilFinished];
[[DataCacheManager shared] removeForKey:pageType error:nil]; [[PersistentCacheManager shared] removeForKey:pageType error:nil];
} }
- (void)removeJSONForModule:(nonnull NSString *)module queue:(nullable NSOperationQueue *)queue waitUntilFinished:(BOOL)waitUntilFinished completionBlock:(nullable void (^)(void))completionBlock { - (void)removeJSONForModule:(nonnull NSString *)module queue:(nullable NSOperationQueue *)queue waitUntilFinished:(BOOL)waitUntilFinished completionBlock:(nullable void (^)(void))completionBlock {
@ -436,7 +437,7 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
} }
}]; }];
[self.moduleQueue addOperations:@[removeOperation] waitUntilFinished:waitUntilFinished]; [self.moduleQueue addOperations:@[removeOperation] waitUntilFinished:waitUntilFinished];
[[DataCacheManager shared] removeForKey:module error:nil]; [[PersistentCacheManager shared] removeForKey:module error:nil];
} }
- (void)removeJSONForModules:(nonnull NSArray *)modules queue:(nullable NSOperationQueue *)queue waitUntilFinished:(BOOL)waitUntilFinished completionBlock:(nullable void (^)(void))completionBlock { - (void)removeJSONForModules:(nonnull NSArray *)modules queue:(nullable NSOperationQueue *)queue waitUntilFinished:(BOOL)waitUntilFinished completionBlock:(nullable void (^)(void))completionBlock {
@ -456,7 +457,7 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
// Removes json from cache with module key. // Removes json from cache with module key.
[weakSelf.moduleCache removeObjectForKey:obj]; [weakSelf.moduleCache removeObjectForKey:obj];
} }
[[DataCacheManager shared] removeForKey:obj error:nil]; [[PersistentCacheManager shared] removeForKey:obj error:nil];
} }
}]; }];
if (completionBlock) { if (completionBlock) {