diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift index 6f8c7e0..6c6549a 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterHandler.swift @@ -9,11 +9,20 @@ @objcMembers open class ClientParameterHandler: NSObject { public static let DefaultTimeout = 30.0 - - open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> ClientParameterProtocol? { + + open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> (any ClientParameterProtocol)? { do { - let parameterType = try ModelRegistry.getHandler(clientParameterModel) as! ClientParameterProtocol.Type - return parameterType.init(clientParameterModel) + //Ensure the handlerType return will be initable using ClientParameterHandler + let handlerType = try ModelRegistry.getHandler(clientParameterModel) as! AnyClientParameterProtocol.Type + + //init the handler + let handler = try handlerType.init(clientParameterModel: clientParameterModel) + + //Cast from AnyClientParameterProtocol to AnyClientParameterProtocol, if not throw + guard let castedHandler = handler as? any ClientParameterProtocol else { throw ClientParameterError.castingError } + + //Return the any ClientParameterProtocol + return castedHandler } catch { if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) { MVMCoreLoggingHandler.addError(toLog: errorObject) @@ -21,7 +30,7 @@ return nil } } - + func getClientParameterModel(_ clientParameters: [String: Any]) throws -> ClientParameterModel? { let data = try JSONSerialization.data(withJSONObject: clientParameters) return try JSONDecoder.create().decode(ClientParameterModel.self, from: data) diff --git a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift index e55fd15..ccaea3b 100644 --- a/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift +++ b/MVMCore/MVMCore/Models/ActionType/Client Parameters/ClientParameterProtocol.swift @@ -8,25 +8,49 @@ import Foundation -public protocol ClientParameterProtocol: ModelHandlerProtocol { - static var name: String { get } +/// Errors used for ClientParamter +public enum ClientParameterError: Error { + case castingError + case modelMismatch(message: String) +} - init(_ clientParameterModel: ClientParameterModelProtocol) +public protocol AnyClientParameterProtocol { + /// Original init using a ClientParameterModelProtocol to get around the self - associatedType issues with ClientParameterProtocol + /// - Parameter clientParameterModel: any Model using the ClientParameterModelProtocol + init(clientParameterModel: ClientParameterModelProtocol) throws +} + +public protocol ClientParameterProtocol: ModelHandlerProtocol, AnyClientParameterProtocol { + associatedtype Model: ClientParameterModelProtocol - var clientParameterModel: ClientParameterModelProtocol { get set } + static var name: String { get } + + var clientParameterModel: Model { get set } + + func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: TimeInterval, completionHandler:@escaping ([String: AnyHashable]?) -> ()) - func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: TimeInterval, 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] - /// Default parameter for timeout scenarios. It will use the protocol extension method bydefault. Can override to send custom values. - func valueOnTimeout() -> [String: AnyHashable] + init(clientParameterModel: Model) } public extension ClientParameterProtocol { - + /// Default Implementation should never be overridden + init(clientParameterModel: ClientParameterModelProtocol) throws { + // Cast the clientParameterModel to ensure it matches the asscociatedType Model assigned to this Handler. + guard let castedModel = clientParameterModel as? Model else { + let message = "Expected \(Model.self) but received \(clientParameterModel.type)" + throw ClientParameterError.modelMismatch(message: message) + } + // Call init for the Handler Class and pass in the casted Model. + self.init(clientParameterModel: castedModel) + } + func valueOnTimeout() -> [String: AnyHashable] { return [Self.name: "failed_to_collect"] } - + /// The handler should call this method to pass the parameter back to the caller. /// If using isFlatMap, you must provide at least 1 element in parameters or it will result in triggering a timeout. func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable], completionHandler: @escaping ([String: AnyHashable]?) -> ()) {