diff --git a/MVMCoreUI/Atomic/Actions/ActionAlertHandler.swift b/MVMCoreUI/Atomic/Actions/ActionAlertHandler.swift index aa3ccc67..cc40b20b 100644 --- a/MVMCoreUI/Atomic/Actions/ActionAlertHandler.swift +++ b/MVMCoreUI/Atomic/Actions/ActionAlertHandler.swift @@ -10,18 +10,22 @@ import Foundation import MVMCore /// Shows an alert using the model. -open class ActionAlertHandler: MVMCoreActionHandlerProtocol { +open class ActionAlertHandler: MVMCoreJSONActionHandlerProtocol { required public init() {} - open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { - guard let model = model as? ActionAlertModel else { return } - try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in - var error: MVMCoreErrorObject? = nil - guard let alertObject = MVMCoreAlertObject.alertObjectWith(action: json, additionalData: additionalData, delegateObject: delegateObject, error: &error) else { - throw MVMCoreError.errorObject(error!) - } - (delegateObject?.actionDelegate as? MVMCoreUIActionDelegateProtocol)?.willShowPopup(with: alertObject, alertJson: json) + open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + var error: MVMCoreErrorObject? = nil + guard let alertObject = MVMCoreAlertObject.alertObjectWith(action: JSON, additionalData: additionalData, delegateObject: delegateObject, error: &error) else { + throw MVMCoreError.errorObject(error!) + } + (delegateObject?.actionDelegate as? MVMCoreUIActionDelegateProtocol)?.willShowPopup(with: alertObject, alertJson: JSON) + _ = await MainActor.run { MVMCoreAlertHandler.shared()?.showAlert(with: alertObject) } } + + open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + let json = try MVMCoreActionHandler.convertActionToJSON(model) + try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData) + } } diff --git a/MVMCoreUI/Atomic/Actions/ActionAlertModel.swift b/MVMCoreUI/Atomic/Actions/ActionAlertModel.swift index 67748a4d..f657304b 100644 --- a/MVMCoreUI/Atomic/Actions/ActionAlertModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionAlertModel.swift @@ -7,7 +7,7 @@ // import MVMCore -@objcMembers public class ActionAlertModel: ActionModelProtocol { +public struct ActionAlertModel: ActionModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Actions/ActionCollapseNotificationModel.swift b/MVMCoreUI/Atomic/Actions/ActionCollapseNotificationModel.swift index 4663d539..94e84744 100644 --- a/MVMCoreUI/Atomic/Actions/ActionCollapseNotificationModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionCollapseNotificationModel.swift @@ -7,8 +7,9 @@ // import UIKit +import MVMCore -@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol { +public struct ActionCollapseNotificationModel: ActionModelProtocol { public static var identifier: String = "collapseNotification" public var actionType: String = ActionCollapseNotificationModel.identifier diff --git a/MVMCoreUI/Atomic/Actions/ActionOpenPanelHandler.swift b/MVMCoreUI/Atomic/Actions/ActionOpenPanelHandler.swift index 87060a4b..20853583 100644 --- a/MVMCoreUI/Atomic/Actions/ActionOpenPanelHandler.swift +++ b/MVMCoreUI/Atomic/Actions/ActionOpenPanelHandler.swift @@ -10,20 +10,24 @@ import Foundation import MVMCore /// Shows the panel. -open class ActionOpenPanelHandler: MVMCoreActionHandlerProtocol { +open class ActionOpenPanelHandler: MVMCoreJSONActionHandlerProtocol { required public init() {} + open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + guard let model = model as? ActionOpenPanelModel else { return } + switch model.panel { + case .left, .menu: + await MVMCoreUISplitViewController.main()?.leftPanel?.willOpen?(withActionInformation: JSON, additionalData: additionalData) + await MVMCoreUISplitViewController.main()?.showLeftPanel(animated: true) + case .right, .support: + await MVMCoreUISplitViewController.main()?.rightPanel?.willOpen?(withActionInformation: JSON, additionalData: additionalData) + await MVMCoreUISplitViewController.main()?.showRightPanel(animated: true) + } + } + open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { guard let model = model as? ActionOpenPanelModel else { return } - try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in - switch model.panel { - case .left, .menu: - await MVMCoreUISplitViewController.main()?.leftPanel?.willOpen?(withActionInformation: json, additionalData: additionalData) - await MVMCoreUISplitViewController.main()?.showLeftPanel(animated: true) - case .right, .support: - await MVMCoreUISplitViewController.main()?.rightPanel?.willOpen?(withActionInformation: json, additionalData: additionalData) - await MVMCoreUISplitViewController.main()?.showRightPanel(animated: true) - } - } + let json = try MVMCoreActionHandler.convertActionToJSON(model) + try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData) } } diff --git a/MVMCoreUI/Atomic/Actions/ActionOpenPanelModel.swift b/MVMCoreUI/Atomic/Actions/ActionOpenPanelModel.swift index eaad4746..ec526e10 100644 --- a/MVMCoreUI/Atomic/Actions/ActionOpenPanelModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionOpenPanelModel.swift @@ -7,8 +7,9 @@ // import Foundation +import MVMCore -public class ActionOpenPanelModel: ActionModelProtocol { +public struct ActionOpenPanelModel: ActionModelProtocol { public enum Panel: String, Codable { case left diff --git a/MVMCoreUI/Atomic/Actions/ActionPopupHandler.swift b/MVMCoreUI/Atomic/Actions/ActionPopupHandler.swift index d0efc18e..2bafd60b 100644 --- a/MVMCoreUI/Atomic/Actions/ActionPopupHandler.swift +++ b/MVMCoreUI/Atomic/Actions/ActionPopupHandler.swift @@ -23,8 +23,12 @@ open class ActionPopupHandler: MVMCoreActionHandlerProtocol { return } (delegateObject?.actionDelegate as? MVMCoreUIActionDelegateProtocol)?.willShowPopup(with: alertObject, alertJson: json!) - MVMCoreAlertHandler.shared()?.showAlert(with: alertObject) - continuation.resume() + Task { + _ = await MainActor.run { + MVMCoreAlertHandler.shared()?.showAlert(with: alertObject) + } + continuation.resume() + } }) } } diff --git a/MVMCoreUI/Atomic/Actions/ActionPopupModel.swift b/MVMCoreUI/Atomic/Actions/ActionPopupModel.swift index 8cdbd83c..cbade308 100644 --- a/MVMCoreUI/Atomic/Actions/ActionPopupModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionPopupModel.swift @@ -6,8 +6,9 @@ // Copyright © 2019 myverizon. All rights reserved. // +import MVMCore -@objcMembers public class ActionPopupModel: ActionModelProtocol { +public struct ActionPopupModel: ActionModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Actions/ActionTopAlertHandler.swift b/MVMCoreUI/Atomic/Actions/ActionTopAlertHandler.swift index db37c3b1..b7d3d5eb 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopAlertHandler.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopAlertHandler.swift @@ -21,9 +21,13 @@ open class ActionTopAlertHandler: MVMCoreActionHandlerProtocol { continuation.resume(throwing: ModelRegistry.Error.decoderOther(message: "Alert Page \(model.pageType) missing ResponseInfo")) return } - let alertObject = MVMCoreAlertObject(forPageType: model.pageType, responseInfo: responseInfo, additionalData: additionalData, delegateObject: delegateObject)! - (delegateObject?.actionDelegate as? MVMCoreUIActionDelegateProtocol)?.willShowTopAlert(with: alertObject, alertJson: json!) - alertObject.showAlert() + + var alertObject = MVMCoreAlertObject(forPageType: model.pageType, responseInfo: responseInfo, additionalData: additionalData, delegateObject: delegateObject) + if let object = alertObject, + let closure = (delegateObject?.actionDelegate as? MVMCoreUIActionDelegateProtocol)?.willShowTopAlert { + alertObject = closure(object, json!) + } + alertObject?.showAlert() continuation.resume() }) } diff --git a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift index 62e496c2..440e318c 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift @@ -8,7 +8,7 @@ import Foundation -@objcMembers public class ActionTopAlertModel: ActionModelProtocol { +public struct ActionTopAlertModel: ActionModelProtocol { public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier diff --git a/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift index 7ca1d6aa..9850e8d0 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift @@ -7,8 +7,9 @@ // import UIKit +import MVMCore -@objcMembers public class ActionTopNotificationModel: ActionModelProtocol { +public struct ActionTopNotificationModel: ActionModelProtocol { public static var identifier: String = "topNotification" public var actionType: String = ActionTopNotificationModel.identifier diff --git a/MVMCoreUI/Atomic/Actions/MVMCoreUIActionOpenPageHandler.swift b/MVMCoreUI/Atomic/Actions/MVMCoreUIActionOpenPageHandler.swift index 550badf5..5de3ed27 100644 --- a/MVMCoreUI/Atomic/Actions/MVMCoreUIActionOpenPageHandler.swift +++ b/MVMCoreUI/Atomic/Actions/MVMCoreUIActionOpenPageHandler.swift @@ -10,10 +10,10 @@ import Foundation import MVMCore open class MVMCoreUIActionOpenPageHandler: ActionOpenPageHandler { - public override func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { + open override func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { // Cleanup the source model data to prevent it from being accidentally auto-forwarded in openPage network requests by blind additionalData insertions. (https://onejira.verizon.com/browse/CXTDT-135642, https://onejira.verizon.com/browse/CXTDT-136001). var additionalData = additionalData additionalData?.removeValue(forKey: KeySourceModel) - try await super.performAction(model, delegateObject: delegateObject, additionalData: additionalData) + try await super.performAction(with: JSON, model: model, delegateObject: delegateObject, additionalData: additionalData) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 9ba0971a..d04c7335 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -9,7 +9,7 @@ import UIKit import MVMCore -@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, ActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol, PageBehaviorHandlerProtocol { +@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, ActionOpenPageDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol, PageBehaviorHandlerProtocol { //-------------------------------------------------- // MARK: - Properties @@ -27,7 +27,7 @@ import MVMCore public weak var manager: (UIViewController & MVMCoreViewManagerProtocol)? /// A temporary iVar backer for delegateObject() until we change the protocol - public lazy var delegateObjectIVar: MVMCoreUIDelegateObject = { + open lazy var delegateObjectIVar: MVMCoreUIDelegateObject = { MVMCoreUIDelegateObject.create(withDelegateForAll: self) }() @@ -450,7 +450,7 @@ import MVMCore let dataMap = behavior.compileLocalPageDataForTransfer(delegateObjectIVar) pageForwardedData.merge(dataMap) { current, _ in current } } - return (requestParameters,pageForwardedData) + return (requestParameters, pageForwardedData) } open func logAction(withActionInformation actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 042f3235..a4d4e54f 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -178,7 +178,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, guard let additionalData = additionalData, additionalData.boolForKey("tabBarPressed") else { // Pass to delegate - return try (viewController as? ActionDelegateProtocol)?.getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData) ?? value + return try (viewController as? ActionOpenPageDelegateProtocol)?.getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData) ?? value } // Allow opportunity to modify parameters. requestParameters = getRequestParametersForNewTabLoad(requestParameters: requestParameters, model: model, additionalData: additionalData) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift index 852b041a..6b30353f 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift @@ -16,8 +16,7 @@ import SafariServices open override func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable : Any]?) { super.defaultHandleActionError(error, additionalData: additionalData) guard !error.silentError else { return } - Task { - // TODO: Verify if necessary. + Task(priority: .userInitiated) { await MainActor.run { // Show alert let alertObject = MVMCoreAlertObject.init(popupAlertWithError: error, isGreedy: false)!