create new ModelHandler protocol/classes

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>

# Conflicts:
#	MVMCore/MVMCore.xcodeproj/project.pbxproj

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-03-03 16:04:19 -06:00
parent 1866c0c28a
commit f61e67df6b
5 changed files with 150 additions and 8 deletions

View File

@ -159,6 +159,9 @@
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 */; };
EA48AAE427D16DE400678D5C /* AnyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA48AAE327D16DE400678D5C /* AnyHandler.swift */; };
EA48AAE627D16DF500678D5C /* ModelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA48AAE527D16DF500678D5C /* ModelHandler.swift */; };
EA48AAE827D16E2900678D5C /* HandlerRequestProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA48AAE727D16E2900678D5C /* HandlerRequestProtocol.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -308,6 +311,9 @@
D2DEDCBA23C65BC300C44CC4 /* Percent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Percent.swift; sourceTree = "<group>"; };
D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateObject.swift; sourceTree = "<group>"; };
EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHandlerProtocol.swift; sourceTree = "<group>"; };
EA48AAE327D16DE400678D5C /* AnyHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyHandler.swift; sourceTree = "<group>"; };
EA48AAE527D16DF500678D5C /* ModelHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHandler.swift; sourceTree = "<group>"; };
EA48AAE727D16E2900678D5C /* HandlerRequestProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandlerRequestProtocol.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -621,6 +627,9 @@
AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */,
01F2A03823A812DD00D954D8 /* ActionOpenUrlModel.swift */,
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */,
EA48AAE327D16DE400678D5C /* AnyHandler.swift */,
EA48AAE527D16DF500678D5C /* ModelHandler.swift */,
EA48AAE727D16E2900678D5C /* HandlerRequestProtocol.swift */,
);
path = ActionHandling;
sourceTree = "<group>";
@ -858,6 +867,7 @@
01F2A03623A80A7300D954D8 /* ActionModelProtocol.swift in Sources */,
AFBB96991FBA3A9A0008D868 /* MVMCoreAlertController.m in Sources */,
881D26941FCC9D180079C521 /* MVMCoreOperation.m in Sources */,
EA48AAE627D16DF500678D5C /* ModelHandler.swift in Sources */,
AFED77A41FCCA29400BAE689 /* MVMCoreViewControllerMappingObject.m in Sources */,
01C851CF23CF7B260021F976 /* JSONMap.swift in Sources */,
01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */,
@ -875,9 +885,11 @@
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
94C014D124211869005811A9 /* ActionRestartModel.swift in Sources */,
D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */,
EA48AAE427D16DE400678D5C /* AnyHandler.swift in Sources */,
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */,
EA48AAE827D16E2900678D5C /* HandlerRequestProtocol.swift in Sources */,
94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */,
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */,

View File

@ -0,0 +1,36 @@
//
// AnyHandler.swift
// MVMCore
//
// Created by Matt Bruce on 3/3/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
/// Type Erased class for HandlerRequestProtocol
public class AnyHandler<Response, Error: Swift.Error>: HandlerRequestProtocol {
//Performable method
private let performObject: () -> Void
//HandlerRequestProtocol method
private let performHandlerObject: (@escaping (Result<Response, Error>) -> Void) -> Void
//Ensures the Request and Handler Response and Error Type match
public init<Request: HandlerRequestProtocol>(wrappedRequest: Request) where Request.Response == Response, Request.Error == Error{
self.performObject = wrappedRequest.perform
self.performHandlerObject = wrappedRequest.perform
}
/// Implementation to call wrapped method
public func perform() {
self.performObject()
}
/// Implementation that calls the wrapped method
/// - Parameter handler: <#handler description#>
public func perform(then handler: @escaping Handler) {
self.performHandlerObject(handler)
}
}

View File

@ -0,0 +1,23 @@
//
// HandlerRequestProtocol.swift
// MVMCore
//
// Created by Matt Bruce on 3/3/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
//Protocol following Request to Response/Error Contract
public protocol HandlerRequestProtocol: Performable {
//Type returned in Success
associatedtype Response
//Type returned in Error
associatedtype Error: Swift.Error
//Handler alias
typealias Handler = (Result<Response, Error>) -> Void
//Method to be implemented by Request
func perform(then handler: @escaping Handler)
}

View File

@ -7,10 +7,19 @@
//
import Foundation
import UIKit
public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
init()
func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?)
public protocol Performable{
func perform()
}
//Base Signature for a Handler - Model relationship
public protocol MVMCoreHandlerProtocol: ModelHandlerProtocol, Performable {
var baseModel: ModelProtocol { get set }
var additionalData: [AnyHashable: Any]? { get set }
var delegateObject: DelegateObject? { get set }
init (baseModel: ModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) throws
}
public extension MVMCoreActionHandler {
@ -40,7 +49,7 @@ public extension MVMCoreActionHandler {
//esnure the actionModelType
let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self),
//ensure there is handlerType for the action of MVMCoreActionHandlerProtocol
let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) as? MVMCoreActionHandlerProtocol.Type
let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) as? MVMCoreHandlerProtocol.Type
else { return false }
do {
@ -49,11 +58,12 @@ public extension MVMCoreActionHandler {
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol")
}
//create the handler since we know it can initialize
let actionHandler = actionHandlerType.init()
//call the handleAction of the handler
actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject)
//create the handler since we know it can initialize
let actionHandler = try? actionHandlerType.init(baseModel: actionModel,
additionalData: additionalData,
delegateObject: delegateObject)
actionHandler?.perform()
} catch {
//log the error

View File

@ -0,0 +1,61 @@
//
// ModelHandler.swift
// MVMCore
//
// Created by Matt Bruce on 3/3/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
/// Abstract Handler class for any type of ModelProtocol
open class ModelHandler<Model: ModelProtocol, Response>: NSObject, MVMCoreHandlerProtocol, HandlerRequestProtocol {
//Success Type from the Result
public typealias Response = Response
//Error Type from the Result
public typealias Error = Swift.Error
//base properties
//baseModel that is tied to this handler
public var baseModel: ModelProtocol
public var additionalData: [AnyHashable: Any]?
public weak var delegateObject: DelegateObject?
//Need to be a property so that you can access
//the handler outside of the "perform(then: handler)
public var handler: Handler!
//typed ModelProtocl this handler is expecting
public var model: Model
//initilization
required public init (baseModel: ModelProtocol,
additionalData: [AnyHashable : Any]?,
delegateObject: DelegateObject?) throws {
//set the properties
self.baseModel = baseModel
self.additionalData = additionalData
self.delegateObject = delegateObject
//ensure the baseModel is of the Model type you are expecting
guard let castedBridgeModel = baseModel as? Model else {
throw ModelRegistry.Error.other(message: "Models Don't match")
}
//set the model
self.model = castedBridgeModel
super.init()
}
//only called in a Void scenario
open func perform() {
fatalError("must override perform")
}
//only called when you want a completion handler.
open func perform(then handler: @escaping Handler) {
self.handler = handler
self.perform()
}
}