Merge branch 'develop' into 'feature/develop_mvp_3'

Develop

See merge request BPHV_MIPS/mvm_core_ui!847
This commit is contained in:
Pfeil, Scott Robert 2022-05-03 20:34:59 +00:00
commit f8e71c3232
13 changed files with 87 additions and 68 deletions

View File

@ -348,7 +348,7 @@
D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */; };
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */; };
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; };
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* TemplateModel.swift */; };
D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */; };
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
D23118B325124E18001C8440 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23118B225124E18001C8440 /* Notification.swift */; };
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; };
@ -936,7 +936,7 @@
D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutConstraintExtension.swift; sourceTree = "<group>"; };
D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyLink.swift; sourceTree = "<group>"; };
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = "<group>"; };
D22D8392241C27B100D3DF69 /* TemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModel.swift; sourceTree = "<group>"; };
D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTemplateModel.swift; sourceTree = "<group>"; };
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
D23118B225124E18001C8440 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = "<group>"; };
@ -1986,7 +1986,7 @@
D29DF0DF21E418B2003B2FB9 /* Templates */ = {
isa = PBXGroup;
children = (
D22D8392241C27B100D3DF69 /* TemplateModel.swift */,
D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */,
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */,
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
@ -3077,7 +3077,7 @@
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */,
D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */,
012A88F123985E0100FE3DA1 /* Color.swift in Sources */,
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */,
D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */,
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */,
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */,

View File

@ -23,4 +23,33 @@ public protocol MoleculeDelegateProtocol: AnyObject {
extension MoleculeDelegateProtocol {
public func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
let moduleJSON: [AnyHashable: Any]? = getModuleWithName(moleculeName)
guard let moduleJSON = moduleJSON as? [String: Any],
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
else { return nil }
do {
return try modelType.decode(jsonDict: moduleJSON as [String : Any]) as? MoleculeModelProtocol
} catch {
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
}
return nil
}
}
extension MoleculeDelegateProtocol where Self: TemplateProtocol {
public func getRootMolecules() -> [MoleculeModelProtocol] {
templateModel?.rootMolecules ?? []
}
}
extension MoleculeDelegateProtocol where Self: MVMCoreViewControllerProtocol {
public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? {
guard let name = name else { return nil }
return loadObject??.modulesJSON?.optionalDictionaryForKey(name)
}
}

View File

@ -8,43 +8,46 @@
import Foundation
public protocol TemplateProtocol: AnyObject {
public protocol TemplateProtocol: AnyObject, PageProtocol {
associatedtype TemplateModel: TemplateModelProtocol
var templateModel: TemplateModel? { get set }
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel
}
public extension TemplateProtocol where Self: ViewController {
public extension TemplateProtocol {
// Utilize existing underlying property
var templateModel: TemplateModel? {
get {
pageModel as? TemplateModel
}
set {
var mutableSelf = self
mutableSelf.pageModel = newValue
}
}
/// Helper function to do common parsing logic.
func parseTemplate(json: [AnyHashable: Any]?) throws {
guard let pageJSON = json else { return }
let delegateObject = (self as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
let data = try JSONSerialization.data(withJSONObject: pageJSON)
let decoder = JSONDecoder()
try decoder.add(delegateObject: delegateObjectIVar)
if let delegateObject = delegateObject {
// Add the delegate to access mid parsing if applicable.
try decoder.add(delegateObject: delegateObject)
}
templateModel = try decodeTemplate(using: decoder, from: data)
model = templateModel as? MVMControllerModelProtocol
guard let model = model else { return }
traverseAndAddRequiredBehaviors()
var behaviorHandler = self
behaviorHandler.createBehaviors(for: model, delegateObject: delegateObjectIVar)
// Add additional required behaviors if applicable.
guard var behaviorHandlerModel = templateModel as? TemplateModelProtocol & PageBehaviorHandlerModelProtocol,
var behaviorHandler = self as? PageBehaviorHandlerProtocol else { return }
behaviorHandlerModel.traverseAndAddRequiredBehaviors()
behaviorHandler.createBehaviors(for: behaviorHandlerModel, delegateObject: delegateObject)
}
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
try decoder.decode(TemplateModel.self, from: data)
}
/// Traverses all models and adds any required behavior models.
func traverseAndAddRequiredBehaviors() {
guard var model = model else { return }
let behaviorModels: [PageBehaviorModelProtocol] = model.reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer {
return accumulator + behaviorRequirer.getRequiredBehaviors()
}
return accumulator
}
for behavior in behaviorModels {
model.add(behavior: behavior)
}
}
}

View File

@ -1,5 +1,5 @@
//
// TemplateModel.swift
// BaseTemplateModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/13/20.
@ -9,7 +9,7 @@
import Foundation
@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
@objcMembers open class BaseTemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------

View File

@ -13,7 +13,6 @@
//--------------------------------------------------
public typealias TemplateModel = CollectionTemplateModel
public var templateModel: CollectionTemplateModel?
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (CollectionItemModelProtocol & MoleculeModelProtocol))]?

View File

@ -19,9 +19,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
public var moleculesInfo: [MoleculeInfo]?
var observer: NSKeyValueObservation?
public var templateModel: ListPageTemplateModel?
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------

View File

@ -15,7 +15,6 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
//--------------------------------------------------
var observer: NSKeyValueObservation?
public var templateModel: StackPageTemplateModel?
//--------------------------------------------------
// MARK: - Lifecycle

View File

@ -7,7 +7,7 @@
//
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
@objcMembers open class ThreeLayerModelBase: BaseTemplateModel, ThreeLayerTemplateModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------

View File

@ -9,11 +9,6 @@
import UIKit
@objcMembers open class ThreeLayerTemplate<TemplateModel: ThreeLayerPageTemplateModel>: ThreeLayerViewController, TemplateProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var templateModel: TemplateModel?
//--------------------------------------------------
// MARK: - Lifecycle

View File

@ -484,26 +484,6 @@ import UIKit
model?.rootMolecules ?? []
}
open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
guard let name = name else { return nil }
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
}
open func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName),
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
else { return nil }
do {
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
} catch {
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
}
return nil
}
// Needed otherwise when subclassed, the extension gets called.
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
@ -618,12 +598,4 @@ import UIKit
selectedField = nil
}
}
//--------------------------------------------------
// MARK: - Behavior Execution
//--------------------------------------------------
public func executeBehaviors<T>(_ behaviorBlock: (_ behavior: T) -> Void) {
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
}
}

View File

@ -23,3 +23,19 @@ public extension PageBehaviorHandlerModelProtocol {
self.behaviors = newBehaviors
}
}
public extension PageBehaviorHandlerModelProtocol where Self: MoleculeTreeTraversalProtocol {
/// Traverses all models and adds any required behavior models.
mutating func traverseAndAddRequiredBehaviors() {
let behaviorModels: [PageBehaviorModelProtocol] = reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer {
return accumulator + behaviorRequirer.getRequiredBehaviors()
}
return accumulator
}
for behavior in behaviorModels {
add(behavior: behavior)
}
}
}

View File

@ -34,4 +34,9 @@ public extension PageBehaviorHandlerProtocol {
}
self.behaviors = behaviors.count > 0 ? behaviors : nil
}
/// Executes all behaviors of type.
func executeBehaviors<T>(_ behaviorBlock: (_ behavior: T) -> Void) {
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
}
}

View File

@ -50,8 +50,11 @@ public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol {
}
public extension MVMCoreUIDelegateObject {
var behaviorModelDelegate: PageBehaviorHandlerModelProtocol? {
(moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorHandlerModelProtocol
}
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
(moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
moleculeDelegate as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
}
}