Compare commits

...

5 Commits

Author SHA1 Message Date
Matt Bruce
8858f89a5c create new ModelHandler protocol/classes
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-03-03 16:01:23 -06:00
Matt Bruce
669a4c4726 made Category public property
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-03-03 16:00:31 -06:00
Matt Bruce
07cf145686 refactored to new throws JSONAny
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-02-15 11:00:34 -06:00
Matt Bruce
5f3daa573f Merge branch 'develop' into feature/JSONValue-base
# Conflicts:
#	MVMCore/MVMCore/Models/Extensions/Encoder.swift

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-02-15 10:40:23 -06:00
Matt Bruce
875abb11e9 added base:Any? as the JSON Value property
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-01-25 13:57:23 -06:00
7 changed files with 187 additions and 12 deletions

View File

@ -157,6 +157,9 @@
D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DEDCBA23C65BC300C44CC4 /* Percent.swift */; }; D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DEDCBA23C65BC300C44CC4 /* Percent.swift */; };
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */; }; D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */; };
EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.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 */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@ -304,6 +307,9 @@
D2DEDCBA23C65BC300C44CC4 /* Percent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Percent.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -615,6 +621,9 @@
AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */, AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */,
AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */, AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */,
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */, D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */,
EA48AAE327D16DE400678D5C /* AnyHandler.swift */,
EA48AAE527D16DF500678D5C /* ModelHandler.swift */,
EA48AAE727D16E2900678D5C /* HandlerRequestProtocol.swift */,
); );
path = ActionHandling; path = ActionHandling;
sourceTree = "<group>"; sourceTree = "<group>";
@ -850,6 +859,7 @@
01F2A03623A80A7300D954D8 /* ActionModelProtocol.swift in Sources */, 01F2A03623A80A7300D954D8 /* ActionModelProtocol.swift in Sources */,
AFBB96991FBA3A9A0008D868 /* MVMCoreAlertController.m in Sources */, AFBB96991FBA3A9A0008D868 /* MVMCoreAlertController.m in Sources */,
881D26941FCC9D180079C521 /* MVMCoreOperation.m in Sources */, 881D26941FCC9D180079C521 /* MVMCoreOperation.m in Sources */,
EA48AAE627D16DF500678D5C /* ModelHandler.swift in Sources */,
AFED77A41FCCA29400BAE689 /* MVMCoreViewControllerMappingObject.m in Sources */, AFED77A41FCCA29400BAE689 /* MVMCoreViewControllerMappingObject.m in Sources */,
01C851CF23CF7B260021F976 /* JSONMap.swift in Sources */, 01C851CF23CF7B260021F976 /* JSONMap.swift in Sources */,
01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */, 01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */,
@ -867,9 +877,11 @@
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */, 881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
94C014D124211869005811A9 /* ActionRestartModel.swift in Sources */, 94C014D124211869005811A9 /* ActionRestartModel.swift in Sources */,
D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */, D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */,
EA48AAE427D16DE400678D5C /* AnyHandler.swift in Sources */,
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */, 946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */, 30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */, D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */,
EA48AAE827D16E2900678D5C /* HandlerRequestProtocol.swift in Sources */,
94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */, 94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */,
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */, 8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
D27073B725BB45C4001C7246 /* ActionActionsModel.swift 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 Foundation
import UIKit
public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
init() public protocol Performable{
func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) 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 { public extension MVMCoreActionHandler {
@ -40,7 +49,7 @@ public extension MVMCoreActionHandler {
//esnure the actionModelType //esnure the actionModelType
let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self), let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self),
//ensure there is handlerType for the action of MVMCoreActionHandlerProtocol //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 } else { return false }
do { do {
@ -49,11 +58,12 @@ public extension MVMCoreActionHandler {
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol") 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 //create the handler since we know it can initialize
actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) let actionHandler = try? actionHandlerType.init(baseModel: actionModel,
additionalData: additionalData,
delegateObject: delegateObject)
actionHandler?.perform()
} catch { } catch {
//log the error //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()
}
}

View File

@ -13,6 +13,7 @@ public typealias JSONValueDictionary = [String: JSONValue]
public enum JSONValueError: Error { public enum JSONValueError: Error {
case encode case encode
case TypeMismatch
} }
extension Optional { extension Optional {
@ -68,6 +69,38 @@ public enum JSONValue: Codable, Equatable {
case .null: break case .null: break
} }
} }
public var base: Any {
switch self {
case .string(let string): return string
case .int(let int): return int
case .double(let double): return double
case .bool(let bool): return bool
case .object(let object): return try! object.toJSONAny()
case .array(let array): return try! ["array": array].toJSONAny()["array"]!
case .null: return NSNull()
}
}
public func value<T>() throws -> T {
guard let base = self.base as? T else {
throw JSONValueError.TypeMismatch
}
return base
}
private func value<T>(type: T.Type) throws -> T {
let base: T = try value()
return base
}
public func toString() throws -> String { try value(type: String.self) }
public func toDouble() throws -> Double { try value(type: Double.self) }
public func toInt() throws -> Int { try value(type: Int.self) }
public func toBool() throws -> Bool { try value(type: Bool.self) }
public func toArray<T>(of type: T.Type) throws -> [T]{ try value(type: [T].self) }
public func toObject<T>(of type: T.Type) throws -> T { try value(type: T.self) }
} }
public func ==(lhs: JSONValue, rhs: JSONValue) -> Bool { public func ==(lhs: JSONValue, rhs: JSONValue) -> Bool {

View File

@ -24,10 +24,10 @@ public struct ModelRegistry {
} }
public struct Category { public struct Category {
var name: String public var name: String
var codingKey: String public var codingKey: String
var instanceTypes: [String: ModelProtocol.Type] = [:] public var instanceTypes: [String: ModelProtocol.Type] = [:]
var handlerTypes: [String: ModelHandlerProtocol.Type] = [:] public var handlerTypes: [String: ModelHandlerProtocol.Type] = [:]
} }
public static var categories: [String: Category] = [:] public static var categories: [String: Category] = [:]