From 1f75221915f8b43e5763f9df309be3dc3cb8cab3 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 10 Aug 2022 22:19:01 -0400 Subject: [PATCH] Drive through delegate up front. Remove some legacy delegate back and forth --- .../BaseDropdownEntryField.swift | 4 +- .../Atomic/Atoms/Selectors/Checkbox.swift | 7 +-- MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift | 8 ++- .../Atomic/Atoms/Views/Label/Label.swift | 4 +- .../HorizontalCombinationViews/Tabs.swift | 4 +- .../AccordionMoleculeTableViewCell.swift | 12 +++-- .../Items/DropDownFilterTableViewCell.swift | 4 +- .../Molecules/Items/TabsTableViewCell.swift | 12 +++-- .../TopNotification/NotificationXButton.swift | 8 +-- .../Templates/ModalMoleculeListTemplate.swift | 6 ++- .../ModalMoleculeStackTemplate.swift | 5 +- .../Templates/ModalSectionListTemplate.swift | 6 ++- MVMCoreUI/BaseClasses/Button.swift | 2 +- .../BaseControllers/ViewController.swift | 53 ++++++++++--------- .../Behaviors/AddRemoveMoleculeBehavior.swift | 30 +++++------ .../Protocols/PageBehaviorProtocol.swift | 8 ++- .../SubNav/SubNavManagerController.swift | 26 +++++---- 17 files changed, 118 insertions(+), 81 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift index fdf80f29..8fa985c7 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/BaseDropdownEntryField.swift @@ -100,6 +100,8 @@ import MVMCore else { return } let additionalDataWithSource = additionalData.dictionaryAdding(key: KeySourceModel, value: baseDropdownEntryFieldModel) - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: actionModel, additionalData: additionalDataWithSource, delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: actionModel, additionalData: additionalDataWithSource, delegateObject: delegateObject) + } } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift index bbbeec00..fc6427b3 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift @@ -389,9 +389,10 @@ import MVMCore } private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - var additionalDataToUpdate = additionalData ?? [:] - additionalDataToUpdate[KeySourceModel] = checkboxModel - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: actionModel, additionalData: additionalDataToUpdate, delegateObject: delegateObject) + let additionalDataToUpdate = (checkboxModel != nil) ? additionalData.dictionaryAdding(key: KeySourceModel, value: checkboxModel!) : additionalData + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: actionModel, additionalData: additionalDataToUpdate, delegateObject: delegateObject) + } } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift index dc16312e..9c1f91ca 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Toggle.swift @@ -396,11 +396,15 @@ public typealias ActionBlockConfirmation = () -> (Bool) guard let self = self else { return } if self.isOn { if let action = model.action { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) + } } } else { if let action = model.alternateAction ?? model.action { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) + } } } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index d78d15d5..9723f18d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -387,7 +387,9 @@ public typealias ActionBlock = () -> () } case let actionAtt as LabelAttributeActionModel: addTappableLinkAttribute(range: NSRange(location: range.location, length: range.length)) { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: actionAtt.action, additionalData: additionalData, delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: actionAtt.action, additionalData: additionalData, delegateObject: delegateObject) + } } addActionAttributes(range: range, string: attributedString) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 42217612..66a4b263 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -259,7 +259,9 @@ extension Tabs: UICollectionViewDelegateFlowLayout { if let delegate = delegate { delegate.didSelectItem(indexPath, tabs: self) } else if let action = tabsModel.tabs[selectedIndex].action { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: action, additionalData: [KeySourceModel: tabsModel], delegateObject:delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: [KeySourceModel: tabsModel], delegateObject: delegateObject) + } } if UIAccessibility.isVoiceOverRunning { UIAccessibility.post(notification: .layoutChanged, argument: tabCell) diff --git a/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift index 1a219840..12916ac3 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift @@ -46,9 +46,13 @@ public class AccordionMoleculeTableViewCell: MoleculeTableViewCell { model.selected = accordionButton.isSelected if accordionButton.isSelected { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: AddMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: AddMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + } } else { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: RemoveMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: RemoveMoleculesActionModel(.automatic), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + } } if (accordionListItemModel?.hideLineWhenExpanded ?? false) && (self.bottomSeparatorView?.shouldBeVisible() ?? false) { @@ -56,7 +60,9 @@ public class AccordionMoleculeTableViewCell: MoleculeTableViewCell { } if let actionModel = accordionButton.isSelected ? accordionListItemModel?.expandAction : accordionListItemModel?.collapseAction { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: actionModel, additionalData: [KeySourceModel: model], delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: actionModel, additionalData: [KeySourceModel: model], delegateObject: delegateObject) + } } } diff --git a/MVMCoreUI/Atomic/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/DropDownFilterTableViewCell.swift index 0a845a92..70122918 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/DropDownFilterTableViewCell.swift @@ -37,7 +37,9 @@ import UIKit actions.append(AddMoleculesActionModel(.fade)) let actionsModel = ActionActionsModel(actions: actions) actionsModel.concurrent = false - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: actionsModel, additionalData: additionData, delegateObject: self.delegateObject) + Task(priority: .userInitiated) { + try await (self.delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: actionsModel, additionalData: additionData, delegateObject: self.delegateObject) + } } } diff --git a/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift index 8e63cbd4..b7f76f2b 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift @@ -57,7 +57,9 @@ extension TabsTableViewCell: TabsDelegate { public func shouldSelectItem(_ indexPath: IndexPath, tabs: Tabs) -> Bool { guard indexPath.row != tabs.selectedIndex else { return false } if let model = tabsListItemModel { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: RemoveMoleculesActionModel(indexPath.row < tabs.selectedIndex ? .right : .left), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: RemoveMoleculesActionModel(indexPath.row < tabs.selectedIndex ? .right : .left), additionalData: [KeySourceModel: model], delegateObject: delegateObject) + } } previousTabIndex = tabs.selectedIndex return true @@ -68,9 +70,13 @@ extension TabsTableViewCell: TabsDelegate { guard let model = tabsListItemModel, index < model.molecules.count else { return } if let action = model.tabs.tabs[index].action { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: action, additionalData: [KeySourceModel: model.tabs], delegateObject:delegateObject) + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: [KeySourceModel: model.tabs], delegateObject: delegateObject) + } + } + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: AddMoleculesActionModel(index < previousTabIndex ? .left : .right), additionalData: [KeySourceModel: model], delegateObject: delegateObject) } - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: AddMoleculesActionModel(index < previousTabIndex ? .left : .right), additionalData: [KeySourceModel: model], delegateObject: delegateObject) } } diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift index 698aedcd..f6d6a5f6 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift @@ -11,8 +11,10 @@ import MVMCore @objcMembers open class NotificationXButton: Button { - open func closeTopAlert() { - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: ActionDismissNotificationModel(), additionalData: nil, delegateObject: nil) + open func closeTopAlert(with delegateObject: MVMCoreUIDelegateObject?) { + Task(priority: .userInitiated) { + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: ActionDismissNotificationModel(), additionalData: nil, delegateObject: delegateObject) + } } open override func setupView() { @@ -35,7 +37,7 @@ import MVMCore // TODO: Temporary, consider action for dismissing top alert if model.action.actionType == ActionNoopModel.identifier { addActionBlock(event: .touchUpInside) { (button) in - (button as? NotificationXButton)?.closeTopAlert() + (button as? NotificationXButton)?.closeTopAlert(with: delegateObject) } } } diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift index 033bebb4..01a0b49e 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift @@ -7,7 +7,7 @@ // import UIKit - +import MVMCore open class ModalMoleculeListTemplate: MoleculeListTemplate { //-------------------------------------------------- @@ -32,7 +32,9 @@ open class ModalMoleculeListTemplate: MoleculeListTemplate { guard let self = self else { return } let closeAction = (self.templateModel as? ModalListPageTemplateModel)?.closeAction ?? ActionBackModel() - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: closeAction, additionalData: nil, delegateObject: self.delegateObjectIVar) + Task(priority: .userInitiated) { + try await (self.delegateObject()?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: closeAction, additionalData: nil, delegateObject: self.delegateObject()) + } }) } diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift index 1531d35b..00f125d8 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift @@ -7,6 +7,7 @@ // import UIKit +import MVMCore open class ModalMoleculeStackTemplate: MoleculeStackTemplate { //-------------------------------------------------- @@ -28,7 +29,9 @@ open class ModalMoleculeStackTemplate: MoleculeStackTemplate { guard let self = self else { return } let closeAction = (self.templateModel as? ModalStackPageTemplateModel)?.closeAction ?? ActionBackModel() - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: closeAction, additionalData: nil, delegateObject: self.delegateObjectIVar) + Task(priority: .userInitiated) { + try await (self.delegateObject()?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: closeAction, additionalData: nil, delegateObject: self.delegateObject()) + } }) } } diff --git a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift index 96052ee1..c5fbb6be 100644 --- a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift @@ -5,7 +5,7 @@ // Created by Scott Pfeil on 10/8/20. // Copyright © 2020 Verizon Wireless. All rights reserved. // - +import MVMCore open class ModalSectionListTemplate: SectionListTemplate { //-------------------------------------------------- @@ -27,7 +27,9 @@ open class ModalSectionListTemplate: SectionListTemplate { guard let self = self else { return } let closeAction = (self.templateModel as? ModalSectionListTemplateModel)?.closeAction ?? ActionBackModel() - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: closeAction, additionalData: nil, delegateObject: self.delegateObjectIVar) + Task(priority: .userInitiated) { + try await (self.delegateObject()?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: closeAction, additionalData: nil, delegateObject: self.delegateObject()) + } }) } } diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index ebda6af4..1b62a741 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -92,7 +92,7 @@ public typealias ButtonAction = (Button) -> () if let sourceModel = sourceModel { additionalData = additionalData.dictionaryAdding(key: KeySourceModel, value: sourceModel) } - try await MVMCoreUIActionHandler.handleActionCheckingDelegate(with: model, additionalData: additionalData, delegateObject: delegateObject) + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: model, additionalData: additionalData, delegateObject: delegateObject) } // MARK:- MoleculeViewProtocol diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index bd62a3ad..e0de37f1 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, ActionOpenPageDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol, PageBehaviorHandlerProtocol { +@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, ActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol, PageBehaviorHandlerProtocol { //-------------------------------------------------- // MARK: - Properties @@ -439,40 +439,41 @@ import MVMCore //-------------------------------------------------- // MARK: - MVMCoreActionDelegateProtocol //-------------------------------------------------- - open func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable : Any]? = nil) throws -> (MVMCoreRequestParameters,[AnyHashable : Any]?) { - let json = try MVMCoreActionHandler.convertActionToJSON(model) - let requestParameters = MVMCoreRequestParameters(actionMap: json)! - addFormParams(requestParameters: requestParameters, model: model, additionalData: additionalData) - requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType") - var pageForwardedData = additionalData ?? [:] - - executeBehaviors { (behavior: PageLocalDataShareBehavior) in - let dataMap = behavior.compileLocalPageDataForTransfer(delegateObjectIVar) - pageForwardedData.merge(dataMap) { current, _ in current } - } - return (requestParameters, pageForwardedData) - } open func logAction(withActionInformation actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) { MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: self, actionInformation: actionInformation, additionalData: additionalData) } - public func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool { - var handled = false - executeBehaviors { (behavior: PageCustomActionHandlerBehavior) in - if !handled { - handled = behavior.handleAction(with: model, additionalData: additionalData) + open func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws { + var additionalData = additionalData + if let model = model as? ActionOpenPageModel { + addFormParams(requestParameters: model.requestParameters, model: model, additionalData: additionalData) + model.requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType") + + var pageForwardedData = additionalData ?? [:] + executeBehaviors { (behavior: PageLocalDataShareBehavior) in + let dataMap = behavior.compileLocalPageDataForTransfer(delegateObjectIVar) + pageForwardedData.merge(dataMap) { current, _ in current } } + additionalData = pageForwardedData + } + + do { + if let behavior = behaviors?.compactMap({ $0 as? PageCustomActionHandlerBehavior }).first(where: { $0.canHandleAction(with: model, additionalData: additionalData) }) { + delegateObject?.actionDelegate?.logAction?(withActionInformation: model.toJSON(), additionalData: additionalData) + try await behavior.handleAction(with: model, additionalData: additionalData) + } else { + try await MVMCoreUIActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject) + } + } catch { + handleAction(error: error, model: model, additionalData: additionalData, delegateObject: delegateObject) + throw error } - return handled } - open func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws { - do { - try await MVMCoreUIActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject) - } catch { - MVMCoreUIActionHandler.shared()?.defaultHandle(error: error, model: model, additionalData: additionalData, delegateObject: delegateObject) - } + open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { + let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))! + MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } //-------------------------------------------------- diff --git a/MVMCoreUI/Behaviors/AddRemoveMoleculeBehavior.swift b/MVMCoreUI/Behaviors/AddRemoveMoleculeBehavior.swift index acd3527a..75171d73 100644 --- a/MVMCoreUI/Behaviors/AddRemoveMoleculeBehavior.swift +++ b/MVMCoreUI/Behaviors/AddRemoveMoleculeBehavior.swift @@ -7,6 +7,7 @@ // import Foundation +import MVMCore public enum AddMoleculesPosition { case above @@ -85,28 +86,27 @@ public class AddRemoveMoleculesBehavior: PageCustomActionHandlerBehavior, PageMo } } - public func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) -> Bool { - if model.actionType == AddMoleculesActionModel.identifier { - guard let model = model as? AddMoleculesActionModel, - let list = delegate?.moleculeListDelegate, - let sourceModel = additionalData?[KeySourceModel] as? (ListItemModelProtocol & MoleculeModelProtocol & AddMolecules), - let moleculesToAdd = sourceModel.getRecursiveMoleculesToAdd(), - let indexPath = list.getAdjustedIndexPath(for: sourceModel, position: moleculesToAdd.1) else { return true } - DispatchQueue.main.async { + public func canHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) -> Bool { + return model.actionType == AddMoleculesActionModel.identifier || model.actionType == RemoveMoleculesActionModel.identifier + } + + public func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) async throws { + if let model = model as? AddMoleculesActionModel, + let list = delegate?.moleculeListDelegate, + let sourceModel = additionalData?[KeySourceModel] as? (ListItemModelProtocol & MoleculeModelProtocol & AddMolecules), + let moleculesToAdd = sourceModel.getRecursiveMoleculesToAdd(), + let indexPath = list.getAdjustedIndexPath(for: sourceModel, position: moleculesToAdd.1) { + await MainActor.run { list.addMolecules(moleculesToAdd.0, indexPath: indexPath, animation: model.animation) } - return true - } else if model.actionType == RemoveMoleculesActionModel.identifier { - guard let model = model as? RemoveMoleculesActionModel, + } else if let model = model as? RemoveMoleculesActionModel, let list = delegate?.moleculeListDelegate, let sourceModel = additionalData?[KeySourceModel] as? (ListItemModelProtocol & MoleculeModelProtocol & RemoveMolecules), - let moleculesToRemove = sourceModel.getRecursiveMoleculesToRemove() else { return true } - DispatchQueue.main.async { + let moleculesToRemove = sourceModel.getRecursiveMoleculesToRemove() { + await MainActor.run { list.removeMolecules(moleculesToRemove, animation: model.animation) } - return true } - return false } } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift index 0245fd7c..3420299d 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift @@ -6,6 +6,8 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // +import MVMCore + public protocol PageBehaviorProtocol: ModelHandlerProtocol { @@ -65,12 +67,14 @@ public protocol PageLocalDataShareBehavior: PageBehaviorProtocol { } public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol { + + /// Returns if this behavior can handle the action. + func canHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) -> Bool /// - Parameters: /// - model: The action model. /// - additionalData: Additional information of the - /// - Returns: Boolean determines if the action has been handled. - func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) -> Bool + func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?) async throws } public extension MVMCoreUIDelegateObject { diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 2d1ab302..6ef2b8d0 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -170,19 +170,15 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, requestParameters.tabWasPressed = true return requestParameters } - - open override func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable : Any]? = nil) throws -> (MVMCoreRequestParameters, [AnyHashable : Any]?) { - let value = try super.getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData) - var requestParameters = value.0 - let additionalData = value.1 - guard let additionalData = additionalData, - additionalData.boolForKey("tabBarPressed") else { - // Pass to delegate - 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) - return (requestParameters, additionalData) + + open override func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws { + if let model = model as? ActionOpenPageModel, + let additionalData = additionalData, + additionalData.boolForKey("tabBarPressed") { + // Allow opportunity to modify parameters. + model.requestParameters = getRequestParametersForNewTabLoad(requestParameters: model.requestParameters, model: model, additionalData: additionalData) + } + try await super.performAction(with: model, additionalData: additionalData, delegateObject: delegateObject) } // MARK: - MVMCorePresentationDelegateProtocol @@ -277,7 +273,9 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } else if let tabsModel = tabs.tabsModel, let action = tabsModel.tabs[indexPath.row].action { // Perform the tab action - MVMCoreUIActionHandler.asyncHandleActionCheckingDelegate(with: action, additionalData: getAdditionalDataForNewTabLoad(indexPath: indexPath), delegateObject: delegateObjectIVar) + Task(priority: .userInitiated) { + try await (delegateObjectIVar.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: getAdditionalDataForNewTabLoad(indexPath: indexPath), delegateObject: delegateObjectIVar) + } } return false }