Merge branch 'feature/behavior_expansion' into 'develop'
Behavior Expansion See merge request BPHV_MIPS/mvm_core_ui!701
This commit is contained in:
commit
e50fef3050
@ -7,12 +7,13 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ImageViewModel: MoleculeModelProtocol {
|
||||
@objcMembers open class ImageViewModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "image"
|
||||
open class var identifier: String { "image" }
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var moleculeName: String = ImageViewModel.identifier
|
||||
public var image: String
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeModelProtocol {
|
||||
public class ListLeftVariableIconWithRightCaretModel: ListItemModel, ParentMoleculeModelProtocol {
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//-----------------------------------------------------
|
||||
@ -17,6 +17,10 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod
|
||||
public var leftLabel: LabelModel
|
||||
public var rightLabel: LabelModel
|
||||
|
||||
public var children: [MoleculeModelProtocol] {
|
||||
return [image, leftLabel, rightLabel]
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//-----------------------------------------------------
|
||||
@ -57,9 +61,9 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||
image = try typeContainer.decode(ImageViewModel.self, forKey: .image)
|
||||
leftLabel = try typeContainer.decodeMolecule(codingKey: .leftLabel)
|
||||
rightLabel = try typeContainer.decodeMolecule(codingKey: .rightLabel)
|
||||
image = try typeContainer.decodeMolecule(codingKey: .image)
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -50,11 +50,11 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol {
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton)
|
||||
primaryButton = try typeContainer.decodeMoleculeIfPresent(codingKey: .primaryButton)
|
||||
if primaryButton?.style == nil {
|
||||
primaryButton?.style = .primary
|
||||
}
|
||||
secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton)
|
||||
secondaryButton = try typeContainer.decodeMoleculeIfPresent(codingKey: .secondaryButton)
|
||||
if secondaryButton?.style == nil {
|
||||
secondaryButton?.style = .secondary
|
||||
}
|
||||
|
||||
@ -48,4 +48,33 @@ import Foundation
|
||||
public init(body: LabelModel) {
|
||||
self.body = body
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//-----------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case headline
|
||||
case body
|
||||
case style
|
||||
case backgroundColor
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline)
|
||||
body = try typeContainer.decodeMoleculeIfPresent(codingKey: .body)
|
||||
style = try typeContainer.decodeIfPresent(Style.self, forKey: .style)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(style, forKey: .style)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ import Foundation
|
||||
|
||||
public protocol MoleculeDelegateProtocol: AnyObject {
|
||||
|
||||
func getRootMolecules() -> [MoleculeModelProtocol]
|
||||
|
||||
/// returns a module for the corresponding module name.
|
||||
func getModuleWithName(_ name: String?) -> [AnyHashable : Any]?
|
||||
func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol?
|
||||
|
||||
@ -143,7 +143,6 @@ import UIKit
|
||||
// Parse the model for the page.
|
||||
do {
|
||||
try parsePageJSON()
|
||||
return true
|
||||
} catch let parsingError {
|
||||
// Log all parsing errors and fail load.
|
||||
handleLoggingFor(parsingError: parsingError)
|
||||
@ -153,6 +152,14 @@ import UIKit
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if let pageData = loadObject.dataForPage {
|
||||
executeBehaviors { (behavior: PageLocalDataShareBehavior) in
|
||||
behavior.receiveLocalPageData(pageData, delegateObjectIVar)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func handleLoggingFor(parsingError: Error) {
|
||||
@ -230,6 +237,10 @@ import UIKit
|
||||
|
||||
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
|
||||
open func handleNewData() {
|
||||
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||
behavior.onPageNew(rootMolecules: getRootMolecules(), delegateObjectIVar)
|
||||
}
|
||||
|
||||
if formValidator == nil {
|
||||
let rules = model?.formRules
|
||||
formValidator = FormValidator(rules)
|
||||
@ -373,6 +384,10 @@ import UIKit
|
||||
// Track.
|
||||
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
|
||||
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
|
||||
|
||||
executeBehaviors { [weak self] (behavior: PageVisibilityBehavior) in
|
||||
behavior.onPageShown(self?.delegateObjectIVar)
|
||||
}
|
||||
}
|
||||
|
||||
open override func viewDidAppear(_ animated: Bool) {
|
||||
@ -381,10 +396,6 @@ import UIKit
|
||||
if manager == nil {
|
||||
pageShown()
|
||||
}
|
||||
|
||||
executeBehaviors { [weak self] (behavior: PageVisibilityBehavior) in
|
||||
behavior.onPageShown(self?.delegateObjectIVar)
|
||||
}
|
||||
}
|
||||
|
||||
open override func viewDidDisappear(_ animated: Bool) {
|
||||
@ -463,17 +474,38 @@ import UIKit
|
||||
open func handleOpenPage(for requestParameters: MVMCoreRequestParameters, actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
||||
addFormParams(requestParameters)
|
||||
requestParameters.parentPageType = loadObject?.pageJSON?.optionalStringForKey("parentPageType")
|
||||
MVMCoreActionHandler.defaultHandleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: additionalData, delegateObject: delegateObject())
|
||||
var pageForwardedData = additionalData ?? [:]
|
||||
executeBehaviors { (behavior: PageLocalDataShareBehavior) in
|
||||
let dataMap = behavior.compileLocalPageDataForTransfer(delegateObjectIVar)
|
||||
pageForwardedData.merge(dataMap) { (current, _) in current }
|
||||
}
|
||||
MVMCoreActionHandler.defaultHandleOpenPage(for: requestParameters, actionInformation: actionInformation, additionalData: pageForwardedData, delegateObject: delegateObject())
|
||||
}
|
||||
|
||||
open func logAction(withActionInformation actionInformation: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) {
|
||||
MVMCoreUILoggingHandler.shared()?.defaultLogAction(forController: self, actionInformation: actionInformation, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open func handleUnknownActionType(_ actionType: String?, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) {
|
||||
var handled = false
|
||||
executeBehaviors { (behavior: PageCustomActionHandlerBehavior) in
|
||||
if (!handled) {
|
||||
handled = behavior.handleAction(type: actionType, information: actionInformation, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
if (!handled) {
|
||||
MVMCoreUIActionHandler.defaultHandleUnknownActionType(actionType, actionInformation: actionInformation, additionalData: additionalData, delegateObject: delegateObjectIVar)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeDelegateProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open func getRootMolecules() -> [MoleculeModelProtocol] {
|
||||
return model?.rootMolecules ?? []
|
||||
}
|
||||
|
||||
open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
||||
guard let name = name else { return nil }
|
||||
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
||||
|
||||
@ -33,11 +33,10 @@ public class PageGetContactBehavior: PageVisibilityBehavior {
|
||||
CNContactStore().requestAccess(for: .contacts) { [weak self] (access, error) in
|
||||
guard access,
|
||||
error == nil,
|
||||
// TODO: Clean up this interface
|
||||
let model = (self?.delegate?.moleculeDelegate as? PageProtocol)?.pageModel as? TemplateModelProtocol else { return }
|
||||
let rootMolecules = self?.delegate?.moleculeDelegate?.getRootMolecules() else { return }
|
||||
// Iterate models and provide contact
|
||||
let store = CNContactStore()
|
||||
let consumers: [PageGetContactBehaviorConsumerProtocol] = model.allMoleculesOfType()
|
||||
let consumers: [PageGetContactBehaviorConsumerProtocol] = rootMolecules.allMoleculesOfType()
|
||||
for consumer in consumers {
|
||||
guard let parameters = consumer.getMatchParameters(),
|
||||
let contacts = try? store.unifiedContacts(matching: parameters.0, keysToFetch: parameters.1) else { return }
|
||||
|
||||
@ -14,6 +14,15 @@ public protocol PageBehaviorProtocol: ModelHandlerProtocol {
|
||||
init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?)
|
||||
}
|
||||
|
||||
/**
|
||||
Behavior conforming protocols. Behaviors will conform to one or more of these protocols to receive page lifecycle events that pertain to them.
|
||||
*/
|
||||
|
||||
public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
|
||||
|
||||
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject)
|
||||
}
|
||||
|
||||
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||
|
||||
func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?)
|
||||
@ -22,7 +31,18 @@ public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||
|
||||
public protocol PageScrolledBehavior: PageBehaviorProtocol {
|
||||
|
||||
func pageScrolled(scrollView: UIScrollView,_ delegateObject: MVMCoreUIDelegateObject?)
|
||||
func pageScrolled(scrollView: UIScrollView, _ delegateObject: MVMCoreUIDelegateObject?)
|
||||
}
|
||||
|
||||
public protocol PageLocalDataShareBehavior: PageBehaviorProtocol {
|
||||
|
||||
func compileLocalPageDataForTransfer(_ delegateObject: MVMCoreUIDelegateObject) -> [AnyHashable: Any]
|
||||
func receiveLocalPageData(_ data:[AnyHashable: Any], _ delegateObject: MVMCoreUIDelegateObject)
|
||||
}
|
||||
|
||||
public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol {
|
||||
|
||||
func handleAction(type actionType: String?, information: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?) -> Bool
|
||||
}
|
||||
|
||||
public extension MVMCoreUIDelegateObject {
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
/// Protocol for molecules to implicity require behaviors.
|
||||
public protocol PageBehaviorProtocolRequirer {
|
||||
func getRequiredBehaviors() -> [PageBehaviorModelProtocol]
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user