Drive through delegate up front. Remove some legacy delegate back and forth
This commit is contained in:
parent
4d72b31a51
commit
e6164026f6
@ -37,14 +37,14 @@ open class ActionActionsHandler: MVMCoreJSONActionHandlerProtocol {
|
|||||||
await withThrowingTaskGroup(of: Void.self) { group in
|
await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
for action in model.actions {
|
for action in model.actions {
|
||||||
group.addTask{
|
group.addTask{
|
||||||
try await MVMCoreActionHandler.handleActionCheckingDelegate(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for action in model.actions {
|
for action in model.actions {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
try await MVMCoreActionHandler.handleActionCheckingDelegate(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,11 +106,11 @@ open class ActionContactHandler: NSObject, MVMCoreActionHandlerProtocol, CNConta
|
|||||||
var phoneNumbers = [labelValue]
|
var phoneNumbers = [labelValue]
|
||||||
phoneNumbers.append(contentsOf: existingContact.phoneNumbers)
|
phoneNumbers.append(contentsOf: existingContact.phoneNumbers)
|
||||||
existingContact.phoneNumbers = phoneNumbers
|
existingContact.phoneNumbers = phoneNumbers
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
Task { @MainActor in
|
||||||
let controller = CNContactViewController(forNewContact: existingContact)
|
let controller = CNContactViewController(forNewContact: existingContact)
|
||||||
controller.contactStore = store
|
controller.contactStore = store
|
||||||
controller.delegate = self
|
controller.delegate = self
|
||||||
MVMCoreNavigationHandler.shared()?.push(controller, animated: true)
|
MVMCoreNavigationHandler.shared()?.push(controller, animated: true)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,9 +11,6 @@ import Foundation
|
|||||||
public protocol ActionDelegateProtocol: MVMCoreActionDelegateProtocol {
|
public protocol ActionDelegateProtocol: MVMCoreActionDelegateProtocol {
|
||||||
/// Asks the delegate to perform the action.
|
/// Asks the delegate to perform the action.
|
||||||
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws
|
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws
|
||||||
|
|
||||||
/// Allows the delegate to handle any custom actions that are not registered with the Action Handler.
|
|
||||||
func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension ActionDelegateProtocol {
|
public extension ActionDelegateProtocol {
|
||||||
@ -21,8 +18,4 @@ public extension ActionDelegateProtocol {
|
|||||||
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws {
|
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,41 +8,17 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol ActionOpenPageDelegateProtocol {
|
|
||||||
/// Allows the delegate to create the request parameters as desired.
|
|
||||||
func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) throws -> (MVMCoreRequestParameters,[AnyHashable : Any]?)
|
|
||||||
}
|
|
||||||
|
|
||||||
open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
required public init() {}
|
required public init() {}
|
||||||
|
|
||||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
guard let model = model as? ActionOpenPageModel else { return }
|
guard let model = model as? ActionOpenPageModel else { return }
|
||||||
if model.background != true {
|
|
||||||
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.startLoading()
|
|
||||||
}
|
|
||||||
defer {
|
|
||||||
if model.background != true {
|
|
||||||
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.stopLoading(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Allows the delegate a chance to create and modify request parameters.
|
|
||||||
var requestParameters: MVMCoreRequestParameters
|
|
||||||
var additionalData = additionalData
|
|
||||||
if let value = try (delegateObject?.actionDelegate as? ActionOpenPageDelegateProtocol)?.getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData) {
|
|
||||||
requestParameters = value.0
|
|
||||||
additionalData = value.1
|
|
||||||
} else {
|
|
||||||
requestParameters = MVMCoreRequestParameters(actionMap: JSON)!
|
|
||||||
}
|
|
||||||
|
|
||||||
if let closure = delegateObject?.actionDelegate?.handleOpenPage {
|
if let closure = delegateObject?.actionDelegate?.handleOpenPage {
|
||||||
// Legacy code will use the old handler function and break the task chain here.
|
// Legacy code will use the old handler function and break the task chain here.
|
||||||
closure(requestParameters, JSON, additionalData)
|
closure(model.requestParameters, JSON, additionalData)
|
||||||
} else {
|
} else {
|
||||||
try await performRequestAddingClientParameters(with: requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
try await performRequestAddingClientParameters(with: model.requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
try handle(error: error, model: model, delegateObject: delegateObject)
|
try handle(error: error, model: model, delegateObject: delegateObject)
|
||||||
@ -52,6 +28,7 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
|||||||
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
guard let model = model as? ActionOpenPageModel else { return }
|
guard let model = model as? ActionOpenPageModel else { return }
|
||||||
do {
|
do {
|
||||||
|
// Pass through the old function for legacy open page.
|
||||||
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||||
try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
} catch {
|
} catch {
|
||||||
@ -66,8 +43,7 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
|||||||
let fetchedParameters = try await ClientParameterHandler().getClientParameters(with: parametersToFetch, requestParameters: requestParameters.parameters as? [String : Any] ?? [:], showLoadingOverlay: !requestParameters.backgroundRequest) {
|
let fetchedParameters = try await ClientParameterHandler().getClientParameters(with: parametersToFetch, requestParameters: requestParameters.parameters as? [String : Any] ?? [:], showLoadingOverlay: !requestParameters.backgroundRequest) {
|
||||||
requestParameters.add(fetchedParameters)
|
requestParameters.add(fetchedParameters)
|
||||||
}
|
}
|
||||||
|
try Task.checkCancellation()
|
||||||
// Makes the request and waits for it.
|
|
||||||
try await MVMCoreLoadHandler.sharedGlobal()?.performRequest(with: requestParameters, delegateObject: delegateObject, additionalData: additionalData)
|
try await MVMCoreLoadHandler.sharedGlobal()?.performRequest(with: requestParameters, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -16,15 +17,18 @@ open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, Cli
|
|||||||
open var actionType: String = identifier
|
open var actionType: String = identifier
|
||||||
open var pageType: String
|
open var pageType: String
|
||||||
open var modules: [String]?
|
open var modules: [String]?
|
||||||
open var baseURL: String?
|
open var baseURL: URL?
|
||||||
open var appContext: String?
|
open var appContext: String?
|
||||||
open var requestURL: String?
|
open var requestURL: URL?
|
||||||
open var extraParameters: JSONValueDictionary?
|
open var extraParameters: JSONValueDictionary?
|
||||||
open var analyticsData: JSONValueDictionary?
|
open var analyticsData: JSONValueDictionary?
|
||||||
open var presentationStyle: String?
|
open var presentationStyle: String?
|
||||||
open var tabBarIndex: Int?
|
open var tabBarIndex: Int?
|
||||||
open var background: Bool?
|
open var background: Bool?
|
||||||
open var clientParameters: ClientParameterModel?
|
open var clientParameters: ClientParameterModel?
|
||||||
|
open var customTimeoutTime: TimeInterval?
|
||||||
|
|
||||||
|
open var requestParameters: MVMCoreRequestParameters
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initialzier
|
// MARK: - Initialzier
|
||||||
@ -37,5 +41,73 @@ open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, Cli
|
|||||||
self.analyticsData = analyticsData
|
self.analyticsData = analyticsData
|
||||||
self.tabBarIndex = tabBarIndex
|
self.tabBarIndex = tabBarIndex
|
||||||
self.background = background
|
self.background = background
|
||||||
|
|
||||||
|
requestParameters = MVMCoreRequestParameters(pageType: pageType, extraParameters: extraParameters.toJSON())!
|
||||||
|
if let background = background {
|
||||||
|
requestParameters.backgroundRequest = background
|
||||||
|
}
|
||||||
|
requestParameters.actionMap = toJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codable
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case actionType
|
||||||
|
case pageType
|
||||||
|
case modules
|
||||||
|
case baseURL
|
||||||
|
case appContext
|
||||||
|
case requestURL
|
||||||
|
case extraParameters
|
||||||
|
case analyticsData
|
||||||
|
case presentationStyle
|
||||||
|
case tabBarIndex
|
||||||
|
case background
|
||||||
|
case clientParameters
|
||||||
|
case customTimeoutTime
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||||
|
baseURL = try typeContainer.decodeIfPresent(URL.self, forKey: .baseURL)
|
||||||
|
appContext = try typeContainer.decodeIfPresent(String.self, forKey: .appContext)
|
||||||
|
requestURL = try typeContainer.decodeIfPresent(URL.self, forKey: .requestURL)
|
||||||
|
modules = try typeContainer.decodeIfPresent([String].self, forKey: .modules)
|
||||||
|
presentationStyle = try typeContainer.decodeIfPresent(String.self, forKey: .presentationStyle)
|
||||||
|
tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex)
|
||||||
|
background = try typeContainer.decodeIfPresent(Bool.self, forKey: .background)
|
||||||
|
clientParameters = try typeContainer.decodeIfPresent(ClientParameterModel.self, forKey: .clientParameters)
|
||||||
|
customTimeoutTime = try typeContainer.decodeIfPresent(TimeInterval.self, forKey: .customTimeoutTime)
|
||||||
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
|
|
||||||
|
requestParameters = MVMCoreRequestParameters(pageType: pageType, additionalModules: modules ?? [], extraParameters: extraParameters.toJSON())!
|
||||||
|
requestParameters.contextRoot = appContext
|
||||||
|
requestParameters.alternateBaseURL = baseURL
|
||||||
|
requestParameters.url = requestURL
|
||||||
|
requestParameters.customTimeoutTime = customTimeoutTime as NSNumber?
|
||||||
|
if let background = background {
|
||||||
|
requestParameters.backgroundRequest = background
|
||||||
|
}
|
||||||
|
requestParameters.actionMap = toJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
open func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(pageType, forKey: .pageType)
|
||||||
|
try container.encodeIfPresent(baseURL, forKey: .baseURL)
|
||||||
|
try container.encodeIfPresent(appContext, forKey: .appContext)
|
||||||
|
try container.encodeIfPresent(requestURL, forKey: .requestURL)
|
||||||
|
try container.encodeIfPresent(modules, forKey: .modules)
|
||||||
|
try container.encodeIfPresent(presentationStyle, forKey: .presentationStyle)
|
||||||
|
try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex)
|
||||||
|
try container.encodeIfPresent(background, forKey: .background)
|
||||||
|
try container.encodeIfPresent(clientParameters, forKey: .clientParameters)
|
||||||
|
try container.encodeIfPresent(customTimeoutTime, forKey: .customTimeoutTime)
|
||||||
|
try container.encodeIfPresent(extraParameters, forKey: .extraParameters)
|
||||||
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,7 +77,7 @@ open class ActionOpenUrlHandler: MVMCoreJSONActionHandlerProtocol {
|
|||||||
} catch {
|
} catch {
|
||||||
// Log error and continue
|
// Log error and continue
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
||||||
if let errorObject = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) {
|
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||||
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
|||||||
} else if let _ = activityType {
|
} else if let _ = activityType {
|
||||||
// If a specific type of activity failed, the activity controller is still presented, cannot continue yet.
|
// If a specific type of activity failed, the activity controller is still presented, cannot continue yet.
|
||||||
if let error = error,
|
if let error = error,
|
||||||
let errorObject = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) {
|
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||||
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||||
}
|
}
|
||||||
} else if let error = error {
|
} else if let error = error {
|
||||||
|
|||||||
@ -33,9 +33,6 @@
|
|||||||
// Handles any unknown action types. Can overwrite for more specific handling.
|
// Handles any unknown action types. Can overwrite for more specific handling.
|
||||||
- (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
- (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||||
|
|
||||||
// Handles any action errors. Can overwrite for more specific handling.
|
|
||||||
- (void)handleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData;
|
|
||||||
|
|
||||||
// Lets the delegate know that another internal module app is about to be launched
|
// Lets the delegate know that another internal module app is about to be launched
|
||||||
- (void)prepareForOpenOtherAppModule:(nullable NSString *)module;
|
- (void)prepareForOpenOtherAppModule:(nullable NSString *)module;
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
|
|||||||
func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Protocol used to bridge legacy, non model based code. Allows us to keep the original json intact and not lose key values during decode/encode.
|
/// Protocol used to bridge legacy, non model based code. Allows us to keep the original json intact and not lose key values during decode/encode. Should not be used for new actions.
|
||||||
public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
||||||
/// Perform the function using the original json and model.
|
/// Perform the function using the original json and model.
|
||||||
func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||||
@ -38,6 +38,7 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to temporarily store the json in additionalData.
|
||||||
private let jsonKey = "MVMCore.JSON"
|
private let jsonKey = "MVMCore.JSON"
|
||||||
|
|
||||||
/// Returns the action handler stored in the MVMCoreObject
|
/// Returns the action handler stored in the MVMCoreObject
|
||||||
@ -73,16 +74,6 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
|
|
||||||
// MARK: - Error Handling
|
// MARK: - Error Handling
|
||||||
|
|
||||||
/// Converts the Error into an ErrorObject.
|
|
||||||
open func getActionErrorObject(for error: Error, actionType: String, delegateObject: DelegateObject? = nil) -> MVMCoreErrorObject {
|
|
||||||
switch error {
|
|
||||||
case MVMCoreError.errorObject(let object):
|
|
||||||
return object
|
|
||||||
default:
|
|
||||||
return MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: actionType))!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a common description for the error location.
|
/// Returns a common description for the error location.
|
||||||
@objc public static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String {
|
@objc public static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String {
|
||||||
return "\(String(describing: delegate))_\(actionType)"
|
return "\(String(describing: delegate))_\(actionType)"
|
||||||
@ -90,36 +81,19 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
|
|
||||||
// MARK: - Action Handling
|
// MARK: - Action Handling
|
||||||
|
|
||||||
/// Convenience function for letting the actionDelegate handle the action, else the handler handles the action.
|
|
||||||
public static func handleActionCheckingDelegate(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
|
||||||
if let closure = (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction {
|
|
||||||
try await closure(model, additionalData, delegateObject)
|
|
||||||
} else {
|
|
||||||
try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenience function for letting the actionDelegate handle the action, else the handler handles the action.
|
|
||||||
@discardableResult
|
|
||||||
public static func asyncHandleActionCheckingDelegate(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Task<Void, Error> {
|
|
||||||
return Task(priority: .userInitiated) {
|
|
||||||
try await handleActionCheckingDelegate(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle an action with the given model.
|
/// Handle an action with the given model.
|
||||||
open func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
open func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
var additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
var additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
||||||
|
MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData)
|
||||||
|
defer {
|
||||||
|
MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData)
|
||||||
|
}
|
||||||
let json = try additionalData?.removeValue(forKey: jsonKey) as? [AnyHashable : Any] ?? MVMCoreActionHandler.convertActionToJSON(model)
|
let json = try additionalData?.removeValue(forKey: jsonKey) as? [AnyHashable : Any] ?? MVMCoreActionHandler.convertActionToJSON(model)
|
||||||
|
|
||||||
// Log the action
|
// Log the action
|
||||||
delegateObject?.actionDelegate?.logAction?(withActionInformation: json, additionalData: additionalData)
|
delegateObject?.actionDelegate?.logAction?(withActionInformation: json, additionalData: additionalData)
|
||||||
|
|
||||||
MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData)
|
|
||||||
defer {
|
|
||||||
MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData)
|
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type
|
let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type
|
||||||
let handler = handlerType.init()
|
let handler = handlerType.init()
|
||||||
@ -150,11 +124,6 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
delegateObject?.actionDelegate?.logAction?(withActionInformation: model.toJSON(), additionalData: additionalData)
|
delegateObject?.actionDelegate?.logAction?(withActionInformation: model.toJSON(), additionalData: additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func defaultHandle(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
|
||||||
let errorObject = getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject)
|
|
||||||
defaultHandleActionError(errorObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Logs the error.
|
/// Logs the error.
|
||||||
@objc open func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable: Any]?) {
|
@objc open func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable: Any]?) {
|
||||||
guard error.logError else { return }
|
guard error.logError else { return }
|
||||||
@ -198,16 +167,14 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
switch error {
|
switch error {
|
||||||
case ModelRegistry.Error.decoderErrorModelNotMapped:
|
case ModelRegistry.Error.decoderErrorModelNotMapped:
|
||||||
// If the model is not mapped, give the legacy classes a chance to handle it.
|
// If the model is not mapped, give the legacy classes a chance to handle it.
|
||||||
if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
if try await handleUnregisteredAction(with: nil, json: json!, additionalData: additionalData, delegateObject: delegateObject) == false {
|
||||||
MVMCoreActionHandler.log(string: "Unknown handled (Model not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
|
||||||
closure(actionType, json, additionalData)
|
|
||||||
} else {
|
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
MVMCoreActionHandler.log(string: "Failed Action: Error \(error)", additionalData: additionalData)
|
MVMCoreActionHandler.log(string: "Failed Action: Error \(error)", additionalData: additionalData)
|
||||||
let errorObject = getActionErrorObject(for: error, actionType: actionType ?? "noAction", delegateObject: delegateObject)
|
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: actionType ?? "noAction")) {
|
||||||
delegateObject?.actionDelegate?.handleActionError?(errorObject, additionalData: additionalData) ?? defaultHandleActionError(errorObject, additionalData: additionalData)
|
defaultHandleActionError(errorObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,15 +197,13 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Subclass to handle and any actions where a handler was not registered. Checks with the delegate handlesUnknownAction function
|
/// Subclass to handle and any actions where a handler was not registered. Checks with the delegate handlesUnknownAction function
|
||||||
open func handleUnregisteredAction(with model: ActionModelProtocol, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws -> Bool {
|
open func handleUnregisteredAction(with model: ActionModelProtocol?, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws -> Bool {
|
||||||
// Check if the delegate handles the action.
|
// Check if the delegate handles the action.
|
||||||
if try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.handlesUnknownAction(for: model, delegateObject: delegateObject, additionalData: additionalData) == true {
|
let actionType = json.optionalStringForKey(KeyActionType)
|
||||||
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(model.actionType) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
||||||
return true
|
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
||||||
} else if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
|
||||||
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(model.actionType) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
|
||||||
// Check if the legacy delegate handles the action.
|
// Check if the legacy delegate handles the action.
|
||||||
closure(model.actionType, json, additionalData)
|
closure(actionType, json, additionalData)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -39,3 +39,14 @@ public enum MVMCoreError: MVMError, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc public extension NSError {
|
||||||
|
@objc func checkForMVMCoreError() -> MVMCoreErrorObject? {
|
||||||
|
switch self as Error {
|
||||||
|
case MVMCoreError.errorObject(let object):
|
||||||
|
return object
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#import "MVMCoreJSONConstants.h"
|
#import "MVMCoreJSONConstants.h"
|
||||||
#import "MVMCoreHardcodedStringsConstants.h"
|
#import "MVMCoreHardcodedStringsConstants.h"
|
||||||
#import "MVMCoreDispatchUtility.h"
|
#import "MVMCoreDispatchUtility.h"
|
||||||
|
#import <MVMCore/MVMCore-Swift.h>
|
||||||
|
|
||||||
@implementation MVMCoreErrorObject
|
@implementation MVMCoreErrorObject
|
||||||
|
|
||||||
@ -106,8 +107,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ (nullable instancetype)createErrorObjectForNSError:(nonnull NSError *)error location:(nullable NSString *)location {
|
+ (nullable instancetype)createErrorObjectForNSError:(nonnull NSError *)error location:(nullable NSString *)location {
|
||||||
|
MVMCoreErrorObject *errorObject = [error checkForMVMCoreError];
|
||||||
MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location];
|
if (errorObject) {
|
||||||
|
return errorObject;
|
||||||
|
}
|
||||||
|
errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location];
|
||||||
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
||||||
errorObject.systemDomain = error.domain;
|
errorObject.systemDomain = error.domain;
|
||||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getNativeScreenForRequestError:requestObject:)]) {
|
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getNativeScreenForRequestError:requestObject:)]) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user