Merge branch 'feature/client_paramter_processing' into 'develop'
Feature/client paramter processing See merge request BPHV_MIPS/mvm_core!146
This commit is contained in:
commit
55dbe0e4dd
@ -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)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.
|
||||
@ -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;
|
||||
|
||||
@ -93,22 +93,19 @@ NSString * const KeyActionTypeOpen = @"openPage";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setClientParameter:(nullable NSDictionary *)actionInformation completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler {
|
||||
- (void)getClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable parameters))completionHandler {
|
||||
|
||||
NSDictionary *clientParametersMap = [actionInformation dict:KeyClientParameters];
|
||||
if (!clientParametersMap) {
|
||||
completionHandler(actionInformation);
|
||||
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];
|
||||
}
|
||||
};
|
||||
@ -116,27 +113,23 @@ NSString * const KeyActionTypeOpen = @"openPage";
|
||||
NSError *error = nil;
|
||||
[MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Fetching client parameters"];
|
||||
[[[MVMCoreObject sharedInstance] clientParameterRegistry] getParametersWith:clientParametersMap
|
||||
requestParameters:requestParameters
|
||||
error:&error
|
||||
completionHandler:^(NSDictionary<NSString *,id> * _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(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"]];
|
||||
}
|
||||
}
|
||||
@ -168,20 +161,17 @@ NSString * const KeyActionTypeOpen = @"openPage";
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
void (^performAction)(NSDictionary*) = ^(NSDictionary* actionMap) {
|
||||
MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionMap];
|
||||
|
||||
[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];
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
[self setClientParameter:actionInformation completionHandler:performAction];
|
||||
MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap: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
|
||||
actionInformation:actionInformation
|
||||
additionalData:additionalData
|
||||
delegateObject:delegateObject];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)shareAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
@ -278,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];
|
||||
}
|
||||
}];
|
||||
}];
|
||||
@ -340,26 +333,35 @@ 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 getClientParameter:[actionInformation dict:KeyClientParameters]
|
||||
requestParameters:nil
|
||||
showLoadingOverlay:true
|
||||
completionHandler:performAction];
|
||||
}
|
||||
|
||||
- (void)prepareLinkAwayWithURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
@ -418,8 +420,20 @@ 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 {
|
||||
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject];
|
||||
+ (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) {
|
||||
[requestParameters addRequestParameters:jsonDictionary];
|
||||
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject];
|
||||
}];
|
||||
} else {
|
||||
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)defaultHandleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
|
||||
@ -9,7 +9,33 @@
|
||||
import Foundation
|
||||
|
||||
public protocol ClientParameterProtocol {
|
||||
init()
|
||||
static var name: String { get }
|
||||
func fetchClientParameters(for paramModel: ClientParameterModelProtocol, timingOutIn timeout: Double, completionHandler:@escaping (AnyHashable?) -> ())
|
||||
|
||||
init(_ clientParameterModel: ClientParameterModelProtocol)
|
||||
|
||||
var clientParameterModel: ClientParameterModelProtocol { get set }
|
||||
|
||||
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() -> [String: AnyHashable]
|
||||
}
|
||||
|
||||
public extension ClientParameterProtocol {
|
||||
|
||||
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 ([String: AnyHashable]?) -> ()) {
|
||||
guard let parameter = parameter else {
|
||||
return completionHandler(nil)
|
||||
}
|
||||
if isFlatMap {
|
||||
completionHandler(parameter)
|
||||
} else {
|
||||
completionHandler([Self.name: parameter])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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? {
|
||||
@ -47,52 +47,67 @@ 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] = [:]
|
||||
let timeout = clientParameterModel.timeout ?? 30.0
|
||||
|
||||
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
|
||||
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(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
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
parametersList[parameterModel.type] = ["error": defaultErrorString]
|
||||
for (index, parameterHandler) in parameterHandlerList.enumerated() {
|
||||
group.enter()
|
||||
// Dispatch asynchronous injection.
|
||||
self.getParameterFromHandler(parameterModel, before: timeout) { (receivedParameter) in
|
||||
parameterHandler.fetchClientParameters(requestParameters: requestParameters,
|
||||
timingOutIn: timeout) { (receivedParameter) in
|
||||
// Queue the results for merge.
|
||||
parametersWorkQueue.async {
|
||||
if let receivedParameter = receivedParameter {
|
||||
parametersList[parameterModel.type] = receivedParameter
|
||||
}
|
||||
returnedList[index] = receivedParameter
|
||||
group.leave() // Leaving is only done after setup (barriered).
|
||||
}
|
||||
}
|
||||
@ -103,13 +118,6 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
func getParameterFromHandler( _ parameterModel: ClientParameterModelProtocol, before timeout: Double, completionHandler:@escaping (AnyHashable?) -> ()) {
|
||||
guard let parameterHandler = createParametersHandler(parameterModel.type) else {
|
||||
return completionHandler(nil)
|
||||
}
|
||||
parameterHandler.fetchClientParameters(for: parameterModel, timingOutIn: timeout, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
/// Add all registry here.
|
||||
open func registerParameters() { }
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user