From 2ee96bf6d9e595eb078603c01c5edad226f842d3 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 19 Feb 2021 20:58:47 -0500 Subject: [PATCH 01/26] QIP --- .../ActionHandling/MVMCoreActionHandler.h | 2 +- .../ActionHandling/MVMCoreActionHandler.m | 54 ++++++++++++++----- .../LoadHandling/MVMCoreRequestParameters.h | 2 + .../ClientParameterProtocol.swift | 2 +- .../ClientParameterRegistry.swift | 19 ++++--- .../MFHardCodedServerResponse.h | 2 +- 6 files changed, 56 insertions(+), 25 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h index 2f41e93..6e272d4 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h @@ -32,7 +32,7 @@ extern NSString * _Nonnull const KeyActionTypeOpen; - (void)synchronouslyHandleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; /// Iterates through the clientParameters list. Gets values from the individual handlers and attaches the parameters to extraParameters. -- (void)setClientParameter:(nullable NSDictionary *)actionInformation completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler; +- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler; #pragma mark - Actions /// by default, returns the original RequestParameter that passed in. Can be overriden for some generic updates to the RequestParameter before handle open page action gets called. diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index ddb1fab..c7e3fc9 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -93,15 +93,15 @@ NSString * const KeyActionTypeOpen = @"openPage"; } } -- (void)setClientParameter:(nullable NSDictionary *)actionInformation completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler { +- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler { - NSDictionary *clientParametersMap = [actionInformation dict:KeyClientParameters]; + //NSDictionary *clientParametersMap = [actionInformation dict:KeyClientParameters]; if (!clientParametersMap) { - completionHandler(actionInformation); + completionHandler(nil); return; } - BOOL isBackgroudRequest = [actionInformation boolForKey:@"background"]; + // BOOL isBackgroudRequest = [actionInformation boolForKey:@"background"]; if (!isBackgroudRequest) { [[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] startLoading]; @@ -116,27 +116,28 @@ NSString * const KeyActionTypeOpen = @"openPage"; NSError *error = nil; [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Fetching client parameters"]; [[[MVMCoreObject sharedInstance] clientParameterRegistry] getParametersWith:clientParametersMap + requestParameters:requestParameters error:&error completionHandler:^(NSDictionary * _Nullable clientParameters) { [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Finshed fetching client parameters"]; if (clientParameters) { - NSMutableDictionary *actionWithClientParameters = [actionInformation mutableCopy]; - NSMutableDictionary *extraParameters = [clientParameters mutableCopy]; - [extraParameters addEntriesFromDictionary:[actionWithClientParameters dictionaryForKey:KeyExtraParameters]]; - actionWithClientParameters[KeyExtraParameters] = extraParameters; + // NSMutableDictionary *actionWithClientParameters = [actionInformation mutableCopy]; + // NSMutableDictionary *extraParameters = [clientParameters mutableCopy]; + // [extraParameters addEntriesFromDictionary:[actionWithClientParameters dictionaryForKey:KeyExtraParameters]]; + // actionWithClientParameters[KeyExtraParameters] = extraParameters; stopLoadingOverlay(); - completionHandler(actionWithClientParameters); + completionHandler(clientParameters); } else { [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"No client parameters"]; stopLoadingOverlay(); - completionHandler(actionInformation); + completionHandler(nil); } }]; if (error) { stopLoadingOverlay(); - completionHandler(actionInformation); + completionHandler(nil); [MVMCoreLoggingHandler addErrorToLog:[MVMCoreErrorObject createErrorObjectForNSError:error location:@"MVMCoreActionHandler->setClientParameter"]]; } } @@ -172,6 +173,8 @@ NSString * const KeyActionTypeOpen = @"openPage"; void (^performAction)(NSDictionary*) = ^(NSDictionary* actionMap) { MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionMap]; + requestParameters.clientParamters = [actionInformation dict:KeyClientParameters]; + [weakSelf updateRequestParametersBeforeHandleOpenPageAction:requestParameters callBack:^(MVMCoreRequestParameters * _Nonnull requestParameters) { if ([delegateObject.actionDelegate respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) { [delegateObject.actionDelegate handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData]; @@ -181,7 +184,10 @@ NSString * const KeyActionTypeOpen = @"openPage"; }]; }; - [self setClientParameter:actionInformation completionHandler:performAction]; + // + //[self setClientParameter:actionInformation completionHandler:performAction]; + + performAction(actionInformation); } - (void)shareAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { @@ -359,7 +365,11 @@ NSString * const KeyActionTypeOpen = @"openPage"; [weakSelf prepareLinkAwayWithURL:otherURL appURL:appURL actionInformation:actionMap additionalData:additionalData delegateObject:delegateObject]; }; - [self setClientParameter:actionInformation completionHandler:performAction]; + // [self setClientParameter:actionInformation completionHandler:performAction]; + [self setClientParameter:[actionInformation dict:KeyClientParameters] + requestParameters:nil + isBackgroudRequest:false + completionHandler:performAction]; } - (void)prepareLinkAwayWithURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { @@ -419,7 +429,23 @@ NSString * const KeyActionTypeOpen = @"openPage"; } + (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { - [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject]; + // + + void (^performRequest)(MVMCoreRequestParameters*) = ^(MVMCoreRequestParameters* requestParametersB) { + [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParametersB dataForPage:additionalData delegateObject:delegateObject]; + }; + + if (requestParameters.clientParamters) { + [[MVMCoreActionHandler sharedActionHandler] setClientParameter:requestParameters.clientParamters + requestParameters: requestParameters.parameters + isBackgroudRequest: NO + completionHandler: ^(NSDictionary * _Nullable jsonDictionary) { + [requestParameters addRequestParameters:jsonDictionary]; + performRequest(requestParameters); + }]; + } else { + performRequest(requestParameters); + } } + (void)defaultHandleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h index 2e52a05..705fc2b 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreRequestParameters.h @@ -89,6 +89,8 @@ 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 2c689ec..62c543a 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -11,5 +11,5 @@ import Foundation public protocol ClientParameterProtocol { init() static var name: String { get } - func fetchClientParameters(for paramModel: ClientParameterModelProtocol, timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) + func fetchClientParameters(for paramModel: ClientParameterModelProtocol, requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index 1a4160d..4c774c7 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -47,14 +47,14 @@ import Foundation /// ] ///} /// completionHandler can return flat dictinary or a map. It depends on the paramters handler - open func getParameters(with clientParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws { + open func getParameters(with clientParameters: [String: Any], requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws { guard let clientParameterModel = try ClientParameterRegistry.getClientParameterModel(clientParameters) else { completionHandler(nil) return } - var parametersList: [String: Any] = [:] + var parametersList: [String: AnyHashable] = [:] let timeout = clientParameterModel.timeout ?? 30.0 let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") @@ -87,15 +87,18 @@ import Foundation parametersList[parameterModel.type] = ["error": defaultErrorString] group.enter() // Dispatch asynchronous injection. - self.getParameterFromHandler(parameterModel, before: timeout) { (receivedParameter) in + self.getParameterFromHandler(parameterModel, + requestParameters: requestParameters, + before: timeout) { (receivedParameter) in // Queue the results for merge. parametersWorkQueue.async { - if let receivedParameter = receivedParameter { - parametersList[parameterModel.type] = receivedParameter + if let receivedParameter = receivedParameter as? [String: AnyHashable] { + //parametersList[parameterModel.type] = receivedParameter + parametersList = parametersList.merging(receivedParameter) { (_, new) in new } } group.leave() // Leaving is only done after setup (barriered). } - } + } } // Callback when all parameters have been merged. @@ -103,11 +106,11 @@ import Foundation } } - func getParameterFromHandler( _ parameterModel: ClientParameterModelProtocol, before timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) { + 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, timingOutIn: timeout, completionHandler: completionHandler) + parameterHandler.fetchClientParameters(for: parameterModel, requestParameters: requestParameters, timingOutIn: timeout, completionHandler: completionHandler) } /// Add all registry here. diff --git a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h index eb9fba9..efa33b6 100644 --- a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h +++ b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h @@ -9,7 +9,7 @@ #import #import "MVMCoreRequestParameters.h" -#define ENABLE_HARD_CODED_RESPONSE 0 && DEBUG +#define ENABLE_HARD_CODED_RESPONSE 1 && DEBUG #if ENABLE_HARD_CODED_RESPONSE From 301e16697100821db2ceab6ece0baa5721f083f2 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 1 Mar 2021 18:23:48 -0500 Subject: [PATCH 02/26] merge --- .../ClientParameterModelProtocol.swift | 5 +++ .../ClientParameterRegistry.swift | 34 ++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift index b742170..dfda709 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift @@ -10,10 +10,15 @@ import Foundation public protocol ClientParameterModelProtocol: ModelProtocol { var type: String { get } + var isFlatMap: Bool? { get } } public extension ClientParameterModelProtocol { + var isFlatMap: Bool? { + return false + } + var type: String { get { Self.identifier } } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index 4c774c7..cfe5612 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -54,7 +54,6 @@ import Foundation return } - var parametersList: [String: AnyHashable] = [:] let timeout = clientParameterModel.timeout ?? 30.0 let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") @@ -64,16 +63,26 @@ import Foundation // 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 mergedParametersList: [String: AnyHashable] { + var parametersList: [String: AnyHashable] = [:] + for item in returnedList { + parametersList = parametersList.merging(item) { (_, new) in new } + } + return parametersList + } + // Setup completion handlers. Barriered to ensure one happens after the other. var complete = false let timeoutWorkItem = DispatchWorkItem(qos: .userInitiated) { - completionHandler(parametersList); + completionHandler(mergedParametersList); complete = true } let completionWorkItem = DispatchWorkItem(qos: .userInitiated) { timeoutWorkItem.cancel() if !complete { // In the case of firing after timeout. - completionHandler(parametersList); + completionHandler(mergedParametersList); complete = true } } @@ -84,17 +93,23 @@ import Foundation // Setup the parameter execution. for parameterModel in clientParameterModel.list { // Setup default timeout / nil error. This will be replaced as parameters are collected. - parametersList[parameterModel.type] = ["error": defaultErrorString] + if !(parameterModel.isFlatMap ?? false) { + returnedList.append([parameterModel.type: ["error": defaultErrorString]]) + } group.enter() + // Dispatch asynchronous injection. self.getParameterFromHandler(parameterModel, requestParameters: requestParameters, before: timeout) { (receivedParameter) in + // Queue the results for merge. parametersWorkQueue.async { - if let receivedParameter = receivedParameter as? [String: AnyHashable] { - //parametersList[parameterModel.type] = receivedParameter - parametersList = parametersList.merging(receivedParameter) { (_, new) in new } + 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]) } group.leave() // Leaving is only done after setup (barriered). } @@ -110,7 +125,10 @@ import Foundation guard let parameterHandler = createParametersHandler(parameterModel.type) else { return completionHandler(nil) } - parameterHandler.fetchClientParameters(for: parameterModel, requestParameters: requestParameters, timingOutIn: timeout, completionHandler: completionHandler) + parameterHandler.fetchClientParameters(for: parameterModel, + requestParameters: requestParameters, + timingOutIn: timeout, + completionHandler: completionHandler) } /// Add all registry here. From b6c48edffd396e5ca736bdc20109524fffb3f75b Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 1 Mar 2021 18:28:02 -0500 Subject: [PATCH 03/26] remove hardcode --- .../Utility/HardCodedServerResponse/MFHardCodedServerResponse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h index efa33b6..eb9fba9 100644 --- a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h +++ b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h @@ -9,7 +9,7 @@ #import #import "MVMCoreRequestParameters.h" -#define ENABLE_HARD_CODED_RESPONSE 1 && DEBUG +#define ENABLE_HARD_CODED_RESPONSE 0 && DEBUG #if ENABLE_HARD_CODED_RESPONSE From 08142cb94568c39a56a201fc363273ba345fed79 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 2 Mar 2021 15:28:10 -0500 Subject: [PATCH 04/26] fix openurl --- .../ActionHandling/MVMCoreActionHandler.m | 25 ++++++++----------- .../MFHardCodedServerResponse.h | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index c7e3fc9..35fb29e 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -93,7 +93,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; } } -- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler { +- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable extraParameters))completionHandler { //NSDictionary *clientParametersMap = [actionInformation dict:KeyClientParameters]; if (!clientParametersMap) { @@ -121,11 +121,6 @@ NSString * const KeyActionTypeOpen = @"openPage"; completionHandler:^(NSDictionary * _Nullable clientParameters) { [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Finshed fetching client parameters"]; if (clientParameters) { - // NSMutableDictionary *actionWithClientParameters = [actionInformation mutableCopy]; - // NSMutableDictionary *extraParameters = [clientParameters mutableCopy]; - // [extraParameters addEntriesFromDictionary:[actionWithClientParameters dictionaryForKey:KeyExtraParameters]]; - // actionWithClientParameters[KeyExtraParameters] = extraParameters; - stopLoadingOverlay(); completionHandler(clientParameters); } else { @@ -184,9 +179,6 @@ NSString * const KeyActionTypeOpen = @"openPage"; }]; }; - // - //[self setClientParameter:actionInformation completionHandler:performAction]; - performAction(actionInformation); } @@ -346,26 +338,31 @@ NSString * const KeyActionTypeOpen = @"openPage"; - (void)linkAwayAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { __weak typeof(self) weakSelf = self; - void (^performAction)(NSDictionary*) = ^(NSDictionary* actionMap) { + void (^performAction)(NSDictionary*) = ^(NSDictionary* extraParamters) { + + NSMutableDictionary *actionWithClientParameters = [actionInformation mutableCopy]; + NSMutableDictionary *extraParametersT = [extraParamters mutableCopy]; + [extraParametersT addEntriesFromDictionary:[actionWithClientParameters dictionaryForKey:KeyExtraParameters]]; + actionWithClientParameters[KeyExtraParameters] = extraParametersT; + // Gets the app url NSURL *appURL = nil; - NSString *appURLString = [actionMap string:KeyLinkAwayAppURL]; + NSString *appURLString = [actionWithClientParameters string:KeyLinkAwayAppURL]; if (appURLString.length > 0) { appURL = [NSURL URLWithString:appURLString]; } // Gets the browser url NSURL *otherURL = nil; - NSString *otherURLString = [actionMap string:KeyLinkAwayURL]; + NSString *otherURLString = [actionWithClientParameters string:KeyLinkAwayURL]; if (otherURLString.length > 0) { otherURL = [NSURL URLWithString:otherURLString]; } // Provide the URL and App URL to be modified if needed by a subclass or delegate. - [weakSelf prepareLinkAwayWithURL:otherURL appURL:appURL actionInformation:actionMap additionalData:additionalData delegateObject:delegateObject]; + [weakSelf prepareLinkAwayWithURL:otherURL appURL:appURL actionInformation:actionWithClientParameters additionalData:additionalData delegateObject:delegateObject]; }; - // [self setClientParameter:actionInformation completionHandler:performAction]; [self setClientParameter:[actionInformation dict:KeyClientParameters] requestParameters:nil isBackgroudRequest:false diff --git a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h index eb9fba9..efa33b6 100644 --- a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h +++ b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h @@ -9,7 +9,7 @@ #import #import "MVMCoreRequestParameters.h" -#define ENABLE_HARD_CODED_RESPONSE 0 && DEBUG +#define ENABLE_HARD_CODED_RESPONSE 1 && DEBUG #if ENABLE_HARD_CODED_RESPONSE From 98f5f45322aebfc7c957fc936d2a2d89e0c8901f Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 3 Mar 2021 16:29:17 -0500 Subject: [PATCH 05/26] codereview --- .../ActionHandling/MVMCoreActionHandler.m | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 35fb29e..437faae 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -93,22 +93,19 @@ NSString * const KeyActionTypeOpen = @"openPage"; } } -- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable extraParameters))completionHandler { +- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable extraParameters))completionHandler { - //NSDictionary *clientParametersMap = [actionInformation dict:KeyClientParameters]; if (!clientParametersMap) { completionHandler(nil); return; } - - // BOOL isBackgroudRequest = [actionInformation boolForKey:@"background"]; - - if (!isBackgroudRequest) { + + if (showLoadingOverlay) { [[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] startLoading]; } void (^stopLoadingOverlay)(void) = ^(void) { - if (!isBackgroudRequest) { + if (showLoadingOverlay) { [[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:true]; } }; @@ -164,22 +161,17 @@ NSString * const KeyActionTypeOpen = @"openPage"; return; } - __weak typeof(self) weakSelf = self; - void (^performAction)(NSDictionary*) = ^(NSDictionary* actionMap) { - MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionMap]; + MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionInformation]; - requestParameters.clientParamters = [actionInformation dict:KeyClientParameters]; + requestParameters.clientParamters = [actionInformation dict:KeyClientParameters]; - [weakSelf 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]; - } - }]; - }; - - performAction(actionInformation); + [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]; + } + }]; } - (void)shareAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { @@ -365,7 +357,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; [self setClientParameter:[actionInformation dict:KeyClientParameters] requestParameters:nil - isBackgroudRequest:false + showLoadingOverlay:true completionHandler:performAction]; } @@ -435,7 +427,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; if (requestParameters.clientParamters) { [[MVMCoreActionHandler sharedActionHandler] setClientParameter:requestParameters.clientParamters requestParameters: requestParameters.parameters - isBackgroudRequest: NO + showLoadingOverlay: !requestParameters.backgroundRequest completionHandler: ^(NSDictionary * _Nullable jsonDictionary) { [requestParameters addRequestParameters:jsonDictionary]; performRequest(requestParameters); From 7006ea83dfd3842e6a3acc76ca734f3059585643 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 4 Mar 2021 14:17:20 -0500 Subject: [PATCH 06/26] fix --- .../ActionHandling/MVMCoreActionHandler.h | 2 +- .../ActionHandling/MVMCoreActionHandler.m | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h index 6e272d4..616eb03 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.h @@ -32,7 +32,7 @@ extern NSString * _Nonnull const KeyActionTypeOpen; - (void)synchronouslyHandleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; /// Iterates through the clientParameters list. Gets values from the individual handlers and attaches the parameters to extraParameters. -- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters isBackgroudRequest:(BOOL)isBackgroudRequest completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler; +- (void)getClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler; #pragma mark - Actions /// by default, returns the original RequestParameter that passed in. Can be overriden for some generic updates to the RequestParameter before handle open page action gets called. diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 437faae..285b522 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -93,7 +93,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; } } -- (void)setClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable extraParameters))completionHandler { +- (void)getClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable parameters))completionHandler { if (!clientParametersMap) { completionHandler(nil); @@ -355,7 +355,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; [weakSelf prepareLinkAwayWithURL:otherURL appURL:appURL actionInformation:actionWithClientParameters additionalData:additionalData delegateObject:delegateObject]; }; - [self setClientParameter:[actionInformation dict:KeyClientParameters] + [self getClientParameter:[actionInformation dict:KeyClientParameters] requestParameters:nil showLoadingOverlay:true completionHandler:performAction]; @@ -417,23 +417,17 @@ 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 { - // - - void (^performRequest)(MVMCoreRequestParameters*) = ^(MVMCoreRequestParameters* requestParametersB) { - [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParametersB dataForPage:additionalData delegateObject:delegateObject]; - }; - ++ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { if (requestParameters.clientParamters) { - [[MVMCoreActionHandler sharedActionHandler] setClientParameter:requestParameters.clientParamters + [[MVMCoreActionHandler sharedActionHandler] getClientParameter:requestParameters.clientParamters requestParameters: requestParameters.parameters showLoadingOverlay: !requestParameters.backgroundRequest completionHandler: ^(NSDictionary * _Nullable jsonDictionary) { [requestParameters addRequestParameters:jsonDictionary]; - performRequest(requestParameters); + [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject]; }]; } else { - performRequest(requestParameters); + [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject]; } } From 931d10f45ae062dd9536bbaa90a8a49f4bd59213 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 5 Mar 2021 17:23:06 -0500 Subject: [PATCH 07/26] 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() { } From c369958f5e5269c686eff67368125a55b39288a3 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 9 Mar 2021 14:22:13 -0500 Subject: [PATCH 08/26] review --- .../ClientParameterModelProtocol.swift | 5 ----- .../Client Parameters/ClientParameterProtocol.swift | 8 ++++---- .../Client Parameters/ClientParameterRegistry.swift | 11 +++-------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift index dfda709..b742170 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterModelProtocol.swift @@ -10,15 +10,10 @@ import Foundation public protocol ClientParameterModelProtocol: ModelProtocol { var type: String { get } - var isFlatMap: Bool? { get } } public extension ClientParameterModelProtocol { - var isFlatMap: Bool? { - return false - } - var type: String { get { Self.identifier } } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index 487f7c6..f6895e0 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -15,15 +15,15 @@ public protocol ClientParameterProtocol { init(_ clientParameterModel:ClientParameterModelProtocol) var isFlatMap: Bool { get } - var clientParameterModel:ClientParameterModelProtocol? { get set} + 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. + /// The handler should call this method to pass the parameter 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. + /// Default parameter for timeout scenarios. It will use the protocol extension method bydefault. Can override to send custom values. func defaultValue() -> AnyHashable } @@ -38,7 +38,7 @@ public extension ClientParameterProtocol { return [Self.name: defaultErrorString()] } - init(_ clientParameterModel:ClientParameterModelProtocol) { + init(_ clientParameterModel: ClientParameterModelProtocol) { self.init() self.clientParameterModel = clientParameterModel } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index eebc552..73644f9 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -58,7 +58,6 @@ import Foundation let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") let group = DispatchGroup() - //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 @@ -76,14 +75,12 @@ import Foundation var mergedParametersList: [String: AnyHashable] { var parametersList: [String: AnyHashable] = [:] - var index = 0 - for item in returnedList { + for (index, item) in returnedList.enumerated() { 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 } @@ -106,10 +103,8 @@ import Foundation parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem) // Setup the parameter execution. - var index = -1 - for parameterHandler in parameterHandlerList { - group.enter() - index += 1 + for (index, parameterHandler) in parameterHandlerList.enumerated() { + group.enter() parameterHandler.fetchClientParameters(requestParameters: requestParameters, timingOutIn: timeout) { (receivedParameter) in // Queue the results for merge. From 460d8b4dd9c02b5f2e133b683c230018be4e9b06 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 9 Mar 2021 16:56:48 -0500 Subject: [PATCH 09/26] review --- .../ClientParameterProtocol.swift | 31 +++++-------------- .../ClientParameterRegistry.swift | 10 +++--- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index f6895e0..a03f40d 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -11,39 +11,24 @@ import Foundation public protocol ClientParameterProtocol { static var name: String { get } - init() init(_ clientParameterModel:ClientParameterModelProtocol) - var isFlatMap: Bool { get } - var clientParameterModel: ClientParameterModelProtocol? { get set } + var clientParameterModel: ClientParameterModelProtocol { get set } - func defaultErrorString() -> String func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) - /// The handler should call this method to pass the parameter back to the caller. - func returnParameters(_ paramter: [String: AnyHashable]?, completionHandler: @escaping (AnyHashable?) -> ()) - /// Default parameter for timeout scenarios. It will use the protocol extension method bydefault. Can override to send custom values. - func defaultValue() -> AnyHashable + func valueOnTimeout() -> 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?) -> ()) { + func valueOnTimeout() -> AnyHashable { + return [Self.name: "failed_to_collect"] + } + + /// The handler should call this method to pass the parameter back to the caller. + func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable]?, completionHandler: @escaping (AnyHashable?) -> ()) { guard let parameter = parameter else { return completionHandler(nil) } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index 73644f9..3044a14 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -64,7 +64,7 @@ import Foundation guard let self = self else { return } var parameterHandlerList: [ClientParameterProtocol] = [] - var returnedList = [[String: AnyHashable]](repeating: [:], count: clientParameterModel.list.count) + var returnedList = [[String: AnyHashable]?](repeating: nil, 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 { @@ -76,10 +76,10 @@ import Foundation var mergedParametersList: [String: AnyHashable] { var parametersList: [String: AnyHashable] = [:] for (index, item) in returnedList.enumerated() { - if item.count == 0, let defaultValue = parameterHandlerList[index].defaultValue() as? [String: AnyHashable] { - parametersList = parametersList.merging(defaultValue) { (_, new) in new } - } else { + if let item = item { parametersList = parametersList.merging(item) { (_, new) in new } + } else if let defaultValue = parameterHandlerList[index].valueOnTimeout() as? [String: AnyHashable] { + parametersList = parametersList.merging(defaultValue) { (_, new) in new } } } return parametersList @@ -104,7 +104,7 @@ import Foundation // Setup the parameter execution. for (index, parameterHandler) in parameterHandlerList.enumerated() { - group.enter() + group.enter() parameterHandler.fetchClientParameters(requestParameters: requestParameters, timingOutIn: timeout) { (receivedParameter) in // Queue the results for merge. From 075ad5395388300bb28c739e19cbea276e5564a7 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 10 Mar 2021 11:20:36 -0500 Subject: [PATCH 10/26] fix --- .../ActionType/Client Parameters/ClientParameterProtocol.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index a03f40d..9d95876 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -11,7 +11,7 @@ import Foundation public protocol ClientParameterProtocol { static var name: String { get } - init(_ clientParameterModel:ClientParameterModelProtocol) + init(_ clientParameterModel: ClientParameterModelProtocol) var clientParameterModel: ClientParameterModelProtocol { get set } From ecac8ede70d0f7799fb6c8ac862980d4a9561e25 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 10 Mar 2021 13:03:44 -0500 Subject: [PATCH 11/26] map --- .../Client Parameters/ClientParameterProtocol.swift | 8 ++++---- .../Client Parameters/ClientParameterRegistry.swift | 7 +++---- .../HardCodedServerResponse/MFHardCodedServerResponse.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index 9d95876..0f6c843 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -15,20 +15,20 @@ public protocol ClientParameterProtocol { var clientParameterModel: ClientParameterModelProtocol { get set } - func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) + func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping ([String: AnyHashable]?) -> ()) /// Default parameter for timeout scenarios. It will use the protocol extension method bydefault. Can override to send custom values. - func valueOnTimeout() -> AnyHashable + func valueOnTimeout() -> [String: AnyHashable] } public extension ClientParameterProtocol { - func valueOnTimeout() -> AnyHashable { + func valueOnTimeout() -> [String: AnyHashable] { return [Self.name: "failed_to_collect"] } /// The handler should call this method to pass the parameter back to the caller. - func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable]?, completionHandler: @escaping (AnyHashable?) -> ()) { + func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable]?, completionHandler: @escaping ([String: AnyHashable]?) -> ()) { guard let parameter = parameter else { return completionHandler(nil) } diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index 3044a14..996dfbc 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -78,7 +78,8 @@ import Foundation for (index, item) in returnedList.enumerated() { if let item = item { parametersList = parametersList.merging(item) { (_, new) in new } - } else if let defaultValue = parameterHandlerList[index].valueOnTimeout() as? [String: AnyHashable] { + } else { + let defaultValue = parameterHandlerList[index].valueOnTimeout() parametersList = parametersList.merging(defaultValue) { (_, new) in new } } } @@ -109,9 +110,7 @@ import Foundation timingOutIn: timeout) { (receivedParameter) in // Queue the results for merge. parametersWorkQueue.async { - if let receivedParameter = receivedParameter as? [String: AnyHashable] { - returnedList[index] = receivedParameter - } + returnedList[index] = receivedParameter group.leave() // Leaving is only done after setup (barriered). } } diff --git a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h index efa33b6..eb9fba9 100644 --- a/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h +++ b/MVMCore/MVMCore/Utility/HardCodedServerResponse/MFHardCodedServerResponse.h @@ -9,7 +9,7 @@ #import #import "MVMCoreRequestParameters.h" -#define ENABLE_HARD_CODED_RESPONSE 1 && DEBUG +#define ENABLE_HARD_CODED_RESPONSE 0 && DEBUG #if ENABLE_HARD_CODED_RESPONSE From 4305b0a4da692793ad44ac22990f6e91b4089a32 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 10 Mar 2021 14:06:03 -0500 Subject: [PATCH 12/26] cleanup --- .../Client Parameters/ClientParameterProtocol.swift | 2 +- .../Client Parameters/ClientParameterRegistry.swift | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index 0f6c843..2cf156b 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -35,7 +35,7 @@ public extension ClientParameterProtocol { if isFlatMap { completionHandler(parameter) } else { - completionHandler([Self.name :parameter]) + 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 996dfbc..bfbbfd2 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -76,12 +76,8 @@ import Foundation var mergedParametersList: [String: AnyHashable] { var parametersList: [String: AnyHashable] = [:] for (index, item) in returnedList.enumerated() { - if let item = item { - parametersList = parametersList.merging(item) { (_, new) in new } - } else { - let defaultValue = parameterHandlerList[index].valueOnTimeout() - parametersList = parametersList.merging(defaultValue) { (_, new) in new } - } + let parameter = item ?? parameterHandlerList[index].valueOnTimeout() + parametersList = parametersList.merging(parameter) { (_, new) in new } } return parametersList } From 8ab8ada72d24d9168794010f3d3039cc095c01df Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 10 Mar 2021 17:06:21 -0500 Subject: [PATCH 13/26] fix --- .../ActionType/Client Parameters/ClientParameterRegistry.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index bfbbfd2..a211675 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -64,7 +64,6 @@ import Foundation guard let self = self else { return } var parameterHandlerList: [ClientParameterProtocol] = [] - var returnedList = [[String: AnyHashable]?](repeating: nil, 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 { @@ -73,6 +72,8 @@ import Foundation } } + var returnedList = [[String: AnyHashable]?](repeating: nil, count: parameterHandlerList.count) + var mergedParametersList: [String: AnyHashable] { var parametersList: [String: AnyHashable] = [:] for (index, item) in returnedList.enumerated() { From e05eb5ebbed6f04f0a43ec7e0e1cbf26781394c2 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 11 Mar 2021 15:21:24 -0500 Subject: [PATCH 14/26] handler fix --- MVMCore/MVMCore.xcodeproj/project.pbxproj | 4 + .../ActionHandling/MVMCoreActionHandler.m | 4 +- .../ClientParameterHandler.swift | 108 ++++++++++++++++++ .../ClientParameterRegistry.swift | 98 +--------------- 4 files changed, 116 insertions(+), 98 deletions(-) create mode 100644 MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift diff --git a/MVMCore/MVMCore.xcodeproj/project.pbxproj b/MVMCore/MVMCore.xcodeproj/project.pbxproj index 449ae7c..a3ac7c6 100644 --- a/MVMCore/MVMCore.xcodeproj/project.pbxproj +++ b/MVMCore/MVMCore.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 016CF36925FA6DD400B82A1F /* ClientParameterHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016CF36825FA6DD400B82A1F /* ClientParameterHandler.swift */; }; 016FF6EE259A4E6300F5E4AA /* ClientParameterModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016FF6ED259A4E6300F5E4AA /* ClientParameterModelProtocol.swift */; }; 016FF6F2259A4FCC00F5E4AA /* ClientParameterModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016FF6F1259A4FCC00F5E4AA /* ClientParameterModel.swift */; }; 016FF6F6259B9AED00F5E4AA /* ClientParameterRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016FF6F5259B9AED00F5E4AA /* ClientParameterRegistry.swift */; }; @@ -152,6 +153,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 016CF36825FA6DD400B82A1F /* ClientParameterHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientParameterHandler.swift; sourceTree = ""; }; 016FF6ED259A4E6300F5E4AA /* ClientParameterModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientParameterModelProtocol.swift; sourceTree = ""; }; 016FF6F1259A4FCC00F5E4AA /* ClientParameterModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientParameterModel.swift; sourceTree = ""; }; 016FF6F5259B9AED00F5E4AA /* ClientParameterRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientParameterRegistry.swift; sourceTree = ""; }; @@ -309,6 +311,7 @@ 016FF6ED259A4E6300F5E4AA /* ClientParameterModelProtocol.swift */, 016FF6F1259A4FCC00F5E4AA /* ClientParameterModel.swift */, 016FF6F5259B9AED00F5E4AA /* ClientParameterRegistry.swift */, + 016CF36825FA6DD400B82A1F /* ClientParameterHandler.swift */, 01934FE625A4FFC2003DCD67 /* ClientParameterActionProtocol.swift */, ); path = "Client Parameters"; @@ -857,6 +860,7 @@ AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */, AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */, AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */, + 016CF36925FA6DD400B82A1F /* ClientParameterHandler.swift in Sources */, AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */, 0AFF597A23FC6E60005C24E8 /* ActionShareModel.swift in Sources */, AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */, diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 8b9a3aa..8072091 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -112,7 +112,9 @@ NSString * const KeyActionTypeOpen = @"openPage"; NSError *error = nil; [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Fetching client parameters"]; - [[[MVMCoreObject sharedInstance] clientParameterRegistry] getParametersWith:clientParametersMap + + ClientParameterHandler* clientParameterHandler = [[ClientParameterHandler alloc] init]; + [clientParameterHandler getParametersWith:clientParametersMap requestParameters:requestParameters error:&error completionHandler:^(NSDictionary * _Nullable clientParameters) { diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift new file mode 100644 index 0000000..083724c --- /dev/null +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift @@ -0,0 +1,108 @@ +// +// ClientParameterHandler.swift +// MVMCore +// +// Created by Suresh, Kamlesh on 3/11/21. +// Copyright © 2021 myverizon. All rights reserved. +// + +import Foundation + + +@objcMembers open class ClientParameterHandler: NSObject { + + var parameterHandlerList: [ClientParameterProtocol] = [] + let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter", autoreleaseFrequency: .workItem) + //DispatchQueue(label: "com.mva.clientparameter") + let group = DispatchGroup() + + open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> ClientParameterProtocol? { + guard let parameterType = MVMCoreObject.sharedInstance()?.clientParameterRegistry?.mapping[clientParameterModel.type] else { return nil } + return parameterType.init(clientParameterModel) + } + + func getClientParameterModel(_ clientParameters: [String: Any]) throws -> ClientParameterModel? { + let data = try JSONSerialization.data(withJSONObject: clientParameters) + return try JSONDecoder().decode(ClientParameterModel.self, from: data) + } + + /// Sample clientParameters + ///{ + /// "timeout": 30, + /// "list": [ + /// { + /// "type": "currentLocation", + /// "inputParameters": { + /// "accuracy": 10, + /// "timeThreshold": 600 + /// } + /// } + /// ] + ///} + /// completionHandler can return flat dictinary or a map. It depends on the paramters handler + open func getParameters(with clientParameters: [String: Any], requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws { + + guard let clientParameterModel = try getClientParameterModel(clientParameters) else { + completionHandler(nil) + return + } + + let timeout = clientParameterModel.timeout ?? 30.0 + + + // Dispatch setup on queue to ensure setup is complete before completion callbacks. + parametersWorkQueue.async(group: group, qos: .userInitiated) { + // 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) { + self.parameterHandlerList.append(parameterHandler) + } + } + + var returnedList = [[String: AnyHashable]?](repeating: nil, count: self.parameterHandlerList.count) + + var mergedParametersList: [String: AnyHashable] { + var parametersList: [String: AnyHashable] = [:] + for (index, item) in returnedList.enumerated() { + let parameter = item ?? self.parameterHandlerList[index].valueOnTimeout() + parametersList = parametersList.merging(parameter) { (_, new) in new } + } + return parametersList + } + + // Setup completion handlers. Barriered to ensure one happens after the other. + var complete = false + let timeoutWorkItem = DispatchWorkItem(qos: .userInitiated) { + // Holding self. so that its not deallocated in the deispatch queue + completionHandler(mergedParametersList); + complete = true + } + let completionWorkItem = DispatchWorkItem(qos: .userInitiated) { + timeoutWorkItem.cancel() + if !complete { // In the case of firing after timeout. + completionHandler(mergedParametersList); + complete = true + } + } + + // Setup timeout. + self.parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem) + + // Setup the parameter execution. + for (index, parameterHandler) in self.parameterHandlerList.enumerated() { + self.group.enter() + parameterHandler.fetchClientParameters(requestParameters: requestParameters, + timingOutIn: timeout) { (receivedParameter) in + // Queue the results for merge. + self.parametersWorkQueue.async { + returnedList[index] = receivedParameter + self.group.leave() // Leaving is only done after setup (barriered). + } + } + } + + // Callback when all parameters have been merged. + self.group.notify(queue: self.parametersWorkQueue, work: completionWorkItem); + } + } +} diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index a211675..bfb9410 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -11,8 +11,7 @@ import Foundation @objcMembers open class ClientParameterRegistry: NSObject { - private var mapping: [String: ClientParameterProtocol.Type] = [:] - + var mapping: [String: ClientParameterProtocol.Type] = [:] public override init() { super.init() @@ -23,101 +22,6 @@ import Foundation mapping[T.name] = handler } - 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? { - let data = try JSONSerialization.data(withJSONObject: clientParameters) - return try JSONDecoder().decode(ClientParameterModel.self, from: data) - } - - /// Sample clientParameters - ///{ - /// "timeout": 30, - /// "list": [ - /// { - /// "type": "currentLocation", - /// "inputParameters": { - /// "accuracy": 10, - /// "timeThreshold": 600 - /// } - /// } - /// ] - ///} - /// completionHandler can return flat dictinary or a map. It depends on the paramters handler - open func getParameters(with clientParameters: [String: Any], requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws { - - guard let clientParameterModel = try ClientParameterRegistry.getClientParameterModel(clientParameters) else { - completionHandler(nil) - return - } - - let timeout = clientParameterModel.timeout ?? 30.0 - - let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") - let group = DispatchGroup() - - // 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 parameterHandlerList: [ClientParameterProtocol] = [] - - // 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 returnedList = [[String: AnyHashable]?](repeating: nil, count: parameterHandlerList.count) - - var mergedParametersList: [String: AnyHashable] { - var parametersList: [String: AnyHashable] = [:] - for (index, item) in returnedList.enumerated() { - let parameter = item ?? parameterHandlerList[index].valueOnTimeout() - parametersList = parametersList.merging(parameter) { (_, new) in new } - } - return parametersList - } - - // Setup completion handlers. Barriered to ensure one happens after the other. - var complete = false - let timeoutWorkItem = DispatchWorkItem(qos: .userInitiated) { - completionHandler(mergedParametersList); - complete = true - } - let completionWorkItem = DispatchWorkItem(qos: .userInitiated) { - timeoutWorkItem.cancel() - if !complete { // In the case of firing after timeout. - completionHandler(mergedParametersList); - complete = true - } - } - - // Setup timeout. - parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem) - - // Setup the parameter execution. - for (index, parameterHandler) in parameterHandlerList.enumerated() { - group.enter() - parameterHandler.fetchClientParameters(requestParameters: requestParameters, - timingOutIn: timeout) { (receivedParameter) in - // Queue the results for merge. - parametersWorkQueue.async { - returnedList[index] = receivedParameter - group.leave() // Leaving is only done after setup (barriered). - } - } - } - - // Callback when all parameters have been merged. - group.notify(queue: parametersWorkQueue, work: completionWorkItem); - } - } - /// Add all registry here. open func registerParameters() { } From 6b37f85ac3fdcb782a8f87da496fdb792424de83 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 11 Mar 2021 15:26:11 -0500 Subject: [PATCH 15/26] remove comment --- .../ActionType/Client Parameters/ClientParameterHandler.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift index 083724c..1fd35d0 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift @@ -12,8 +12,7 @@ import Foundation @objcMembers open class ClientParameterHandler: NSObject { var parameterHandlerList: [ClientParameterProtocol] = [] - let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter", autoreleaseFrequency: .workItem) - //DispatchQueue(label: "com.mva.clientparameter") + let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter") let group = DispatchGroup() open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> ClientParameterProtocol? { From 529bf5d447000c71ea0cc64086933f9f39141eb5 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 11 Mar 2021 15:27:53 -0500 Subject: [PATCH 16/26] space --- .../ActionType/Client Parameters/ClientParameterRegistry.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift index bfb9410..ab3a488 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterRegistry.swift @@ -26,7 +26,7 @@ import Foundation open func registerParameters() { } /// Register Default Core Client Paramter Objects - public func register(handler: T.Type, for model: M.Type) throws { + public func register(handler: T.Type, for model: M.Type) throws { try ModelRegistry.register(model) register(handler) } From 1670cd6c40433949114ecba9909cab2cecac07f2 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 11 Mar 2021 15:29:53 -0500 Subject: [PATCH 17/26] space --- MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 8072091..b534d2a 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -113,7 +113,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; NSError *error = nil; [MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Fetching client parameters"]; - ClientParameterHandler* clientParameterHandler = [[ClientParameterHandler alloc] init]; + ClientParameterHandler *clientParameterHandler = [[ClientParameterHandler alloc] init]; [clientParameterHandler getParametersWith:clientParametersMap requestParameters:requestParameters error:&error From de10ed8eef3449ff66ba2aa826fbbe9c90a2e34d Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Thu, 11 Mar 2021 15:32:20 -0500 Subject: [PATCH 18/26] comment --- .../ActionType/Client Parameters/ClientParameterHandler.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift index 1fd35d0..1fb9cf3 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift @@ -50,6 +50,8 @@ import Foundation // Dispatch setup on queue to ensure setup is complete before completion callbacks. + + // Don't use [weak self]. Object is deallocated in the dispatch queue. parametersWorkQueue.async(group: group, qos: .userInitiated) { // 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 { @@ -72,7 +74,6 @@ import Foundation // Setup completion handlers. Barriered to ensure one happens after the other. var complete = false let timeoutWorkItem = DispatchWorkItem(qos: .userInitiated) { - // Holding self. so that its not deallocated in the deispatch queue completionHandler(mergedParametersList); complete = true } From bad4c67e9e8aa5a3edc2199e3cac8cee95fc05fa Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 15 Mar 2021 16:39:46 -0500 Subject: [PATCH 19/26] added ModelHandlerProtocol Signed-off-by: Matt Bruce --- MVMCore/MVMCore.xcodeproj/project.pbxproj | 4 ++++ .../MVMCore/Models/Model/ModelHandlerProtocol.swift | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 MVMCore/MVMCore/Models/Model/ModelHandlerProtocol.swift diff --git a/MVMCore/MVMCore.xcodeproj/project.pbxproj b/MVMCore/MVMCore.xcodeproj/project.pbxproj index 449ae7c..afc5dae 100644 --- a/MVMCore/MVMCore.xcodeproj/project.pbxproj +++ b/MVMCore/MVMCore.xcodeproj/project.pbxproj @@ -149,6 +149,7 @@ D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DEDCB823C6400600C44CC4 /* UnitInterval.swift */; }; D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DEDCBA23C65BC300C44CC4 /* Percent.swift */; }; D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */; }; + EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -288,6 +289,7 @@ D2DEDCB823C6400600C44CC4 /* UnitInterval.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitInterval.swift; sourceTree = ""; }; D2DEDCBA23C65BC300C44CC4 /* Percent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Percent.swift; sourceTree = ""; }; D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateObject.swift; sourceTree = ""; }; + EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHandlerProtocol.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -404,6 +406,7 @@ 946EE1A8237B5C650036751F /* Model */ = { isa = PBXGroup; children = ( + EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */, 946EE1A2237B59C30036751F /* ModelProtocol.swift */, 946EE1A6237B5B1C0036751F /* ModelRegistry.swift */, ); @@ -869,6 +872,7 @@ 94C014D924212360005811A9 /* ActionSettingModel.swift in Sources */, D2DEDCB723C63F3B00C44CC4 /* Clamping.swift in Sources */, 01DF561421F90ADC00CC099B /* Dictionary+MFConvenience.swift in Sources */, + EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */, AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */, 946EE1A3237B59C30036751F /* ModelProtocol.swift in Sources */, AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */, diff --git a/MVMCore/MVMCore/Models/Model/ModelHandlerProtocol.swift b/MVMCore/MVMCore/Models/Model/ModelHandlerProtocol.swift new file mode 100644 index 0000000..522147b --- /dev/null +++ b/MVMCore/MVMCore/Models/Model/ModelHandlerProtocol.swift @@ -0,0 +1,11 @@ +// +// ModelViewProtocol.swift +// MVMCore +// +// Created by Matt Bruce on 3/12/21. +// Copyright © 2021 myverizon. All rights reserved. +// + +import Foundation + +public protocol ModelHandlerProtocol {} From 473da43e6b4a84a2d9746927f05a38869cceda08 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 15 Mar 2021 16:40:22 -0500 Subject: [PATCH 20/26] refactored Category to include the mapping handler Dictionary added methods to register and get handlers --- .../MVMCore/Models/Model/ModelRegistry.swift | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift index 93407d1..deeb6ed 100644 --- a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift +++ b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift @@ -25,24 +25,59 @@ public struct ModelRegistry { var name: String var codingKey: String var instanceTypes: [String: ModelProtocol.Type] = [:] + var handlerTypes: [String: ModelHandlerProtocol.Type] = [:] } private static var categories: [String: Category] = [:] + + /// Registers models for Atomic use. + public static func register(handler: H.Type, for model: M.Type) throws { + //register the type + try self.register(model) + + //get the key for the handler + let key = model.identifier + + //get the category for the ModelProtocol + var category = getCategory(for: model) + + // Check to ensure the Category/Container combination doesn't exist. + if category.handlerTypes[key] != nil { + throw ModelRegistry.Error.other(message: "ModelHandlerProtocol: \(String(describing: handler)) already exists in Category: \(category.name)") + } else { + category.handlerTypes[key] = handler + } + categories[category.name] = category + } /// Registers models for Atomic use. public static func register(_ type: M.Type) throws { - - var category = categories[M.categoryName] ?? Category(name: M.categoryName, codingKey: M.categoryCodingKey) + //get the category for the ModelProtocol + var category = getCategory(for: type) // Check to ensure the Category/Type combination doesn't exist. if category.instanceTypes[M.identifier] != nil { throw ModelRegistry.Error.other(message: "ModelProtocol: \(M.identifier) already exists in Category: \(M.categoryName)") } - category.instanceTypes[M.identifier] = type categories[M.categoryName] = category } + public static func getHandler(_ model: ModelProtocol) -> ModelHandlerProtocol.Type? { + //get the modelType + let modelType = type(of: model) + + //get the category for the ModelProtocol + guard let category = categories[modelType.categoryName] else { return nil } + + //get the containerProtocol for this ModelProtocol you had registered + return category.handlerTypes[modelType.identifier] + } + + private static func getCategory(for type: M.Type) -> Category { + return categories[type.categoryName] ?? Category(name: type.categoryName, codingKey: type.categoryCodingKey) + } + private static func getCategory(for type: T.Type) -> Category? { // Temporary code till we find a better solution. //if this is a protocol composotion, loop through each protocol for a category lookup From 86819283c07223442f46f346ee4a3d60123b1d50 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 17 Mar 2021 11:37:01 -0400 Subject: [PATCH 21/26] improve locae check behavior --- MVMCore/MVMCore/Models/Model/ModelRegistry.swift | 1 - MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift index 93407d1..791e70e 100644 --- a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift +++ b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift @@ -7,7 +7,6 @@ // Copyright © 2019 myverizon. All rights reserved. // -import Foundation public struct ModelRegistry { diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index b48f34e..308016f 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -19,8 +19,13 @@ } + (BOOL)userPrefersSpanish { - // This should be enough for us to look at what the user prefers. - return [[[[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2] lowercaseString] isEqualToString:@"es"]; + // Gets preferences based on what the user wants and the app provides. + NSString *languageCode = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; + if (languageCode && [languageCode length] > 2) { + return [[[languageCode substringToIndex:2] lowercaseString] isEqualToString:@"es"]; + } else { + return [[languageCode lowercaseString] isEqualToString:@"es"]; + } } + (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key { From 63abf3d35e596b7ad49e931b6b4d828c4072752a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 17 Mar 2021 11:46:09 -0400 Subject: [PATCH 22/26] updated comment --- MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index 308016f..8c76ba8 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -19,7 +19,7 @@ } + (BOOL)userPrefersSpanish { - // Gets preferences based on what the user wants and the app provides. + // Gets language code based on what the user prefers and the app provides. NSString *languageCode = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; if (languageCode && [languageCode length] > 2) { return [[[languageCode substringToIndex:2] lowercaseString] isEqualToString:@"es"]; @@ -35,7 +35,6 @@ } else { return [[NSBundle bundleWithPath:[[MVMCoreGetterUtility bundleForMVMCore] pathForResource:@"en" ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil]; - } } From e13530f5b45ed4cb5f03aa42392e2c3d12373524 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 17 Mar 2021 13:52:20 -0400 Subject: [PATCH 23/26] updating func --- .../Utility/Helpers/MVMCoreGetterUtility.h | 6 ++++++ .../Utility/Helpers/MVMCoreGetterUtility.m | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h index 262cc75..df18405 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h @@ -19,6 +19,12 @@ // Returns the hardcoded string from the string file. + (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key; +// Return current system language ++ (nullable NSString *)getSystemLanguage; + +// Return current preferred system language ++ (nullable NSString *)getPreferredAvailableLanguage; + // Returns true if the user's language is Spanish + (BOOL)userPrefersSpanish; diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index 8c76ba8..0d2f8ef 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -18,15 +18,27 @@ return [NSBundle bundleWithIdentifier:@"com.vzw.MVMCore"]; } +// Confirms that the preferred user language is for spanish users. + (BOOL)userPrefersSpanish { - // Gets language code based on what the user prefers and the app provides. - NSString *languageCode = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; + + NSString *languageCode = [MVMCoreGetterUtility getPreferredAvailableLanguage]; if (languageCode && [languageCode length] > 2) { return [[[languageCode substringToIndex:2] lowercaseString] isEqualToString:@"es"]; } else { return [[languageCode lowercaseString] isEqualToString:@"es"]; } } + +// Gets language code based on what the user prefers and the app provides. ++ (NSString *)getPreferredAvailableLanguage { + + return [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; +} + ++ (NSString *)getSystemLanguage { + + return [[NSLocale preferredLanguages] objectAtIndex:0]; +} + (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key { // If the app language is not english... force load from the english file anyway. From 7581c6609f2043f458f10ec1932fd53a047e13fb Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 18 Mar 2021 11:46:07 -0400 Subject: [PATCH 24/26] providing redirect --- .../Utility/Helpers/MVMCoreGetterUtility.h | 3 +++ .../Utility/Helpers/MVMCoreGetterUtility.m | 15 +++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h index df18405..64feae8 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.h @@ -19,6 +19,9 @@ // Returns the hardcoded string from the string file. + (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key; +// Returns the hardcoded string from the string file based on module. ++ (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key bundle:(nullable NSBundle *)bundle; + // Return current system language + (nullable NSString *)getSystemLanguage; diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index 0d2f8ef..a132316 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -35,19 +35,22 @@ return [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; } +// Returns the preferred language set system wide. + (NSString *)getSystemLanguage { return [[NSLocale preferredLanguages] objectAtIndex:0]; } + (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key { + // Redirect key with relevant module. + return [MVMCoreGetterUtility hardcodedStringWithKey:key bundle:[MVMCoreGetterUtility bundleForMVMCore]]; +} + ++ (nullable NSString *)hardcodedStringWithKey:(nonnull NSString *)key bundle:(nullable NSBundle *)bundle { + // If the app language is not english... force load from the english file anyway. - if ([MVMCoreGetterUtility userPrefersSpanish]) { - return [[NSBundle bundleWithPath:[[MVMCoreGetterUtility bundleForMVMCore] pathForResource:@"es" ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil]; - - } else { - return [[NSBundle bundleWithPath:[[MVMCoreGetterUtility bundleForMVMCore] pathForResource:@"en" ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil]; - } + NSString *languageCode = [MVMCoreGetterUtility userPrefersSpanish] ? @"es" : @"en"; + return [[NSBundle bundleWithPath:[bundle pathForResource:languageCode ofType:@"lproj"]] localizedStringForKey:key value:@"" table:nil]; } + (nonnull UIColor *)getColorForHexString:(nonnull NSString *)hexString { From ff0bde3fbff7bee3e5b99f78891819a1e4989a8e Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 18 Mar 2021 13:41:52 -0400 Subject: [PATCH 25/26] refactored --- MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index a132316..044f2d5 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -21,11 +21,11 @@ // Confirms that the preferred user language is for spanish users. + (BOOL)userPrefersSpanish { - NSString *languageCode = [MVMCoreGetterUtility getPreferredAvailableLanguage]; + NSString *languageCode = [[MVMCoreGetterUtility getPreferredAvailableLanguage] lowercaseString]; if (languageCode && [languageCode length] > 2) { - return [[[languageCode substringToIndex:2] lowercaseString] isEqualToString:@"es"]; + return [[languageCode substringToIndex:2] isEqualToString:@"es"]; } else { - return [[languageCode lowercaseString] isEqualToString:@"es"]; + return [languageCode isEqualToString:@"es"]; } } From f36f1e5142acf5d32eb3344a376fd5eac3d94f96 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 18 Mar 2021 15:09:15 -0400 Subject: [PATCH 26/26] simpifying check --- MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m index 044f2d5..c5a8570 100644 --- a/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m +++ b/MVMCore/MVMCore/Utility/Helpers/MVMCoreGetterUtility.m @@ -21,12 +21,7 @@ // Confirms that the preferred user language is for spanish users. + (BOOL)userPrefersSpanish { - NSString *languageCode = [[MVMCoreGetterUtility getPreferredAvailableLanguage] lowercaseString]; - if (languageCode && [languageCode length] > 2) { - return [[languageCode substringToIndex:2] isEqualToString:@"es"]; - } else { - return [languageCode isEqualToString:@"es"]; - } + return [[[MVMCoreGetterUtility getPreferredAvailableLanguage] lowercaseString] hasPrefix:@"es"]; } // Gets language code based on what the user prefers and the app provides.