From 9a8cae6d9d295ce369a992ea28eaecba8a46616e Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 21 Oct 2021 15:04:03 -0500 Subject: [PATCH 1/8] added MVMCoreActionHandlerProtocol added Extension for ModelRegistry to get the actionHandler added method to be called by Legacy code to check to see if there is an action handler Signed-off-by: Matt Bruce --- .../MVMCoreActionHandler+Extension.swift | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift index 5acdbca..48484d9 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift @@ -8,6 +8,22 @@ import Foundation +public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol { + init() + func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) +} + +extension ModelRegistry { + public static func getActionHandler(_ model: ActionModelProtocol) throws -> MVMCoreActionHandlerProtocol { + do { + let type = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type + return type.init() + } catch { + throw ModelRegistry.Error.other(message: error.localizedDescription) + } + } +} + public extension MVMCoreActionHandler { /// Converts the action to json for old action handler to handle. @@ -26,6 +42,41 @@ public extension MVMCoreActionHandler { } } + @objc func hasActionHandler(actionType: String?, actionInformation: [String: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Bool { + //ensure there is a Serialized version of the Action + guard let actionType = actionType, let actionInformation = actionInformation else { return false } + + do { + //get the actionModelType + guard let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self) else { + throw ModelRegistry.Error.decoderErrorModelNotMapped() + } + + //deserialize the actionModel for the actionType found + guard let actionModel = try actionModelType.decode(jsonDict: actionInformation) as? ActionModelProtocol else { + throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol") + } + + //get the action Handler for the actionModel created + let actionHandler = try ModelRegistry.getActionHandler(actionModel) + + //call the handleAction of the handler + actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) + + //complete + return true + + } catch { + //log the error + if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") { + MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) + } + + //incomplete + return false + } + } + /// Start action on current thread. func syncHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { guard let json = convertActionToJSON(model, delegateObject: delegateObject) else { return } From 6c8bb9ce4bf197626b0eaac248094751e235220f Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 21 Oct 2021 15:04:29 -0500 Subject: [PATCH 2/8] call the new method from legacy code to check in the final step for registered Action Handlers Signed-off-by: Matt Bruce --- MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 4f307f5..5877975 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -387,7 +387,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; } - (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { - return NO; + return [self hasActionHandlerWithActionType:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; } - (void)unknownAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { From 59ff7d2fad90435e14fac5e19597a38d9c62308c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 22 Oct 2021 15:05:24 -0500 Subject: [PATCH 3/8] fix for legacy Signed-off-by: Matt Bruce --- .../MVMCoreActionHandler+Extension.swift | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift index 48484d9..23bb047 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift @@ -44,37 +44,32 @@ public extension MVMCoreActionHandler { @objc func hasActionHandler(actionType: String?, actionInformation: [String: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Bool { //ensure there is a Serialized version of the Action - guard let actionType = actionType, let actionInformation = actionInformation else { return false } + guard let actionType = actionType, + let actionInformation = actionInformation, + let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self) + else { return false } do { - //get the actionModelType - guard let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self) else { - throw ModelRegistry.Error.decoderErrorModelNotMapped() - } - //deserialize the actionModel for the actionType found guard let actionModel = try actionModelType.decode(jsonDict: actionInformation) as? ActionModelProtocol else { throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol") } - + //get the action Handler for the actionModel created let actionHandler = try ModelRegistry.getActionHandler(actionModel) //call the handleAction of the handler actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) - //complete - return true - } catch { //log the error if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") { MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } - - //incomplete - return false } + + //complete + return true } /// Start action on current thread. From c0958b58e4399468080a4abe4b2a2cde1afa10b7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 27 Oct 2021 14:53:55 -0500 Subject: [PATCH 4/8] added getHandlerType for a Type refactored existing getHandler to call this new method Signed-off-by: Matt Bruce --- MVMCore/MVMCore/Models/Model/ModelRegistry.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift index 78d8657..f148119 100644 --- a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift +++ b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift @@ -165,8 +165,11 @@ public struct ModelRegistry { //-------------------------------------------------- public static func getHandler(_ model: ModelProtocol) throws -> ModelHandlerProtocol.Type { - // Get the modelType - let modelType = type(of: model) + return try getHandlerType(for: type(of: model)) + } + + //get handler for the specific Model + public static func getHandlerType(for modelType: ModelProtocol.Type) throws -> ModelHandlerProtocol.Type{ // Get the category for the ModelProtocol guard let category = categories[modelType.categoryName] else { From b546fcbb8b00ab8941d369b94428e167e3e2b603 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 27 Oct 2021 14:54:52 -0500 Subject: [PATCH 5/8] refactored hasActionHandler to include a guard for HandlerType and refactored out old method to hard cast acation MVMCoreActionHandlerProtocol Signed-off-by: Matt Bruce --- .../MVMCoreActionHandler+Extension.swift | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift index 23bb047..aebffa8 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift @@ -13,17 +13,6 @@ public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol { func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) } -extension ModelRegistry { - public static func getActionHandler(_ model: ActionModelProtocol) throws -> MVMCoreActionHandlerProtocol { - do { - let type = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type - return type.init() - } catch { - throw ModelRegistry.Error.other(message: error.localizedDescription) - } - } -} - public extension MVMCoreActionHandler { /// Converts the action to json for old action handler to handle. @@ -46,30 +35,40 @@ public extension MVMCoreActionHandler { //ensure there is a Serialized version of the Action guard let actionType = actionType, let actionInformation = actionInformation, - let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self) + let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self), + let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) else { return false } do { + //Cast the actionHandlerType to the new Protocol + guard let actionHandlerProtocolType = actionHandlerType as? MVMCoreActionHandlerProtocol.Type else { + throw ModelRegistry.Error.decoderOther(message: "ModelHandlerProtocol found not of MVMCoreActionHandlerProtocol Type") + } + //deserialize the actionModel for the actionType found guard let actionModel = try actionModelType.decode(jsonDict: actionInformation) as? ActionModelProtocol else { throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol") } - - //get the action Handler for the actionModel created - let actionHandler = try ModelRegistry.getActionHandler(actionModel) + + //create the handler since we know it can initialize + let actionHandler = actionHandlerProtocolType.init() //call the handleAction of the handler actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) + + //found the handler and executed the action + return true } catch { //log the error if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") { MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } + + //there was a handler however something failed + return false } - //complete - return true } /// Start action on current thread. From 9a158c4909c3d73a880006610ad1d9d7ec28beb0 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 28 Oct 2021 10:05:09 -0500 Subject: [PATCH 6/8] added comments Signed-off-by: Matt Bruce --- MVMCore/MVMCore/Models/Model/ModelRegistry.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift index f148119..f3fbae6 100644 --- a/MVMCore/MVMCore/Models/Model/ModelRegistry.swift +++ b/MVMCore/MVMCore/Models/Model/ModelRegistry.swift @@ -164,6 +164,7 @@ public struct ModelRegistry { // MARK: - Functions //-------------------------------------------------- + ///This returns a handler type. public static func getHandler(_ model: ModelProtocol) throws -> ModelHandlerProtocol.Type { return try getHandlerType(for: type(of: model)) } From 7f5419d81b6b2de7e758592b7ae33b1eae6b651a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 28 Oct 2021 10:05:36 -0500 Subject: [PATCH 7/8] updated method to always return true if a handler was found, even if there is an error Signed-off-by: Matt Bruce --- .../MVMCoreActionHandler+Extension.swift | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift index aebffa8..04ea87c 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift @@ -55,20 +55,16 @@ public extension MVMCoreActionHandler { //call the handleAction of the handler actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) - - //found the handler and executed the action - return true - + } catch { //log the error if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") { MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } - - //there was a handler however something failed - return false } + //found the handler, returning true no matter if there was a failure in the do...catch + return true } /// Start action on current thread. From 9293894d367da338f7397b4a9d6fc37332b53a0a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 29 Oct 2021 09:25:24 -0500 Subject: [PATCH 8/8] refactored the hasActionHanlder guard bug - added public to JSONValue decode Signed-off-by: Matt Bruce --- .../MVMCoreActionHandler+Extension.swift | 23 +++++++++---------- MVMCore/MVMCore/Models/JSON/JSONValue.swift | 2 +- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift index 04ea87c..273b8b9 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler+Extension.swift @@ -32,30 +32,29 @@ public extension MVMCoreActionHandler { } @objc func hasActionHandler(actionType: String?, actionInformation: [String: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Bool { - //ensure there is a Serialized version of the Action - guard let actionType = actionType, + + guard //ensure there is a actinType + let actionType = actionType, + //ensure there is a serialized version of the Action let actionInformation = actionInformation, + //esnure the actionModelType let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self), - let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) + //ensure there is handlerType for the action of MVMCoreActionHandlerProtocol + let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) as? MVMCoreActionHandlerProtocol.Type else { return false } do { - //Cast the actionHandlerType to the new Protocol - guard let actionHandlerProtocolType = actionHandlerType as? MVMCoreActionHandlerProtocol.Type else { - throw ModelRegistry.Error.decoderOther(message: "ModelHandlerProtocol found not of MVMCoreActionHandlerProtocol Type") - } - - //deserialize the actionModel for the actionType found + //ensure the decoded actionModel is of ActionModelProtocol guard let actionModel = try actionModelType.decode(jsonDict: actionInformation) as? ActionModelProtocol else { throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol") } - + //create the handler since we know it can initialize - let actionHandler = actionHandlerProtocolType.init() + let actionHandler = actionHandlerType.init() //call the handleAction of the handler actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject) - + } catch { //log the error if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") { diff --git a/MVMCore/MVMCore/Models/JSON/JSONValue.swift b/MVMCore/MVMCore/Models/JSON/JSONValue.swift index a603d23..43796cb 100644 --- a/MVMCore/MVMCore/Models/JSON/JSONValue.swift +++ b/MVMCore/MVMCore/Models/JSON/JSONValue.swift @@ -51,7 +51,7 @@ public enum JSONValue: Codable, Equatable { self = value ?? JSONValue.null } - func decode() throws -> T { + public func decode() throws -> T { let encoded = try JSONEncoder().encode(self) return try JSONDecoder().decode(T.self, from: encoded) }