From 931d10f45ae062dd9536bbaa90a8a49f4bd59213 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 5 Mar 2021 17:23:06 -0500 Subject: [PATCH] enhancement --- .../ActionHandling/MVMCoreActionHandler.h | 2 +- .../ActionHandling/MVMCoreActionHandler.m | 21 +++--- .../LoadHandling/MVMCoreRequestParameters.h | 2 - .../ClientParameterProtocol.swift | 45 ++++++++++++- .../ClientParameterRegistry.swift | 64 +++++++++---------- 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h index 616eb03..d46fa63 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h @@ -97,7 +97,7 @@ extern NSString * _Nonnull const KeyActionTypeOpen; + (void)defaultLogAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; /// Sends the request to the load handler. -+ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; ++ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; /// By default, throws an error, calling defaultHandleActionError. + (void)defaultHandleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 285b522..8b9a3aa 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -162,14 +162,14 @@ NSString * const KeyActionTypeOpen = @"openPage"; } MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionInformation]; - - requestParameters.clientParamters = [actionInformation dict:KeyClientParameters]; - [self updateRequestParametersBeforeHandleOpenPageAction:requestParameters callBack:^(MVMCoreRequestParameters * _Nonnull requestParameters) { if ([delegateObject.actionDelegate respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) { [delegateObject.actionDelegate handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData]; } else { - [MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters additionalData:additionalData delegateObject:delegateObject]; + [MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters + actionInformation:actionInformation + additionalData:additionalData + delegateObject:delegateObject]; } }]; } @@ -268,7 +268,10 @@ NSString * const KeyActionTypeOpen = @"openPage"; if ([delegateObject.actionDelegate respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) { [delegateObject.actionDelegate handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:dataForPage]; } else { - [MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters additionalData:additionalData delegateObject:delegateObject]; + [MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters + actionInformation:actionInformation + additionalData:additionalData + delegateObject:delegateObject]; } }]; }]; @@ -417,9 +420,11 @@ NSString * const KeyActionTypeOpen = @"openPage"; // Currently no default log action but this will eventually be server driven. } -+ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { - if (requestParameters.clientParamters) { - [[MVMCoreActionHandler sharedActionHandler] getClientParameter:requestParameters.clientParamters ++ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { + + NSDictionary *clientParamters = [actionInformation dict:KeyClientParameters]; + if (clientParamters) { + [[MVMCoreActionHandler sharedActionHandler] getClientParameter:clientParamters requestParameters: requestParameters.parameters showLoadingOverlay: !requestParameters.backgroundRequest completionHandler: ^(NSDictionary * _Nullable jsonDictionary) { diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h index 705fc2b..2e52a05 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h @@ -89,8 +89,6 @@ typedef NS_ENUM(NSInteger, MFLoadStyle) { // If the request was created with an action map. @property (nullable, strong, nonatomic) NSDictionary *actionMap; -@property (nullable, strong, nonatomic) NSDictionary *clientParamters; - @property (nullable, strong, nonatomic) NSNumber *customTimeoutTime; // Will open support panel at the end of the load. diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index 62c543a..487f7c6 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -9,7 +9,48 @@ import Foundation public protocol ClientParameterProtocol { - init() static var name: String { get } - func fetchClientParameters(for paramModel: ClientParameterModelProtocol, requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) + + init() + init(_ clientParameterModel:ClientParameterModelProtocol) + + var isFlatMap: Bool { get } + var clientParameterModel:ClientParameterModelProtocol? { get set} + + func defaultErrorString() -> String + func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) + + /// The handler should call this methos to pass the paramter back to the caller. + func returnParameters(_ paramter: [String: AnyHashable]?, completionHandler: @escaping (AnyHashable?) -> ()) + + /// Default parameter for timout scenarios. It will use the protocol extension method bydefault. Can override to send custom values. + func defaultValue() -> AnyHashable +} + +public extension ClientParameterProtocol { + var isFlatMap: Bool { false } + + func defaultErrorString() -> String { + return "failed_to_collect" + } + + func defaultValue() -> AnyHashable { + return [Self.name: defaultErrorString()] + } + + init(_ clientParameterModel:ClientParameterModelProtocol) { + self.init() + self.clientParameterModel = clientParameterModel + } + + func returnParameters(_ parameter: [String: AnyHashable]?, completionHandler: @escaping (AnyHashable?) -> ()) { + guard let parameter = parameter else { + return completionHandler(nil) + } + if isFlatMap { + completionHandler(parameter) + } else { + completionHandler([Self.name :parameter]) + } + } } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index cfe5612..eebc552 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -23,9 +23,9 @@ import Foundation mapping[T.name] = handler } - open func createParametersHandler(_ actionType: String) -> ClientParameterProtocol? { - guard let parameterType = mapping[actionType] else { return nil } - return parameterType.init() + open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> ClientParameterProtocol? { + guard let parameterType = mapping[clientParameterModel.type] else { return nil } + return parameterType.init(clientParameterModel) } static func getClientParameterModel(_ clientParameters: [String: Any]) throws -> ClientParameterModel? { @@ -58,17 +58,32 @@ import Foundation let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") let group = DispatchGroup() - let defaultErrorString = "failed_to_collect." + //let defaultErrorString = "failed_to_collect." // Dispatch setup on queue to ensure setup is complete before completion callbacks. parametersWorkQueue.async(group: group, qos: .userInitiated) { [weak self] in guard let self = self else { return } - var returnedList: [[String: AnyHashable]] = [] + var parameterHandlerList: [ClientParameterProtocol] = [] + var returnedList = [[String: AnyHashable]](repeating: [:], count: clientParameterModel.list.count) + + // Create the handler list so that same object can be used when merging. Merging needs default value in case of timeout + for parameterModel in clientParameterModel.list { + if let parameterHandler = self.createParametersHandler(parameterModel) { + parameterHandlerList.append(parameterHandler) + } + } + var mergedParametersList: [String: AnyHashable] { var parametersList: [String: AnyHashable] = [:] + var index = 0 for item in returnedList { - parametersList = parametersList.merging(item) { (_, new) in new } + if item.count == 0, let defaultValue = parameterHandlerList[index].defaultValue() as? [String: AnyHashable] { + parametersList = parametersList.merging(defaultValue) { (_, new) in new } + } else { + parametersList = parametersList.merging(item) { (_, new) in new } + } + index += 1 } return parametersList } @@ -89,31 +104,22 @@ import Foundation // Setup timeout. parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem) - + // Setup the parameter execution. - for parameterModel in clientParameterModel.list { - // Setup default timeout / nil error. This will be replaced as parameters are collected. - if !(parameterModel.isFlatMap ?? false) { - returnedList.append([parameterModel.type: ["error": defaultErrorString]]) - } + var index = -1 + for parameterHandler in parameterHandlerList { group.enter() - - // Dispatch asynchronous injection. - self.getParameterFromHandler(parameterModel, - requestParameters: requestParameters, - before: timeout) { (receivedParameter) in - + index += 1 + parameterHandler.fetchClientParameters(requestParameters: requestParameters, + timingOutIn: timeout) { (receivedParameter) in // Queue the results for merge. parametersWorkQueue.async { - if parameterModel.isFlatMap ?? false, let receivedParameter = receivedParameter as? [String: AnyHashable] { - // parametersList = parametersList.merging(receivedParameter) { (_, new) in new } - returnedList.append(receivedParameter) - } else if let receivedParameter = receivedParameter { - returnedList.append([parameterModel.type: receivedParameter]) + if let receivedParameter = receivedParameter as? [String: AnyHashable] { + returnedList[index] = receivedParameter } group.leave() // Leaving is only done after setup (barriered). } - } + } } // Callback when all parameters have been merged. @@ -121,16 +127,6 @@ import Foundation } } - func getParameterFromHandler( _ parameterModel: ClientParameterModelProtocol, requestParameters: [String: Any], before timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) { - guard let parameterHandler = createParametersHandler(parameterModel.type) else { - return completionHandler(nil) - } - parameterHandler.fetchClientParameters(for: parameterModel, - requestParameters: requestParameters, - timingOutIn: timeout, - completionHandler: completionHandler) - } - /// Add all registry here. open func registerParameters() { }