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.