From c59dd703487462989f5eba382116ce827e78315f Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Thu, 15 Feb 2024 22:15:22 -0500 Subject: [PATCH 1/3] Fallback response JSON handling. --- .../ActionOpenPageHandler.swift | 23 +++++++++++++++++++ .../ActionHandling/ActionOpenPageModel.swift | 4 ++++ .../MVMCore/LoadHandling/MVMCoreLoadObject.h | 6 ++++- .../MVMCoreLoadRequestOperation.h | 3 +++ .../MVMCoreLoadRequestOperation.m | 3 ++- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift index 2f79085..0cafd24 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift @@ -34,12 +34,35 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol { continuation.resume() } } + + if operation.error != nil, let fallbackResponseJson = model.fallbackResponse?.toJSON() { + await runFallback(response: fallbackResponseJson, requestParameters: requestParameters, delegateObject: delegateObject) + } } } catch { try handle(error: error, model: model, delegateObject: delegateObject) } } + /// Given backup JSON data, run it through the load handler. + fileprivate func runFallback(response: JSONDictionary, requestParameters: MVMCoreRequestParameters, delegateObject: DelegateObject?) async { + guard let loadHandler = MVMCoreLoadHandler.sharedGlobal(), let fallbackLoadObject = MVMCoreLoadObject(requestParameters: requestParameters, dataForPage: nil, delegateObject: delegateObject) + else { return } + + let (loadObject, errorObject) = await MVMCoreLoadRequestOperation.processJSON(fromServer: response, loadObject: fallbackLoadObject) + + if let errorObject { + MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject) + } else { + let operation = loadHandler.loadObject(loadObject) + await withCheckedContinuation { continuation in + operation.completionBlock = { + continuation.resume() + } + } + } + } + open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { guard let model = model as? ActionOpenPageModel else { return } do { diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift index 34308ef..c8362a8 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift @@ -27,6 +27,7 @@ public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, public var background: Bool? public var clientParameters: ClientParameterModel? public var customTimeoutTime: TimeInterval? + public var fallbackResponse: JSONValueDictionary? public var requestParameters: MVMCoreRequestParameters @@ -67,6 +68,7 @@ public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, case background case clientParameters case customTimeoutTime + case fallbackResponse } public init(from decoder: Decoder) throws { @@ -83,6 +85,7 @@ public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, customTimeoutTime = try typeContainer.decodeIfPresent(TimeInterval.self, forKey: .customTimeoutTime) extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters) analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData) + fallbackResponse = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .fallbackResponse) requestParameters = MVMCoreRequestParameters(pageType: pageType, additionalModules: modules ?? [], extraParameters: extraParameters.toJSON())! requestParameters.contextRoot = appContext @@ -110,5 +113,6 @@ public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, try container.encodeIfPresent(customTimeoutTime, forKey: .customTimeoutTime) try container.encodeIfPresent(extraParameters, forKey: .extraParameters) try container.encodeIfPresent(analyticsData, forKey: .analyticsData) + try container.encodeIfPresent(fallbackResponse, forKey: .fallbackResponse) } } diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h index 72875fa..0cdc847 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadObject.h @@ -11,6 +11,7 @@ #import #import #import +#import @class MVMCoreLoadRequestOperation; @class MVMCoreRequestParameters; @@ -58,9 +59,12 @@ // The full response json @property (nullable, strong, nonatomic) NSDictionary *responseJSON; -//Unique Identifier for event tracking +// Unique Identifier for event tracking @property (nullable, strong, nonatomic) NSString *identifier; +// If any error happened during the load. +@property (nullable, strong, nonatomic) MVMCoreErrorObject *error; + - (nullable instancetype)initWithPageJSON:(nullable NSDictionary *)pageJSON modulesJSON:(nullable NSDictionary *)modulesJSON requestParameters:(nullable MVMCoreRequestParameters *)requestParameters dataForPage:(nullable NSDictionary *)dataForPage delegateObject:(nullable DelegateObject *)delegateObject; - (nullable instancetype)initWithRequestParameters:(nullable MVMCoreRequestParameters *)requestParameters dataForPage:(nullable NSDictionary *)dataForPage delegateObject:(nullable DelegateObject *)delegateObject; diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h index 1f2bce5..fa034e9 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h @@ -19,6 +19,7 @@ @interface MVMCoreLoadRequestOperation : MVMCoreOperation @property (nullable, strong, nonatomic) MVMCoreRequestParameters *requestParameters; +/// For load objects as in input parameter. Does not attach self generated load objects. @property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject; @property (nullable, strong, nonatomic) NSDictionary *dataForPage; @property (nullable, strong, nonatomic) DelegateObject *delegateObject; @@ -27,6 +28,8 @@ @property (nonatomic) BOOL backgroundLoad; @property (nonatomic, getter=areDependenciesAdded) BOOL dependenciesAdded; @property (nonnull, nonatomic, strong) NSString *identifier; +/// If any error happened during the operation. +@property (nullable, strong, nonatomic) MVMCoreErrorObject *error; /// Legacy flag for if this operation will have an alert to show when finished. @property (nonatomic, readonly) BOOL alertToShow; diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index e2ab27b..149bc54 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -856,7 +856,8 @@ //make post load calls function [MVMCoreLoadRequestOperation loadPostCallActions:loadObject]; [MVMCoreLoadRequestOperation loadPostAction:loadObject delegateObject:delegateObject]; - + loadObject.error = errorObject; + loadObject.operation.error = errorObject; [loadObject.operation markAsFinished]; } From 1e487dd58b37f9ecb023eec4bed51511e02eefda Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Wed, 21 Feb 2024 17:54:49 -0500 Subject: [PATCH 2/3] Address code review comment of piping data for page. --- MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift index 92f1057..0af8bcd 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift @@ -36,7 +36,7 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol { } if operation.error != nil, let fallbackResponseJson = model.fallbackResponse?.toJSON() { - await runFallback(response: fallbackResponseJson, requestParameters: requestParameters, delegateObject: delegateObject) + await runFallback(response: fallbackResponseJson, requestParameters: requestParameters, delegateObject: delegateObject, additionalData: additionalData) } } } catch { @@ -45,8 +45,8 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol { } /// Given backup JSON data, run it through the load handler. - fileprivate func runFallback(response: JSONDictionary, requestParameters: MVMCoreRequestParameters, delegateObject: DelegateObject?) async { - guard let loadHandler = MVMCoreLoadHandler.sharedGlobal(), let fallbackLoadObject = MVMCoreLoadObject(requestParameters: requestParameters, dataForPage: nil, delegateObject: delegateObject) + fileprivate func runFallback(response: JSONDictionary, requestParameters: MVMCoreRequestParameters, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async { + guard let loadHandler = MVMCoreLoadHandler.sharedGlobal(), let fallbackLoadObject = MVMCoreLoadObject(requestParameters: requestParameters, dataForPage: additionalData, delegateObject: delegateObject) else { return } let (loadObject, errorObject) = await MVMCoreLoadRequestOperation.processJSON(fromServer: response, loadObject: fallbackLoadObject) From 0c8012d40f9bfc775d7d6870ef7899b7ec534595 Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Wed, 21 Feb 2024 17:55:39 -0500 Subject: [PATCH 3/3] Reverse assigning the loadObject identifier to the operation. (self.identifer will always be nil on init.) --- MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index 149bc54..4563544 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -53,7 +53,7 @@ - (nullable instancetype)initWithLoadObject:(nullable MVMCoreLoadObject *)loadObject backgroundLoad:(BOOL)backgroundLoad { if (self = [self initWithRequestParameters:loadObject.requestParameters dataForPage:loadObject.dataForPage delegateObject:loadObject.delegateObject backgroundLoad:backgroundLoad]) { - loadObject.identifier = self.identifier; + self.identifier = loadObject.identifier; self.loadObject = loadObject; } return self;