split handlenewdata from updateUI. refactor behavior constuction. molecule iteration bug fixes. removing AnyObject requirement from ParentMoleculeProtocol.
This commit is contained in:
parent
41ce041a0d
commit
cd35990a95
@ -382,7 +382,7 @@
|
|||||||
D23A8FEE26122F7D007E14CE /* VisibleBehaviorForVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */; };
|
D23A8FEE26122F7D007E14CE /* VisibleBehaviorForVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */; };
|
||||||
D23A8FF82612308D007E14CE /* PageBehaviorProtocolRequirer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */; };
|
D23A8FF82612308D007E14CE /* PageBehaviorProtocolRequirer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */; };
|
||||||
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */; };
|
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */; };
|
||||||
D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */; };
|
D23A90002612347A007E14CE /* PageBehaviorConatinerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFF2612347A007E14CE /* PageBehaviorConatinerModelProtocol.swift */; };
|
||||||
D23A9004261234CE007E14CE /* PageBehaviorHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */; };
|
D23A9004261234CE007E14CE /* PageBehaviorHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */; };
|
||||||
D23A900926125FFB007E14CE /* GetContactBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A900826125FFB007E14CE /* GetContactBehavior.swift */; };
|
D23A900926125FFB007E14CE /* GetContactBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A900826125FFB007E14CE /* GetContactBehavior.swift */; };
|
||||||
D23A90682614B0B4007E14CE /* CoreUIModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */; };
|
D23A90682614B0B4007E14CE /* CoreUIModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */; };
|
||||||
@ -969,7 +969,7 @@
|
|||||||
D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleBehaviorForVideo.swift; sourceTree = "<group>"; };
|
D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleBehaviorForVideo.swift; sourceTree = "<group>"; };
|
||||||
D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorProtocolRequirer.swift; sourceTree = "<group>"; };
|
D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorProtocolRequirer.swift; sourceTree = "<group>"; };
|
||||||
D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorModelProtocol.swift; sourceTree = "<group>"; };
|
D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorHandlerModelProtocol.swift; sourceTree = "<group>"; };
|
D23A8FFF2612347A007E14CE /* PageBehaviorConatinerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorConatinerModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorHandlerProtocol.swift; sourceTree = "<group>"; };
|
D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorHandlerProtocol.swift; sourceTree = "<group>"; };
|
||||||
D23A900826125FFB007E14CE /* GetContactBehavior.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetContactBehavior.swift; sourceTree = "<group>"; };
|
D23A900826125FFB007E14CE /* GetContactBehavior.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetContactBehavior.swift; sourceTree = "<group>"; };
|
||||||
D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreUIModelMapping.swift; sourceTree = "<group>"; };
|
D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreUIModelMapping.swift; sourceTree = "<group>"; };
|
||||||
@ -1202,10 +1202,10 @@
|
|||||||
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */,
|
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */,
|
||||||
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */,
|
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */,
|
||||||
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
|
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
|
||||||
|
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
|
||||||
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
|
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
|
||||||
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
|
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
|
||||||
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */,
|
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */,
|
||||||
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
|
|
||||||
012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */,
|
012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */,
|
||||||
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
||||||
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */,
|
011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */,
|
||||||
@ -1321,7 +1321,7 @@
|
|||||||
children = (
|
children = (
|
||||||
D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */,
|
D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */,
|
||||||
D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */,
|
D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */,
|
||||||
D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */,
|
D23A8FFF2612347A007E14CE /* PageBehaviorConatinerModelProtocol.swift */,
|
||||||
D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */,
|
D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */,
|
||||||
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */,
|
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */,
|
||||||
);
|
);
|
||||||
@ -2720,7 +2720,7 @@
|
|||||||
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
|
||||||
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
|
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
|
||||||
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
|
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
|
||||||
D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */,
|
D23A90002612347A007E14CE /* PageBehaviorConatinerModelProtocol.swift in Sources */,
|
||||||
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
|
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
|
||||||
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
|
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
|
||||||
D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */,
|
D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */,
|
||||||
|
|||||||
@ -12,13 +12,15 @@ public protocol MoleculeContainerModelProtocol: ContainerModelProtocol, ParentMo
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension MoleculeContainerModelProtocol {
|
public extension MoleculeContainerModelProtocol {
|
||||||
|
|
||||||
var children: [MoleculeModelProtocol] {
|
var children: [MoleculeModelProtocol] {
|
||||||
return [molecule]
|
return [molecule]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension MoleculeContainerModelProtocol where Self: AnyObject {
|
||||||
|
|
||||||
func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
mutating func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||||
return try replaceChildMolecule(at: &molecule, with: replacementMolecule)
|
return try replaceChildMolecule(at: &molecule, with: replacementMolecule)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,11 +16,12 @@ public protocol StackModelProtocol: ParentMoleculeModelProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension StackModelProtocol {
|
extension StackModelProtocol {
|
||||||
|
|
||||||
public var children: [MoleculeModelProtocol] { return molecules }
|
public var children: [MoleculeModelProtocol] { return molecules }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StackModelProtocol where Self: AnyObject {
|
||||||
|
|
||||||
public func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
public mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool {
|
||||||
return try replaceChildMolecule(in: &molecules, with: molecule)
|
return try replaceChildMolecule(in: &molecules, with: molecule)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,8 +68,13 @@ public extension Array where Element == MoleculeModelProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) {
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) {
|
||||||
forEach { (molecule) in
|
var shouldStop = false
|
||||||
molecule.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit)
|
for molecule in self {
|
||||||
|
molecule.depthFirstTraverse(options: options, depth: depth) { depth, molecule, stop in
|
||||||
|
onVisit(depth, molecule, &shouldStop)
|
||||||
|
stop = shouldStop
|
||||||
|
}
|
||||||
|
if shouldStop { break }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,15 +8,15 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol ParentModelProtocol: MoleculeTreeTraversalProtocol, AnyObject {
|
public protocol ParentModelProtocol: MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
var children: [MoleculeModelProtocol] { get }
|
var children: [MoleculeModelProtocol] { get }
|
||||||
|
|
||||||
/// Method for replacing surface level children. (Does not recurse.)
|
/// Method for replacing surface level children. (Does not recurse.)
|
||||||
func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool
|
mutating func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension ParentModelProtocol {
|
public extension ParentModelProtocol where Self: AnyObject {
|
||||||
|
|
||||||
/// Top level test to replace child molecules. Each parent molecule should attempt to replace.
|
/// Top level test to replace child molecules. Each parent molecule should attempt to replace.
|
||||||
func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { return false }
|
func replaceChildMolecule(with molecule: MoleculeModelProtocol) throws -> Bool { return false }
|
||||||
|
|||||||
@ -37,9 +37,12 @@ public extension TemplateModelProtocol {
|
|||||||
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) {
|
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) {
|
||||||
return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit)
|
return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TemplateModelProtocol {
|
||||||
|
|
||||||
/// Recursively finds and replaces the first child matching the replacement molecule id property.
|
/// Recursively finds and replaces the first child matching the replacement molecule id property.
|
||||||
func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
mutating func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) throws -> Bool {
|
||||||
// Attempt root level replacement on the template model first.
|
// Attempt root level replacement on the template model first.
|
||||||
if try replaceChildMolecule(with: replacementMolecule) {
|
if try replaceChildMolecule(with: replacementMolecule) {
|
||||||
return true
|
return true
|
||||||
@ -49,7 +52,7 @@ public extension TemplateModelProtocol {
|
|||||||
var possibleError: Error?
|
var possibleError: Error?
|
||||||
// Dive into each root thereafter.
|
// Dive into each root thereafter.
|
||||||
depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in
|
depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in
|
||||||
guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return }
|
guard var parentMolecule = molecule as? ParentMoleculeModelProtocol else { return }
|
||||||
do {
|
do {
|
||||||
didReplaceMolecule = try parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
didReplaceMolecule = try parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol TemplateProtocol: AnyObject, PageProtocol {
|
public protocol TemplateProtocol: AnyObject, PageProtocol{
|
||||||
associatedtype TemplateModel: TemplateModelProtocol
|
associatedtype TemplateModel: TemplateModelProtocol
|
||||||
var templateModel: TemplateModel? { get set }
|
var templateModel: TemplateModel? { get set }
|
||||||
|
|
||||||
@ -28,25 +28,26 @@ public extension TemplateProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
||||||
|
try decoder.decode(TemplateModel.self, from: data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension TemplateProtocol where Self: PageBehaviorHandlerProtocol, Self: MVMCoreViewControllerProtocol {
|
||||||
|
|
||||||
/// Helper function to do common parsing logic.
|
/// Helper function to do common parsing logic.
|
||||||
func parseTemplate(json: [AnyHashable: Any]?) throws {
|
func parseTemplate(json: [AnyHashable: Any]?) throws {
|
||||||
guard let pageJSON = json else { return }
|
guard let pageJSON = json else { return }
|
||||||
let delegateObject = (self as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
|
let delegateObject = delegateObject?() as? MVMCoreUIDelegateObject
|
||||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||||
let decoder = JSONDecoder.create(with: delegateObject)
|
let decoder = JSONDecoder.create(with: delegateObject)
|
||||||
templateModel = try decodeTemplate(using: decoder, from: data)
|
templateModel = try decodeTemplate(using: decoder, from: data)
|
||||||
|
|
||||||
// Add additional required behaviors if applicable.
|
// Add additional required behaviors if applicable.
|
||||||
guard var behaviorHandlerModel = templateModel as? TemplateModelProtocol & PageBehaviorHandlerModelProtocol,
|
guard var pageBehaviorsModel = templateModel as? TemplateModelProtocol & PageBehaviorConatinerModelProtocol else { return }
|
||||||
var behaviorHandler = self as? PageBehaviorHandlerProtocol else { return }
|
|
||||||
behaviorHandlerModel.traverseAndAddRequiredBehaviors()
|
pageBehaviorsModel.traverseAndAddRequiredBehaviors()
|
||||||
behaviorHandler.createBehaviors(for: behaviorHandlerModel, delegateObject: delegateObject)
|
var behaviorHandler = self
|
||||||
if let viewController = self as? UIViewController {
|
behaviorHandler.applyBehaviors(pageBehaviorModel: pageBehaviorsModel, delegateObject: delegateObject)
|
||||||
MVMCoreUISession.sharedGlobal()?.applyGlobalBehaviors(to: viewController)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
|
||||||
try decoder.decode(TemplateModel.self, from: data)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,12 +80,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||||
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||||
setup()
|
setup()
|
||||||
registerCells()
|
registerCells()
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -21,8 +21,8 @@ open class ModalSectionListTemplate: SectionListTemplate {
|
|||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
override open func handleNewData() {
|
override open func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
_ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { [weak self] _ in
|
_ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { [weak self] _ in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
let closeAction = (self.templateModel as? ModalSectionListTemplateModel)?.closeAction ??
|
let closeAction = (self.templateModel as? ModalSectionListTemplateModel)?.closeAction ??
|
||||||
|
|||||||
@ -81,12 +81,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
return molecule
|
return molecule
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||||
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||||
setup()
|
setup()
|
||||||
registerWithTable()
|
registerWithTable()
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func viewDidAppear(_ animated: Bool) {
|
open override func viewDidAppear(_ animated: Bool) {
|
||||||
@ -300,7 +300,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeListTemplate: MoleculeListProtocol {
|
extension MoleculeListTemplate: MoleculeListProtocol {
|
||||||
open func removeMolecules(at indexPaths: [IndexPath], animation: UITableView.RowAnimation?) {
|
public func removeMolecules(at indexPaths: [IndexPath], animation: UITableView.RowAnimation?) {
|
||||||
for (index, indexPath) in indexPaths.sorted().enumerated() {
|
for (index, indexPath) in indexPaths.sorted().enumerated() {
|
||||||
let removeIndex = indexPath.row - index
|
let removeIndex = indexPath.row - index
|
||||||
moleculesInfo?.remove(at: removeIndex)
|
moleculesInfo?.remove(at: removeIndex)
|
||||||
@ -313,7 +313,7 @@ extension MoleculeListTemplate: MoleculeListProtocol {
|
|||||||
view.layoutIfNeeded()
|
view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation?) {
|
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation?) {
|
||||||
var indexPaths: [IndexPath] = []
|
var indexPaths: [IndexPath] = []
|
||||||
|
|
||||||
for molecule in molecules {
|
for molecule in molecules {
|
||||||
@ -332,7 +332,7 @@ extension MoleculeListTemplate: MoleculeListProtocol {
|
|||||||
self.view.layoutIfNeeded()
|
self.view.layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
open func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? {
|
public func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? {
|
||||||
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
guard let index = moleculesInfo?.firstIndex(where: { (moleculeInfo) -> Bool in
|
||||||
return equal(moleculeA: molecule, moleculeB: moleculeInfo.molecule)
|
return equal(moleculeA: molecule, moleculeB: moleculeInfo.molecule)
|
||||||
}) else { return nil }
|
}) else { return nil }
|
||||||
|
|||||||
@ -26,8 +26,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
heightConstraint?.isActive = true
|
heightConstraint?.isActive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,10 +19,10 @@ import UIKit
|
|||||||
try super.parsePageJSON()
|
try super.parsePageJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
topViewOutsideOfScroll = templateModel?.anchorHeader ?? false
|
topViewOutsideOfScroll = templateModel?.anchorHeader ?? false
|
||||||
bottomViewOutsideOfScroll = templateModel?.anchorFooter ?? false
|
bottomViewOutsideOfScroll = templateModel?.anchorFooter ?? false
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func viewForTop() -> UIView? {
|
open override func viewForTop() -> UIView? {
|
||||||
|
|||||||
@ -9,6 +9,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorHandlerModelProtocol {
|
public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorConatinerModelProtocol {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,8 +63,8 @@ open class ScrollingViewController: ViewController {
|
|||||||
registerForKeyboardNotifications()
|
registerForKeyboardNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
// will change scrollView indicatorStyle automatically on the basis of backgroundColor
|
// will change scrollView indicatorStyle automatically on the basis of backgroundColor
|
||||||
var greyScale: CGFloat = 0
|
var greyScale: CGFloat = 0
|
||||||
if view.backgroundColor?.getWhite(&greyScale, alpha: nil) ?? false {
|
if view.backgroundColor?.getWhite(&greyScale, alpha: nil) ?? false {
|
||||||
|
|||||||
@ -108,8 +108,8 @@ import Foundation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
topView?.removeFromSuperview()
|
topView?.removeFromSuperview()
|
||||||
bottomView?.removeFromSuperview()
|
bottomView?.removeFromSuperview()
|
||||||
topView = viewForTop()
|
topView = viewForTop()
|
||||||
|
|||||||
@ -50,8 +50,8 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
tableView.reloadData()
|
tableView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
createViewForTableHeader()
|
createViewForTableHeader()
|
||||||
createViewForTableFooter()
|
createViewForTableFooter()
|
||||||
tableView?.reloadData()
|
tableView?.reloadData()
|
||||||
|
|||||||
@ -49,8 +49,8 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func updateUI() {
|
||||||
super.handleNewData()
|
super.updateUI()
|
||||||
|
|
||||||
// Removes the views
|
// Removes the views
|
||||||
topView?.removeFromSuperview()
|
topView?.removeFromSuperview()
|
||||||
|
|||||||
@ -111,9 +111,12 @@ import MVMCore
|
|||||||
guard newData else { return }
|
guard newData else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
// TODO: Parse parsePageJSON modifies the page model on a different thread than
|
||||||
|
// the UI update which could cause discrepancies. Parse should return the resulting
|
||||||
|
// object and assignment should be synchronized on handleNewData(model: ).
|
||||||
try parsePageJSON()
|
try parsePageJSON()
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
self.handleNewDataAndUpdateUI()
|
self.handleNewData()
|
||||||
})
|
})
|
||||||
} catch {
|
} catch {
|
||||||
if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: pageType))") {
|
if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: pageType))") {
|
||||||
@ -160,7 +163,7 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,9 +232,12 @@ import MVMCore
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls processNewData and then sets the ui to update with updateView
|
@MainActor
|
||||||
open func handleNewDataAndUpdateUI() {
|
open func updateUI() {
|
||||||
handleNewData()
|
if let backgroundColor = model?.backgroundColor {
|
||||||
|
view.backgroundColor = backgroundColor.uiColor
|
||||||
|
}
|
||||||
|
|
||||||
needsUpdateUI = true
|
needsUpdateUI = true
|
||||||
view.setNeedsLayout()
|
view.setNeedsLayout()
|
||||||
}
|
}
|
||||||
@ -244,6 +250,7 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
|
/// Processes any new data. Called after the page is loaded the first time and on response updates for this page,
|
||||||
|
@MainActor
|
||||||
open func handleNewData() {
|
open func handleNewData() {
|
||||||
if model?.navigationBar == nil {
|
if model?.navigationBar == nil {
|
||||||
let navigationItem = createDefaultLegacyNavigationModel()
|
let navigationItem = createDefaultLegacyNavigationModel()
|
||||||
@ -259,12 +266,10 @@ import MVMCore
|
|||||||
formValidator = FormValidator(rules)
|
formValidator = FormValidator(rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let backgroundColor = model?.backgroundColor {
|
|
||||||
view.backgroundColor = backgroundColor.uiColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the manager of new data
|
// Notify the manager of new data
|
||||||
manager?.newDataReceived?(in: self)
|
manager?.newDataReceived?(in: self)
|
||||||
|
|
||||||
|
updateUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func generateMoleculeView(from model: MoleculeModelProtocol) -> MoleculeViewProtocol? {
|
public func generateMoleculeView(from model: MoleculeModelProtocol) -> MoleculeViewProtocol? {
|
||||||
@ -333,7 +338,7 @@ import MVMCore
|
|||||||
initialLoad()
|
initialLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNewDataAndUpdateUI()
|
handleNewData()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func viewDidLayoutSubviews() {
|
open override func viewDidLayoutSubviews() {
|
||||||
|
|||||||
@ -43,7 +43,7 @@ public class PageGetContactBehavior: PageVisibilityBehavior {
|
|||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
// TODO: move to protocol function instead
|
// TODO: move to protocol function instead
|
||||||
guard let controller = self?.delegate?.moleculeDelegate as? ViewController else { return }
|
guard let controller = self?.delegate?.moleculeDelegate as? ViewController else { return }
|
||||||
controller.handleNewDataAndUpdateUI()
|
controller.handleNewData()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,11 +45,12 @@ public class GetNotificationAuthStatusBehavior: PageVisibilityBehavior {
|
|||||||
for consumer in consumers {
|
for consumer in consumers {
|
||||||
consumer.consume(notificationStatus: settings.authorizationStatus)
|
consumer.consume(notificationStatus: settings.authorizationStatus)
|
||||||
}
|
}
|
||||||
// Tell template to update
|
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
Task {
|
||||||
|
// Tell template to update
|
||||||
guard let controller = self.delegate?.moleculeDelegate as? ViewController else { return }
|
guard let controller = self.delegate?.moleculeDelegate as? ViewController else { return }
|
||||||
controller.handleNewDataAndUpdateUI()
|
await controller.handleNewData()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
//
|
//
|
||||||
// PageBehaviorHandlerModelProtocol.swift
|
// PageBehaviorConatinerModelProtocol.swift
|
||||||
// MVMCoreUI
|
// MVMCoreUI
|
||||||
//
|
//
|
||||||
// Created by Scott Pfeil on 3/29/21.
|
// Created by Scott Pfeil on 3/29/21.
|
||||||
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
public protocol PageBehaviorHandlerModelProtocol {
|
/// Protocol applied to a model that contains a list of behavior models.
|
||||||
|
public protocol PageBehaviorConatinerModelProtocol {
|
||||||
var behaviors: [PageBehaviorModelProtocol]? { get set }
|
var behaviors: [PageBehaviorModelProtocol]? { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension PageBehaviorHandlerModelProtocol {
|
public extension PageBehaviorConatinerModelProtocol {
|
||||||
|
|
||||||
/// Adds the behavior model to the behaviors if possible.
|
/// Adds the behavior model to the behaviors if possible.
|
||||||
mutating func add(behavior: PageBehaviorModelProtocol) {
|
mutating func add(behavior: PageBehaviorModelProtocol) {
|
||||||
@ -24,7 +25,7 @@ public extension PageBehaviorHandlerModelProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension PageBehaviorHandlerModelProtocol where Self: MoleculeTreeTraversalProtocol {
|
public extension PageBehaviorConatinerModelProtocol where Self: MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
/// Traverses all models and adds any required behavior models.
|
/// Traverses all models and adds any required behavior models.
|
||||||
mutating func traverseAndAddRequiredBehaviors() {
|
mutating func traverseAndAddRequiredBehaviors() {
|
||||||
@ -12,20 +12,10 @@ public protocol PageBehaviorHandlerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension PageBehaviorHandlerProtocol {
|
public extension PageBehaviorHandlerProtocol {
|
||||||
|
|
||||||
/// Creates the behaviors and sets the variable.
|
/// Creates the behaviors and sets the variable.
|
||||||
mutating func createBehaviors(for model: PageBehaviorHandlerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
func createBehaviors(for behaviorModels: [PageBehaviorModelProtocol], delegateObject: MVMCoreUIDelegateObject?) -> [PageBehaviorProtocol] {
|
||||||
|
var behaviors = [PageBehaviorProtocol]()
|
||||||
behaviors = behaviors?.filter { $0.transcendsPageUpdates }
|
|
||||||
if behaviors?.isEmpty ?? false {
|
|
||||||
behaviors = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let behaviorModels = model.behaviors else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var behaviors: [PageBehaviorProtocol] = behaviors ?? []
|
|
||||||
|
|
||||||
for behaviorModel in behaviorModels {
|
for behaviorModel in behaviorModels {
|
||||||
do {
|
do {
|
||||||
let handlerType = try ModelRegistry.getHandler(behaviorModel) as! PageBehaviorProtocol.Type
|
let handlerType = try ModelRegistry.getHandler(behaviorModel) as! PageBehaviorProtocol.Type
|
||||||
@ -37,7 +27,23 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return behaviors
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func applyBehaviors(pageBehaviorModel: PageBehaviorConatinerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
// Pull the existing behaviors.
|
||||||
|
var behaviors = (behaviors ?? []).filter { $0.transcendsPageUpdates }
|
||||||
|
// Create and append any new behaviors based on the incoming models.
|
||||||
|
let newBehaviors = createBehaviors(for: pageBehaviorModel.behaviors ?? [], delegateObject: delegateObject)
|
||||||
|
behaviors.append(contentsOf: newBehaviors)
|
||||||
|
|
||||||
|
// Apply them to the page.
|
||||||
self.behaviors = behaviors.count > 0 ? behaviors : nil
|
self.behaviors = behaviors.count > 0 ? behaviors : nil
|
||||||
|
|
||||||
|
// Ask the session to apply any more. (Curently inverted contol due to Swift <--> Obj-C conflict.
|
||||||
|
if let viewController = self as? UIViewController {
|
||||||
|
MVMCoreUISession.sharedGlobal()?.applyGlobalBehaviors(to: viewController)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes all behaviors of type.
|
/// Executes all behaviors of type.
|
||||||
@ -49,3 +55,11 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? true
|
return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension PageBehaviorHandlerProtocol where Self: MVMCoreViewControllerProtocol {
|
||||||
|
|
||||||
|
mutating func applyBehaviors(pageBehaviorModel: PageBehaviorConatinerModelProtocol) {
|
||||||
|
applyBehaviors(pageBehaviorModel: pageBehaviorModel, delegateObject: delegateObject?() as? MVMCoreUIDelegateObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -86,8 +86,8 @@ public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension MVMCoreUIDelegateObject {
|
public extension MVMCoreUIDelegateObject {
|
||||||
var behaviorModelDelegate: PageBehaviorHandlerModelProtocol? {
|
var behaviorModelDelegate: PageBehaviorConatinerModelProtocol? {
|
||||||
(moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorHandlerModelProtocol
|
(moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorConatinerModelProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
|
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior {
|
|||||||
|
|
||||||
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) {
|
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
|
||||||
guard let templateModel = delegateObject?.moleculeDelegate?.getTemplateModel() else { return }
|
guard var templateModel = delegateObject?.moleculeDelegate?.getTemplateModel() else { return }
|
||||||
|
|
||||||
templateModel.printMolecules()
|
templateModel.printMolecules()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user