Digital PCT265 story MVAPCT-48 - Initial demo of loading feed from cache
This commit is contained in:
parent
c636cc1ca4
commit
8c32dbbd7d
@ -96,6 +96,7 @@
|
||||
AF43A7411FC5FA6F008E9347 /* MVMCoreViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */; };
|
||||
AF4955E22BAB1EB200567276 /* MVMCoreCache+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF4955E12BAB1EB200567276 /* MVMCoreCache+Extension.swift */; };
|
||||
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F1289212CA00919EEB /* MVMError.swift */; };
|
||||
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F3289212EB00919EEB /* MVMCoreError.swift */; };
|
||||
AF686FDA2A8A876A008F666A /* NavigationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF686FD92A8A876A008F666A /* NavigationOperation.swift */; };
|
||||
@ -252,6 +253,7 @@
|
||||
AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewProtocol.h; sourceTree = "<group>"; };
|
||||
AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionObject.h; sourceTree = "<group>"; };
|
||||
AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionObject.m; sourceTree = "<group>"; };
|
||||
AF4955E12BAB1EB200567276 /* MVMCoreCache+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreCache+Extension.swift"; sourceTree = "<group>"; };
|
||||
AF60A7F1289212CA00919EEB /* MVMError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMError.swift; sourceTree = "<group>"; };
|
||||
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreError.swift; sourceTree = "<group>"; };
|
||||
AF686FD92A8A876A008F666A /* NavigationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationOperation.swift; sourceTree = "<group>"; };
|
||||
@ -656,6 +658,7 @@
|
||||
children = (
|
||||
AF43A7091FC4F415008E9347 /* MVMCoreCache.h */,
|
||||
AF43A7081FC4F415008E9347 /* MVMCoreCache.m */,
|
||||
AF4955E12BAB1EB200567276 /* MVMCoreCache+Extension.swift */,
|
||||
605A9A292ABD712F00487E47 /* MVMCoreLoggingHandler.swift */,
|
||||
6042E8FB2B3094680031644B /* MVMCoreLoggingHandlerHelper.h */,
|
||||
D288D5F426C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift */,
|
||||
@ -902,6 +905,7 @@
|
||||
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */,
|
||||
AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */,
|
||||
AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */,
|
||||
AF4955E22BAB1EB200567276 /* MVMCoreCache+Extension.swift in Sources */,
|
||||
016CF36925FA6DD400B82A1F /* ClientParameterHandler.swift in Sources */,
|
||||
5846ABF42B44BB9000FA6C76 /* Collection+Safe.swift in Sources */,
|
||||
AF69D4F7286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift in Sources */,
|
||||
|
||||
@ -383,8 +383,14 @@
|
||||
if (requestParameters.backgroundRequest) {
|
||||
return [self loadBackgroundRequest:requestParameters dataForPage:dataForPage delegateObject:delegateObject];
|
||||
} else {
|
||||
if (!requestParameters.noloadingOverlay) {
|
||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] startLoading];
|
||||
}
|
||||
MVMCoreLoadRequestOperation *loadOperation = [[MVMCoreLoadRequestOperation alloc] initWithRequestParameters:requestParameters dataForPage:dataForPage delegateObject:delegateObject backgroundLoad:NO];
|
||||
loadOperation.identifier = requestParameters.identifier;
|
||||
[loadOperation setCompletionBlock:^{
|
||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:YES];
|
||||
}];
|
||||
[self.blockingLoadQueue addOperation:loadOperation];
|
||||
return loadOperation;
|
||||
}
|
||||
|
||||
@ -38,6 +38,38 @@ public enum PopBackError: MVMError, CustomStringConvertible {
|
||||
|
||||
@objc
|
||||
public extension MVMCoreLoadRequestOperation {
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
func checkIfNewControllerIsNeeded(loadObject: MVMCoreLoadObject) -> Bool {
|
||||
guard loadObject.requestParameters?.replaceViewIfOnStackElseLoadWithStyle == true,
|
||||
let pageType = loadObject.pageType else {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Controller shouldn't be replaced.")
|
||||
return true
|
||||
}
|
||||
let newVC = MVMCoreViewControllerMappingObject.shared()?.createMFViewController(ofTemplate: loadObject.pageJSON?.optionalStringForKey("template"), pageType: pageType)
|
||||
guard let index = NavigationHandler.shared().navigationController?.viewControllers.firstIndex(where: { controller in
|
||||
(controller as? MVMCoreViewControllerProtocol)?.pageType == pageType && type(of: controller) == type(of: newVC)
|
||||
}) else {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: No matching controller found.")
|
||||
return true
|
||||
}
|
||||
if index == NavigationHandler.shared().navigationController!.viewControllers.count - 1 {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Controller is already showing.")
|
||||
Task {
|
||||
MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil)
|
||||
}
|
||||
} else {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Pop back to controller.")
|
||||
guard let operation = try? NavigationHandler.shared().getOperationPopToViewController(with: pageType, navigationController: loadObject.requestParameters?.navigationController, delegateObject: loadObject.delegateObject, animated: !(loadObject.requestParameters?.shouldNotAnimatePush ?? false)) else { return true }
|
||||
Task {
|
||||
await navigate(with: operation, loadObject: loadObject)
|
||||
MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@objc
|
||||
func popBackToPage(for loadObject: MVMCoreLoadObject) {
|
||||
Task(priority: .high) {
|
||||
|
||||
@ -90,6 +90,8 @@
|
||||
*/
|
||||
+ (void)removeCaches:(nullable NSDictionary *)cacheDictionary;
|
||||
|
||||
+ (void)notifyListenersOfNewResponse:(nullable NSDictionary *)pages modules:(nullable NSDictionary *)modules systemParameters:(nullable NSDictionary *)systemParameters loadObject:(nonnull MVMCoreLoadObject *)loadObject;
|
||||
|
||||
/** Creates the view controller based on the load object passed in.
|
||||
* @param loadObject The load data from the cache or server.
|
||||
* @param completionHandler The completion handler to load once finished. Returns any loaded view controller and the load.*/
|
||||
|
||||
@ -132,71 +132,74 @@
|
||||
} else {
|
||||
|
||||
// No provided load object, check the cache for data first..
|
||||
[MVMCoreLoadRequestOperation checkCacheForDataForRequest:self.requestParameters completionHandler:^(NSDictionary *pageFromCache, NSDictionary *modulesFromCache) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
|
||||
if ([self checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log if loaded from cache.
|
||||
if (pageFromCache) {
|
||||
MVMCoreLog(@"loaded from cache page %@",[MVMCoreActionUtility formatDictionaryAsJSONString:pageFromCache]);
|
||||
}
|
||||
if (modulesFromCache) {
|
||||
MVMCoreLog(@"loaded from cache modules %@",[MVMCoreActionUtility formatDictionaryAsJSONString:modulesFromCache]);
|
||||
}
|
||||
|
||||
// Create a load object from any data we fetched.
|
||||
MVMCoreLoadObject *loadObject = [self createLoadObjectWithPageFromCache:pageFromCache modulesFromCache:modulesFromCache];
|
||||
|
||||
// Check if we need to go to server for missing data.
|
||||
MVMCoreRequestParameters *requestForMissingData = [MVMCoreLoadRequestOperation createRequestForDataWithLoadObject:loadObject];
|
||||
if (!requestForMissingData) {
|
||||
[MVMCoreLoadRequestOperation checkCacheForDataForRequest:self.requestParameters completionHandler:^(NSDictionary *pageFromCache, NSDictionary *modulesFromCache) {
|
||||
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadCompleteFor:loadObject.requestParameters.pageType serverProcessingTime:@"0" requestURL:loadObject.requestParameters.URL.absoluteString requestUUID:loadObject.identifier isFromCache:loadObject.pageDataFromCache];
|
||||
|
||||
// We have all the needed data, continue with the load.
|
||||
[MVMCoreLoadRequestOperation handleLoadObject:loadObject error:nil];
|
||||
} else {
|
||||
|
||||
if(!self.backgroundLoad && loadObject.requestParameters.pageType) {
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadStartedFor:loadObject.requestParameters.pageType requestUUID:loadObject.identifier requestURL:loadObject.requestParameters.URL.absoluteString];
|
||||
if ([self checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Send a new request to the server.
|
||||
[MVMCoreLoadRequestOperation sendRequest:requestForMissingData loadObject:loadObject completionHandler:^(NSDictionary * _Nullable json) {
|
||||
|
||||
|
||||
// Log if loaded from cache.
|
||||
if (pageFromCache) {
|
||||
MVMCoreLog(@"loaded from cache page %@",[MVMCoreActionUtility formatDictionaryAsJSONString:pageFromCache]);
|
||||
}
|
||||
if (modulesFromCache) {
|
||||
MVMCoreLog(@"loaded from cache modules %@",[MVMCoreActionUtility formatDictionaryAsJSONString:modulesFromCache]);
|
||||
}
|
||||
|
||||
// Create a load object from any data we fetched.
|
||||
MVMCoreLoadObject *loadObject = [self createLoadObjectWithPageFromCache:pageFromCache modulesFromCache:modulesFromCache];
|
||||
|
||||
// Check if we need to go to server for missing data.
|
||||
MVMCoreRequestParameters *requestForMissingData = [MVMCoreLoadRequestOperation createRequestForDataWithLoadObject:loadObject];
|
||||
if (!requestForMissingData) {
|
||||
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadCompleteFor:loadObject.requestParameters.pageType serverProcessingTime:@"0" requestURL:loadObject.requestParameters.URL.absoluteString requestUUID:loadObject.identifier isFromCache:loadObject.pageDataFromCache];
|
||||
|
||||
// We have all the needed data, continue with the load.
|
||||
[MVMCoreLoadRequestOperation handleLoadObject:loadObject error:nil];
|
||||
} else {
|
||||
|
||||
if(!self.backgroundLoad && loadObject.requestParameters.pageType) {
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadStartedFor:loadObject.requestParameters.pageType requestUUID:loadObject.identifier requestURL:loadObject.requestParameters.URL.absoluteString];
|
||||
}
|
||||
|
||||
// Send a new request to the server.
|
||||
[MVMCoreLoadRequestOperation sendRequest:requestForMissingData loadObject:loadObject completionHandler:^(NSDictionary * _Nullable json) {
|
||||
|
||||
#if ENABLE_HARD_CODED_RESPONSE
|
||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(modifyJSON:)]) {
|
||||
json = [[MVMCoreObject sharedInstance].globalLoadDelegate modifyJSON:json];
|
||||
}
|
||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(modifyJSON:)]) {
|
||||
json = [[MVMCoreObject sharedInstance].globalLoadDelegate modifyJSON:json];
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString *serverProcessTime = [(NSDictionary *)json objectChainOfKeysOrIndexes:@[@"ResponseInfo", @"timeStamp"]] ?: @"0";
|
||||
|
||||
if(!self.backgroundLoad && loadObject.requestParameters.pageType && serverProcessTime) {
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadCompleteFor:loadObject.requestParameters.pageType serverProcessingTime:serverProcessTime requestURL:loadObject.requestParameters.URL.absoluteString requestUUID:loadObject.identifier isFromCache:loadObject.pageDataFromCache];
|
||||
}
|
||||
|
||||
// Process the data retrieved from the server.
|
||||
[MVMCoreLoadRequestOperation processJSONFromServer:json loadObject:loadObject completionHandler:^(MVMCoreLoadObject * _Nonnull loadObject, MVMCoreErrorObject * _Nullable error) {
|
||||
|
||||
if ([loadObject.operation checkAndHandleForCancellation]) {
|
||||
return;
|
||||
NSString *serverProcessTime = [(NSDictionary *)json objectChainOfKeysOrIndexes:@[@"ResponseInfo", @"timeStamp"]] ?: @"0";
|
||||
|
||||
if(!self.backgroundLoad && loadObject.requestParameters.pageType && serverProcessTime) {
|
||||
[[MVMCoreLoggingHandler sharedLoggingHandler] logPageLoadCompleteFor:loadObject.requestParameters.pageType serverProcessingTime:serverProcessTime requestURL:loadObject.requestParameters.URL.absoluteString requestUUID:loadObject.identifier isFromCache:loadObject.pageDataFromCache];
|
||||
}
|
||||
|
||||
if (loadObject.pageDataFromCache || loadObject.pageType) {
|
||||
// Process the data retrieved from the server.
|
||||
[MVMCoreLoadRequestOperation processJSONFromServer:json loadObject:loadObject completionHandler:^(MVMCoreLoadObject * _Nonnull loadObject, MVMCoreErrorObject * _Nullable error) {
|
||||
|
||||
// Can continue loading with the page.
|
||||
[MVMCoreLoadRequestOperation handleLoadObject:loadObject error:error];
|
||||
} else {
|
||||
// Something to show, or nothing was expected to show, can finish.
|
||||
[MVMCoreLoadRequestOperation loadFinished:loadObject loadedViewController:nil errorObject:error];
|
||||
}
|
||||
if ([loadObject.operation checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadObject.pageDataFromCache || loadObject.pageType) {
|
||||
|
||||
// Can continue loading with the page.
|
||||
[MVMCoreLoadRequestOperation handleLoadObject:loadObject error:error];
|
||||
} else {
|
||||
// Something to show, or nothing was expected to show, can finish.
|
||||
[MVMCoreLoadRequestOperation loadFinished:loadObject loadedViewController:nil errorObject:error];
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,9 +584,14 @@
|
||||
};
|
||||
|
||||
if (!error.nativeDrivenErrorScreen) {
|
||||
|
||||
// Server driven screen, create normally
|
||||
[MVMCoreLoadRequestOperation createViewControllerWithLoadObject:loadObject completionHandler:completionHandler];
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
if ([loadObject.operation checkIfNewControllerIsNeededWithLoadObject:loadObject]) {
|
||||
[MVMCoreDispatchUtility performBlockInBackground:^{
|
||||
[MVMCoreLoadRequestOperation createViewControllerWithLoadObject:loadObject completionHandler:completionHandler];
|
||||
}];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
// Get the proper native error screen from the delegate
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
|
||||
101
MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift
Normal file
101
MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift
Normal file
@ -0,0 +1,101 @@
|
||||
//
|
||||
// Cache.swift
|
||||
// JSONCreator
|
||||
//
|
||||
// Created by Matt Bruce on 3/20/24.
|
||||
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
public enum CacheError: Error {
|
||||
case serializationFailed
|
||||
case deserializationFailed
|
||||
case dataNotFound
|
||||
case dataExpired
|
||||
case saveFailed(Error)
|
||||
case loadFailed(Error)
|
||||
}
|
||||
|
||||
public class CachedData: Codable {
|
||||
public var data: [String: AnyHashable]
|
||||
public var expirationDate: Date
|
||||
enum CodingKeys: CodingKey {
|
||||
case data, expirationDate
|
||||
}
|
||||
|
||||
public init(data: [String: AnyHashable], expirationDate: Date) {
|
||||
self.data = data
|
||||
self.expirationDate = expirationDate
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(expirationDate, forKey: .expirationDate)
|
||||
let dataAsData = try JSONSerialization.data(withJSONObject: data, options: [])
|
||||
try container.encode(dataAsData, forKey: .data)
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
expirationDate = try values.decode(Date.self, forKey: .expirationDate)
|
||||
let dataAsData = try values.decode(Data.self, forKey: .data)
|
||||
guard let jsonData = try JSONSerialization.jsonObject(with: dataAsData, options: []) as? [String: AnyHashable] else {
|
||||
throw CacheError.deserializationFailed
|
||||
}
|
||||
data = jsonData
|
||||
}
|
||||
}
|
||||
|
||||
@objc public class DataCacheManager: NSObject {
|
||||
@objc public static let shared = DataCacheManager()
|
||||
// private let cache = NSCache<NSString, CachedData>()
|
||||
private let fileManager = FileManager.default
|
||||
private lazy var documentsDirectory = { fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! }()
|
||||
|
||||
public override init() {}
|
||||
|
||||
@objc public func save(data: [String: AnyHashable], forKey key: String, cacheDuration: TimeInterval, shouldPersist: Bool = true) throws {
|
||||
let expirationDate = Date().addingTimeInterval(cacheDuration)
|
||||
let cachedData = CachedData(data: data, expirationDate: expirationDate)
|
||||
// cache.setObject(cachedData, forKey: NSString(string: key))
|
||||
if shouldPersist {
|
||||
let filePath = self.filePath(forKey: key)
|
||||
do {
|
||||
let dataToSave = try JSONEncoder().encode(cachedData)
|
||||
try dataToSave.write(to: filePath, options: .atomicWrite)
|
||||
} catch let error as EncodingError {
|
||||
throw CacheError.serializationFailed
|
||||
} catch {
|
||||
throw CacheError.saveFailed(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func load(forKey key: String) throws -> [String: AnyHashable] {
|
||||
let keyNSString = NSString(string: key)
|
||||
// if let cachedObject = cache.object(forKey: keyNSString),
|
||||
// Date() < cachedObject.expirationDate {
|
||||
// return cachedObject.data
|
||||
// } else {
|
||||
let filePath = self.filePath(forKey: key)
|
||||
do {
|
||||
let data = try Data(contentsOf: filePath)
|
||||
let decodedCachedData = try JSONDecoder().decode(CachedData.self, from: data)
|
||||
if Date() < decodedCachedData.expirationDate {
|
||||
// cache.setObject(decodedCachedData, forKey: keyNSString)
|
||||
return decodedCachedData.data
|
||||
} else {
|
||||
throw CacheError.dataExpired
|
||||
}
|
||||
} catch let error as DecodingError {
|
||||
throw CacheError.deserializationFailed
|
||||
} catch {
|
||||
throw CacheError.loadFailed(error)
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private func filePath(forKey key: String) -> URL {
|
||||
return documentsDirectory.appendingPathComponent("\(key).json")
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,8 @@ typedef void(^MVMCoreGetImageBlock)(UIImage * _Nullable, NSData * _Nullable, BOO
|
||||
// Checks the set of modules to be cached for the given module
|
||||
- (BOOL)shouldCacheJSONWithModule:(nonnull NSString *)module;
|
||||
|
||||
- (BOOL)shouldPersistentlyCache:(nonnull NSDictionary *)jsonDictionary identifier:(nonnull NSString *)identifier;
|
||||
|
||||
// For pages external to the mobile first framework to be added to the list to not cache
|
||||
- (void)addPageTypesToNotCache:(nullable NSArray <NSString *>*)array;
|
||||
|
||||
|
||||
@ -39,6 +39,8 @@
|
||||
|
||||
@property (nullable, strong, nonatomic) NSCache *playerItemCache;
|
||||
|
||||
@property (nullable, strong, nonatomic) NSSet *itemsToPersist;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreCache
|
||||
@ -65,6 +67,8 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
|
||||
self.videoQueue = dispatch_queue_create("video_queue", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0));
|
||||
self.playerItemCache = [[NSCache alloc] init];
|
||||
|
||||
self.itemsToPersist = [NSSet setWithObjects:@"myFeed",@"FeedOrder",@"HabContent",@"launchModule",@"tabBar",@"DeepLinkService", nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -140,6 +144,10 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
|
||||
// First checks the cache by page type.
|
||||
dictionary = [weakSelf.pageTypeCache objectForKey:pageType];
|
||||
if (!dictionary) {
|
||||
NSError *error = nil;
|
||||
dictionary = [[DataCacheManager shared] loadForKey:pageType error:&error];
|
||||
}
|
||||
} else {
|
||||
|
||||
// If no pagetype, return whole cache
|
||||
@ -176,6 +184,12 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
NSDictionary *moduleDictionary = [weakSelf.moduleCache objectForKey:module];
|
||||
if (moduleDictionary) {
|
||||
[modulesDictionary setObject:moduleDictionary forKey:module];
|
||||
} else {
|
||||
NSError *error = nil;
|
||||
moduleDictionary = [[DataCacheManager shared] loadForKey:module error:&error];
|
||||
if (moduleDictionary) {
|
||||
[modulesDictionary setObject:moduleDictionary forKey:module];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,6 +220,13 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
[self addModulesToCache:jsonDictionary queue:nil waitUntilFinished:NO completionBlock:NULL];
|
||||
}
|
||||
|
||||
- (BOOL)shouldPersistentlyCache:(nonnull NSDictionary *)jsonDictionary identifier:(nonnull NSString *)identifier {
|
||||
if ([self.itemsToPersist containsObject:identifier]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Advanced Insertion
|
||||
|
||||
- (void)addPageToCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType queue:(nullable NSOperationQueue *)queue waitUntilFinished:(BOOL)waitUntilFinished completionBlock:(nullable void (^)(void))completionBlock {
|
||||
@ -230,6 +251,10 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
NSNumber *shouldCache = [jsonDictionary optionalNumberForKey:@"cache"];
|
||||
if (shouldCache == nil || shouldCache.boolValue) {
|
||||
[weakSelf.pageTypeCache setObject:jsonDictionary forKey:pageType];
|
||||
if ([self shouldPersistentlyCache:jsonDictionary identifier:pageType]) {
|
||||
NSError *error = nil;
|
||||
[[DataCacheManager shared] saveWithData:jsonDictionary forKey:pageType cacheDuration:604800 shouldPersist:YES error:&error];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -267,6 +292,11 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
|
||||
NSNumber *shouldCache = [jsonDictionary optionalNumberForKey:@"cache"];
|
||||
if (shouldCache == nil || shouldCache.boolValue) {
|
||||
[weakSelf.moduleCache setObject:obj forKey:key];
|
||||
|
||||
if ([self shouldPersistentlyCache:obj identifier:key]) {
|
||||
NSError *error = nil;
|
||||
[[DataCacheManager shared] saveWithData:obj forKey:key cacheDuration:604800 shouldPersist:YES error:&error];
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user