Merge branch 'develop' into feature/fix_form_rules

This commit is contained in:
Suresh, Kamlesh 2021-04-05 11:26:42 -04:00
commit 08c83872d5
63 changed files with 1009 additions and 608 deletions

View File

@ -53,7 +53,6 @@
017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */; };
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */; };
017BEB7B236763000024EF95 /* LineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7A236763000024EF95 /* LineModel.swift */; };
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */; };
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; };
01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */; };
@ -123,7 +122,9 @@
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; };
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehavior.swift */; };
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */; };
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */; };
27F973532466074500CAB5C5 /* PageBehaviorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */; };
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; };
31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; };
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; };
@ -346,13 +347,19 @@
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; };
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; };
D23A8FEB26122F69007E14CE /* VisibleBehaviorForVideoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FEA26122F69007E14CE /* VisibleBehaviorForVideoModel.swift */; };
D23A8FEE26122F7D007E14CE /* VisibleBehaviorForVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */; };
D23A8FF82612308D007E14CE /* PageBehaviorProtocolRequirer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */; };
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */; };
D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */; };
D23A9004261234CE007E14CE /* PageBehaviorHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */; };
D23A900926125FFB007E14CE /* GetContactBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A900826125FFB007E14CE /* GetContactBehavior.swift */; };
D23A90682614B0B4007E14CE /* CoreUIModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */; };
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; };
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; };
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; };
D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */; };
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
D24918F625D5AD8E00CAB4B1 /* PageVisibilityClosureBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24918F525D5AD8E00CAB4B1 /* PageVisibilityClosureBehavior.swift */; };
D24918FA25D5ADBB00CAB4B1 /* PageScrolledClosureBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24918F925D5ADBA00CAB4B1 /* PageScrolledClosureBehavior.swift */; };
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; };
D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */; };
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; };
@ -607,7 +614,6 @@
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonLabel.swift; sourceTree = "<group>"; };
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeViewProtocol.swift; sourceTree = "<group>"; };
017BEB7A236763000024EF95 /* LineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineModel.swift; sourceTree = "<group>"; };
017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeObjectMapping.swift; sourceTree = "<group>"; };
01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = "<group>"; };
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeModelProtocol.swift; sourceTree = "<group>"; };
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
@ -679,7 +685,9 @@
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = "<group>"; };
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
27F973522466074500CAB5C5 /* PageBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehavior.swift; sourceTree = "<group>"; };
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTreeTraversalProtocol.swift; sourceTree = "<group>"; };
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentMoleculeModelProtocol.swift; sourceTree = "<group>"; };
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageBehaviorProtocol.swift; sourceTree = "<group>"; };
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = "<group>"; };
31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = "<group>"; };
31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = "<group>"; };
@ -902,13 +910,19 @@
D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = "<group>"; };
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; };
D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; };
D23A8FEA26122F69007E14CE /* VisibleBehaviorForVideoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleBehaviorForVideoModel.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>"; };
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>"; };
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>"; };
D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreUIModelMapping.swift; sourceTree = "<group>"; };
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = "<group>"; };
D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = "<group>"; };
D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = "<group>"; };
D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageBarButtonItem.swift; sourceTree = "<group>"; };
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
D24918F525D5AD8E00CAB4B1 /* PageVisibilityClosureBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageVisibilityClosureBehavior.swift; sourceTree = "<group>"; };
D24918F925D5ADBA00CAB4B1 /* PageScrolledClosureBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageScrolledClosureBehavior.swift; sourceTree = "<group>"; };
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = "<group>"; };
D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationImageButtonModel.swift; sourceTree = "<group>"; };
D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = "<group>"; };
@ -1147,6 +1161,7 @@
D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */,
D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */,
D28BA74C248589C800B75CB8 /* TabPageModelProtocol.swift */,
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
);
path = ModelProtocols;
sourceTree = "<group>";
@ -1281,10 +1296,13 @@
27F973512466071600CAB5C5 /* Behaviors */ = {
isa = PBXGroup;
children = (
27F973522466074500CAB5C5 /* PageBehavior.swift */,
D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */,
D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */,
D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */,
D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */,
27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */,
27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */,
D24918F525D5AD8E00CAB4B1 /* PageVisibilityClosureBehavior.swift */,
D24918F925D5ADBA00CAB4B1 /* PageScrolledClosureBehavior.swift */,
D23A900826125FFB007E14CE /* GetContactBehavior.swift */,
);
path = Behaviors;
sourceTree = "<group>";
@ -1703,6 +1721,18 @@
path = TwoColumn;
sourceTree = "<group>";
};
D23A8FE926122F41007E14CE /* Video */ = {
isa = PBXGroup;
children = (
D29C559525C099630082E7D6 /* VideoDataManager.swift */,
D29C559225C0992D0082E7D6 /* VideoModel.swift */,
D29C558F25C095210082E7D6 /* Video.swift */,
D23A8FEA26122F69007E14CE /* VisibleBehaviorForVideoModel.swift */,
D23A8FED26122F7D007E14CE /* VisibleBehaviorForVideo.swift */,
);
path = Video;
sourceTree = "<group>";
};
D23EA7FC247EBB7500D60C34 /* Buttons */ = {
isa = PBXGroup;
children = (
@ -2050,6 +2080,7 @@
D29DF17D21E69E26003B2FB9 /* Views */ = {
isa = PBXGroup;
children = (
D23A8FE926122F41007E14CE /* Video */,
0A9D09162433796500D2E6C0 /* CarouselIndicator */,
9445890B2385BCE300DE9FD4 /* ProgressBarModel.swift */,
01509D922327ECFB00EF99AA /* ProgressBar.swift */,
@ -2082,9 +2113,6 @@
AA37CBD42519072F0027344C /* Stars.swift */,
AA07EA902510A442009A2AE3 /* StarModel.swift */,
AA07EA922510A451009A2AE3 /* Star.swift */,
D29C559525C099630082E7D6 /* VideoDataManager.swift */,
D29C559225C0992D0082E7D6 /* VideoModel.swift */,
D29C558F25C095210082E7D6 /* Video.swift */,
);
path = Views;
sourceTree = "<group>";
@ -2143,6 +2171,7 @@
D2ED2817254B112900A1C293 /* MVMCoreUIActionDelegateProtocol.h */,
D2ED281B254B119D00A1C293 /* MVMCoreUIActionHandler.h */,
D2ED281C254B119D00A1C293 /* MVMCoreUIActionHandler.m */,
D23A90672614B0B4007E14CE /* CoreUIModelMapping.swift */,
);
path = OtherHandlers;
sourceTree = "<group>";
@ -2259,7 +2288,6 @@
D2C78CD324252F4E00B69FDE /* Atomic */ = {
isa = PBXGroup;
children = (
017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */,
94C01508242155FE005811A9 /* Actions */,
D202AFE2242A5F1400E5BEDF /* Extensions */,
D2C78CD424252F5D00B69FDE /* Protocols */,
@ -2275,6 +2303,7 @@
isa = PBXGroup;
children = (
012A88C7238DB02000FE3DA1 /* MoleculeDelegateProtocol.swift */,
27F6B08726051831008529AA /* MoleculeTreeTraversalProtocol.swift */,
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
D20F3B43252E00E4004B3F56 /* PageProtocol.swift */,
012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */,
@ -2486,6 +2515,7 @@
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */,
D23A90682614B0B4007E14CE /* CoreUIModelMapping.swift in Sources */,
31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */,
8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */,
AAA7CD6B250642080045B959 /* Heart.swift in Sources */,
@ -2573,6 +2603,7 @@
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */,
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,
011D9602240DA20A000E3791 /* FormRuleWatcherFieldProtocol.swift in Sources */,
D23A900926125FFB007E14CE /* GetContactBehavior.swift in Sources */,
D264FAA1243CF66B00D98315 /* ContainerCollectionReusableView.swift in Sources */,
AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */,
D260106323D0C05000764D80 /* StackItemModel.swift in Sources */,
@ -2584,11 +2615,13 @@
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */,
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */,
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */,
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */,
D23A8FEB26122F69007E14CE /* VisibleBehaviorForVideoModel.swift in Sources */,
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */,
D2CAC7D3251105A700C75681 /* MVMCoreUITopAlertExpandableView+Extension.swift in Sources */,
AA07EA932510A451009A2AE3 /* Star.swift in Sources */,
@ -2606,6 +2639,7 @@
D2ED27EC254B0CE700A1C293 /* UIAlertControllerStyle+Extension.swift in Sources */,
C695A69623C990BC00BFB94E /* DoughnutChart.swift in Sources */,
014AA72D23C5059B006F3E93 /* StackPageTemplateModel.swift in Sources */,
D23A8FEE26122F7D007E14CE /* VisibleBehaviorForVideo.swift in Sources */,
0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */,
D260106123D0C02A00764D80 /* StackItemModelProtocol.swift in Sources */,
0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */,
@ -2627,6 +2661,7 @@
AAC23FAF24D92A1E009208DF /* ListThreeColumnSpeedTest.swift in Sources */,
0A0FEC7425D42A5E00AF2548 /* BaseItemPickerEntryField.swift in Sources */,
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
D23A8FF82612308D007E14CE /* PageBehaviorProtocolRequirer.swift in Sources */,
D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */,
D2ED27ED254B0CE700A1C293 /* ActionPopupModel.swift in Sources */,
94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */,
@ -2749,9 +2784,7 @@
94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */,
011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */,
011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */,
D24918F625D5AD8E00CAB4B1 /* PageVisibilityClosureBehavior.swift in Sources */,
D20492A624329CE200A5EED6 /* LoadImageView.swift in Sources */,
017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */,
D274CA332236A78900B01B62 /* FooterView.swift in Sources */,
014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */,
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
@ -2820,6 +2853,7 @@
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */,
D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */,
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */,
27F6B08826051831008529AA /* MoleculeTreeTraversalProtocol.swift in Sources */,
D2D3957A252FDBB300047B11 /* ModalSectionListTemplate.swift in Sources */,
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */,
D28BA741248025A300B75CB8 /* TabBarModel.swift in Sources */,
@ -2835,7 +2869,6 @@
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
D24918FA25D5ADBB00CAB4B1 /* PageScrolledClosureBehavior.swift in Sources */,
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
@ -2901,7 +2934,7 @@
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */,
0AB000BC24BF64A50090C5E7 /* ModalStackPageTemplateModel.swift in Sources */,
27F973532466074500CAB5C5 /* PageBehavior.swift in Sources */,
27F973532466074500CAB5C5 /* PageBehaviorProtocol.swift in Sources */,
94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */,
D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */,
D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */,
@ -2910,6 +2943,7 @@
012A88F123985E0100FE3DA1 /* Color.swift in Sources */,
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */,
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */,
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */,
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */,
0AA4D2E125CAEC72008DB32D /* AccessibilityModelProtocol.swift in Sources */,
@ -2945,6 +2979,7 @@
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
@ -2971,6 +3006,7 @@
011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */,
AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */,
011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */,
D23A9004261234CE007E14CE /* PageBehaviorHandlerProtocol.swift in Sources */,
01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */,
D2169301251E51E7002A6324 /* SectionListTemplate.swift in Sources */,
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */,

View File

@ -7,12 +7,12 @@
//
@objcMembers public class LabelModel: MoleculeModelProtocol {
@objcMembers open class LabelModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "label"
open class var identifier: String { "label" }
public var backgroundColor: Color?
public var text: String
public var accessibilityText: String?

View File

@ -8,7 +8,7 @@
import Foundation
open class VideoModel: MoleculeModelProtocol {
open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer {
public static var identifier = "video"
public var backgroundColor: Color?
public var video: String
@ -39,8 +39,6 @@ open class VideoModel: MoleculeModelProtocol {
/// Keeps a reference to the video data.
public var videoDataManager: VideoDataManager
private weak var visibleBehavior: PageVisibilityClosureBehavior?
private weak var scrollBehavior: PageScrolledClosureBehavior?
private var activeListener: Any?
private var resignActiveListener: Any?
@ -81,61 +79,16 @@ open class VideoModel: MoleculeModelProtocol {
try container.encode(alwaysReset, forKey: .alwaysReset)
}
public func getRequiredBehaviors() -> [PageBehaviorModelProtocol] {
return [VisibleBehaviorForVideoModel(with: self)]
}
open func addVisibilityHalting(for view: Video, delegateObject: MVMCoreUIDelegateObject?) {
self.view = view
halted = false
addVisibleBehavior(for: view, delegateObject: delegateObject)
addScrollBehavior(for: view, delegateObject: delegateObject)
addActiveListener(for: view, delegateObject: delegateObject)
}
/// Adds a behavior to pause the video on page hidden behavior and unpause if necessary on page shown.
open func addVisibleBehavior(for view: Video, delegateObject: MVMCoreUIDelegateObject?) {
let onShow = { [weak self] in
guard let self = self,
let view = self.view,
view.isVisibleInDelegate() else { return }
self.halted = false
}
let onHide: () -> Void = { [weak self] in
self?.halted = true
}
guard visibleBehavior == nil else {
visibleBehavior?.pageShownHandler = onShow
visibleBehavior?.pageHiddenHandler = onHide
return
}
guard var delegate = delegateObject?.behaviorTemplateDelegate else { return }
let pauseBehavior = PageVisibilityClosureBehavior(with: onShow, onPageHiddenHandler: onHide)
delegate.add(behavior: pauseBehavior)
self.visibleBehavior = pauseBehavior
}
/// Adds a behavior to pause the video if scrolled off of the page and unpause if necessary if scrolled on.
open func addScrollBehavior(for view: Video, delegateObject: MVMCoreUIDelegateObject?) {
let onScroll = { [weak self] (scrollView: UIScrollView) in
// If visible to not visible, pause video.
// If not visible to visible, unpause if needed, add visible behavior
guard let self = self,
let view = self.view else { return }
self.halted = !view.isVisible(in: scrollView)
}
guard scrollBehavior == nil else {
scrollBehavior?.pageScrolledHandler = onScroll
return
}
guard var delegate = delegateObject?.behaviorTemplateDelegate else { return }
let scrollBehavior = PageScrolledClosureBehavior(with: onScroll)
delegate.add(behavior: scrollBehavior)
self.scrollBehavior = scrollBehavior
}
open func addActiveListener(for view: Video, delegateObject: MVMCoreUIDelegateObject?) {
removeActiveListener()

View File

@ -0,0 +1,36 @@
//
// VisibleBehaviorForVideo.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
open class VisibleBehaviorForVideo: PageVisibilityBehavior, PageScrolledBehavior {
var model: PageBehaviorModelProtocol
required public init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
self.model = model
}
public func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) {
guard let model = (model as? VisibleBehaviorForVideoModel)?.videoModel,
let view = model.view,
view.isVisibleInDelegate() else { return }
model.halted = false
}
public func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?) {
(model as? VisibleBehaviorForVideoModel)?.videoModel?.halted = true
}
public func pageScrolled(scrollView: UIScrollView, _ delegateObject: MVMCoreUIDelegateObject?) {
// If visible to not visible, pause video.
// If not visible to visible, unpause if needed, add visible behavior
guard let model = (model as? VisibleBehaviorForVideoModel)?.videoModel,
let view = model.view else { return }
model.halted = !view.isVisible(in: scrollView)
}
}

View File

@ -0,0 +1,20 @@
//
// VisibleBehaviorForVideoModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
open class VisibleBehaviorForVideoModel: PageBehaviorModelProtocol {
public static var identifier: String = "visibleBehaviorForVideoModel"
public var shouldAllowMultipleInstances: Bool = true
public weak var videoModel: VideoModel?
init(with videoModel: VideoModel) {
self.videoModel = videoModel
}
}

View File

@ -1,285 +0,0 @@
//
// MoleculeObjectMapping.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 10/28/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers public class MoleculeObjectMapping: NSObject {
/// Returns the mapping object stored in the singleton
public static func shared() -> Self? {
return MVMCoreActionUtility.initializerClassCheck(CoreUIObject.sharedInstance()?.moleculeMap, classToVerify: self) as? Self
}
/// Registers the model with the model registry and the view with the mapper.
public func register<M: ModelProtocol, V: MoleculeViewProtocol>(viewClass: V.Type, viewModelClass: M.Type) {
try? ModelRegistry.register(handler: viewClass, for: viewModelClass)
}
/// Returns the type of molecule view for the given model
public func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
return ModelRegistry.getHandler(model) as? MoleculeViewProtocol.Type
}
/// Creates a molecule with the given model.
public func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
guard let type = getMoleculeClass(model) else { return nil }
return type.init(model: model, delegateObject, additionalData)
}
/// Convenience function for legacy classes
public func getMoleculeModelForJSON(_ json: [String: Any], delegateObject: DelegateObject? = nil) throws -> MoleculeModelProtocol? {
guard let moleculeName = json.optionalStringForKey(KeyMoleculeName),
let type = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else {
throw ModelRegistry.Error.decoderErrorModelNotMapped()
}
guard let model = try type.decode(jsonDict: json, delegateObject: delegateObject) as? MoleculeModelProtocol else {
throw ModelRegistry.Error.decoderError
}
return model
}
/// Call to register all of the CoreUI molecules.
public static func registerObjects() {
// MARK:- Stacks
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackView.self, viewModelClass: StackModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: UnOrderedList.self, viewModelClass: UnOrderedListModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: NumberedList.self, viewModelClass: NumberedListModel.self)
// MARK:- Label
MoleculeObjectMapping.shared()?.register(viewClass: Label.self, viewModelClass: LabelModel.self)
// need to move labelattributemodel to different method
try? ModelRegistry.register(LabelAttributeFontModel.self)
try? ModelRegistry.register(LabelAttributeColorModel.self)
try? ModelRegistry.register(LabelAttributeImageModel.self)
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
try? ModelRegistry.register(LabelAttributeActionModel.self)
// MARK:- TextView
MoleculeObjectMapping.shared()?.register(viewClass: TextViewEntryField.self, viewModelClass: TextViewEntryFieldModel.self)
// MARK:- Buttons
MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ExternalLink.self, viewModelClass: ExternalLinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Link.self, viewModelClass: LinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CaretLink.self, viewModelClass: CaretLinkModel.self)
// MARK:- Entry Field
MoleculeObjectMapping.shared()?.register(viewClass: TextEntryField.self, viewModelClass: TextEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MdnEntryField.self, viewModelClass: MdnEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DigitEntryField.self, viewModelClass: DigitEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ItemDropdownEntryField.self, viewModelClass: ItemDropdownEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DateDropdownEntryField.self, viewModelClass: DateDropdownEntryFieldModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MultiItemDropdownEntryField.self, viewModelClass: MultiItemDropdownEntryFieldModel.self)
// MARK:- Selectors
MoleculeObjectMapping.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: RadioBoxes.self, viewModelClass: RadioBoxesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: RadioSwatches.self, viewModelClass: RadioSwatchesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Heart.self, viewModelClass: HeartModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Stars.self, viewModelClass: StarsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Star.self, viewModelClass: StarModel.self)
// MARK:- Other Atoms
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CaretView.self, viewModelClass: CaretViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DashLine.self, viewModelClass: DashLineModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LoadImageView.self, viewModelClass: ImageViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Line.self, viewModelClass: LineModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Wheel.self, viewModelClass: WheelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: WebView.self, viewModelClass: WebViewModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LoadingSpinner.self, viewModelClass: LoadingSpinnerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Video.self, viewModelClass: VideoModel.self)
// MARK:- Horizontal Combination Molecules
MoleculeObjectMapping.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ImageHeadlineBody.self, viewModelClass: ImageHeadlineBodyModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tabs.self, viewModelClass: TabsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TwoLinkView.self, viewModelClass: TwoLinkViewModel.self)
// MARK:- Vertical Combination Molecules
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBody.self, viewModelClass: HeadlineBodyModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadLineBodyCaretLinkImage.self, viewModelClass: HeadlineBodyCaretLinkImageModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: EyebrowHeadlineBodyLink.self, viewModelClass: EyebrowHeadlineBodyLinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLink.self, viewModelClass: HeadlineBodyLinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyButton.self, viewModelClass: HeadlineBodyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BGImageHeadlineBodyButton.self, viewModelClass: BGImageHeadlineBodyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ThreeHeadlineBodyLink.self, viewModelClass: ThreeHeadlineBodyLinkModel.self)
// MARK:- Left Right Molecules
MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LeftRightLabelView.self, viewModelClass: LeftRightLabelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LabelToggle.self, viewModelClass: LabelToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyToggle.self, viewModelClass: HeadlineBodyToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyLinkToggle.self, viewModelClass: HeadlineBodyLinkToggleModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ActionDetailWithImage.self, viewModelClass: ActionDetailWithImageModel.self)
// MARK:- List items
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeTableViewCell.self, viewModelClass: MoleculeListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: DropDownFilterTableViewCell.self, viewModelClass: DropDownListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: AccordionMoleculeTableViewCell.self, viewModelClass: AccordionListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: TabsTableViewCell.self, viewModelClass: TabsListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarData.self, viewModelClass: ListProgressBarDataModel.self)
// MARK:- Other Items
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeStackItem.self, viewModelClass: MoleculeStackItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: StackItem.self, viewModelClass: StackItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: MoleculeCollectionItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CarouselItem.self, viewModelClass: CarouselItemModel.self)
// MARK:- Other Container Molecules
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeContainer.self, viewModelClass: MoleculeContainerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BGImageMolecule.self, viewModelClass: BGImageMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BGVideoImageMolecule.self, viewModelClass: BGVideoImageMoleculeModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeSectionHeader.self, viewModelClass: MoleculeSectionHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MoleculeSectionFooter.self, viewModelClass: MoleculeSectionFooterModel.self)
// MARK:- Other Molecules
MoleculeObjectMapping.shared()?.register(viewClass: DoughnutChartView.self, viewModelClass: DoughnutChartModel.self)
// Navigation Molecules
try? ModelRegistry.register(NavigationItemModel.self)
try? ModelRegistry.register(NavigationImageButtonModel.self)
try? ModelRegistry.register(NavigationLabelButtonModel.self)
// MARK:- Other Organisms
MoleculeObjectMapping.shared()?.register(viewClass: Carousel.self, viewModelClass: CarouselModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BarsIndicatorView.self, viewModelClass: BarsCarouselIndicatorModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: NumericIndicatorView.self, viewModelClass: NumericCarouselIndicatorModel.self)
// MARK:- Designed List Items
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaret.self, viewModelClass: ListLeftVariableIconWithRightCaretModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretBodyText.self, viewModelClass: ListLeftVariableIconWithRightCaretBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconWithRightCaretAllTextLinks.self, viewModelClass: ListLeftVariableIconWithRightCaretAllTextLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxAllTextAndLinks.self, viewModelClass: ListLeftVariableCheckboxAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonAllTextAndLinks.self, viewModelClass: ListLeftVariableRadioButtonAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListBodyText.self, viewModelClass: ListLeftVariableNumberedListBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTextLinkAllTextAndLinks.self, viewModelClass: ListRightVariableTextLinkAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableButtonAllTextAndLinks.self, viewModelClass: ListRightVariableButtonAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeBodyText.self, viewModelClass: ListRightVariablePriceChangeBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePriceChangeAllTextAndLinks.self, viewModelClass: ListRightVariablePriceChangeAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableToggleAllTextAndLinks.self, viewModelClass: ListRightVariableToggleAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableRightCaretAllTextAndLinks.self, viewModelClass: ListRightVariableRightCaretAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnCompareChanges.self, viewModelClass: ListTwoColumnCompareChangesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDetails.self, viewModelClass: ListTwoColumnPriceDetailsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnPriceDescription.self, viewModelClass: ListTwoColumnPriceDescriptionModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnDropdownSelectors.self, viewModelClass: ListTwoColumnDropdownSelectorsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalData.self, viewModelClass: ListThreeColumnInternationalDataModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsage.self, viewModelClass: ListThreeColumnDataUsageModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillChanges.self, viewModelClass: ListThreeColumnBillChangesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillHistory.self, viewModelClass: ListThreeColumnBillHistoryModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnSpeedTest.self, viewModelClass: ListThreeColumnSpeedTestModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageListItem.self, viewModelClass: ListFourColumnDataUsageListItemModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListProgressBarThin.self, viewModelClass: ListProgressBarThinModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListStoreLocator.self, viewModelClass: ListStoreLocatorModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListStarRating.self, viewModelClass: ListStarRatingModel.self)
// MARK:- Designed Section Dividers
MoleculeObjectMapping.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnPlanDataDivider.self, viewModelClass: ListThreeColumnPlanDataDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerShort.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerShortModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnTextWithWhitespaceDividerTall.self, viewModelClass: ListOneColumnTextWithWhitespaceDividerTallModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListOneColumnFullWidthTextDividerSubsection.self, viewModelClass: ListOneColumnFullWidthTextDividerSubsectionModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListTwoColumnSubsectionDivider.self, viewModelClass: ListTwoColumnSubsectionDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnInternationalDataDivider.self, viewModelClass: ListThreeColumnInternationalDataDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnSpeedTestDivider.self, viewModelClass: ListThreeColumnSpeedTestDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillChangesDivider.self, viewModelClass: ListThreeColumnBillChangesDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnDataUsageDivider.self, viewModelClass: ListThreeColumnDataUsageDividerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListThreeColumnBillHistoryDivider.self, viewModelClass: ListThreeColumnBillHistoryDividerModel.self)
// MARK:- Designed Headers
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1Button.self, viewModelClass: HeadersH1ButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1LandingPageHeader.self, viewModelClass: HeadersH1LandingPageHeaderModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH1NoButtonsBodyText.self, viewModelClass: HeadersH1NoButtonsBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2NoButtonsBodyText.self, viewModelClass: HeadersH2NoButtonsBodyTextModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2TinyButton.self, viewModelClass: HeadersH2TinyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Buttons.self, viewModelClass: HeadersH2ButtonsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2PricingTwoRows.self, viewModelClass: HeadersH2PricingTwoRowsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2Link.self, viewModelClass: HeadersH2LinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: HeadersH2CaretLink.self, viewModelClass: HeadersH2CaretLinkModel.self)
// MARK:- Device Items
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonMedium.self, viewModelClass: ListDeviceComplexButtonMediumModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexButtonSmall.self, viewModelClass: ListDeviceComplexButtonSmallModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self)
// MARK:- LockUps
MoleculeObjectMapping.shared()?.register(viewClass: LockUpsPlanNames.self, viewModelClass: LockUpsPlanNamesModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: LockupsPlanSMLXL.self, viewModelClass: LockupsPlanSMLXLModel.self)
// MARK: - Top Notifications
MoleculeObjectMapping.shared()?.register(viewClass: NotificationView.self, viewModelClass: NotificationModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: CollapsableNotification.self, viewModelClass: CollapsableNotificationModel.self)
// MARK:- Helper models
try? ModelRegistry.register(RuleRequiredModel.self)
try? ModelRegistry.register(RuleAnyRequiredModel.self)
try? ModelRegistry.register(RuleAnyValueChangedModel.self)
try? ModelRegistry.register(RuleAllValueChangedModel.self)
try? ModelRegistry.register(RuleEqualsModel.self)
try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self)
try? ModelRegistry.register(RuleRegexModel.self)
// MARK:- Actions
try? ModelRegistry.register(ActionPopupModel.self)
try? ModelRegistry.register(ActionAlertModel.self)
try? ModelRegistry.register(ActionTopAlertModel.self)
try? ModelRegistry.register(ActionCollapseNotificationModel.self)
try? ModelRegistry.register(ActionOpenPanelModel.self)
try? ModelRegistry.register(ActionTopNotificationModel.self)
// MARK:- Behaviors
try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self)
}
/// Convenience function to get required modules for a give model
public static func getRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let model = model else { return nil }
return MoleculeObjectMapping.shared()?.getMoleculeClass(model)?.requiredModules(with: model, delegateObject, error: error)
}
/// Convenience function to add require modules for the given model to the passed in array.
public static func addRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, moduleList: inout [String]?, errorList: inout [MVMCoreErrorObject]?) {
guard let model = model else { return }
let error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>? = nil
if let modules = getRequiredModules(for: model, delegateObject, error: error) {
moduleList?.append(contentsOf: modules)
}
if let error = error?.pointee {
errorList?.append(error)
}
}
}

View File

@ -7,7 +7,7 @@
//
public class ListLeftVariableIconAllTextLinksModel: ListItemModel, MoleculeModelProtocol {
public class ListLeftVariableIconAllTextLinksModel: ListItemModel, MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -16,6 +16,10 @@ public class ListLeftVariableIconAllTextLinksModel: ListItemModel, MoleculeModel
public var image: ImageViewModel
public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel
public var children: [MoleculeModelProtocol] {
return [image, eyebrowHeadlineBodyLink]
}
//--------------------------------------------------
// MARK: - Method
//--------------------------------------------------

View File

@ -31,7 +31,7 @@ import Foundation
guard let model = model as? MoleculeSectionFooterModel else { return }
if molecule != nil {
molecule?.set(with: model.molecule, delegateObject, additionalData)
} else if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: additionalData) {
} else if let moleculeView = ModelRegistry.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: additionalData) {
addMolecule(moleculeView)
}
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)

View File

@ -42,7 +42,7 @@ import Foundation
guard let model = model as? MoleculeSectionHeaderModel else { return }
if molecule != nil {
molecule?.set(with: model.molecule, delegateObject, additionalData)
} else if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: additionalData) {
} else if let moleculeView = ModelRegistry.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: additionalData) {
addMolecule(moleculeView)
}
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)

View File

@ -9,7 +9,7 @@
import UIKit
public class TwoButtonViewModel: MoleculeModelProtocol {
public class TwoButtonViewModel: ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -19,6 +19,10 @@ public class TwoButtonViewModel: MoleculeModelProtocol {
public var primaryButton: ButtonModel?
public var secondaryButton: ButtonModel?
public var children: [MoleculeModelProtocol] {
return [primaryButton, secondaryButton].compactMap { $0 }
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------

View File

@ -16,7 +16,7 @@ open class MoleculeCollectionViewCell: CollectionViewCell {
guard let collectionModel = model as? MoleculeCollectionItemModel else { return }
if molecule == nil {
if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(collectionModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
if let moleculeView = ModelRegistry.createMolecule(collectionModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
addMolecule(moleculeView)
}
} else {

View File

@ -23,7 +23,7 @@ import UIKit
if molecule != nil {
molecule?.set(with: castModel.molecule, delegateObject, additionalData)
} else if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(castModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
} else if let moleculeView = ModelRegistry.createMolecule(castModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
addMolecule(moleculeView)
}
super.set(with: model, delegateObject, additionalData)

View File

@ -12,7 +12,7 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "tabsListItem"
var tabs: TabsModel
var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]
private enum CodingKeys: String, CodingKey {
case moleculeName
case tabs

View File

@ -167,7 +167,7 @@ import UIKit
if let moleculeModel = model.molecule {
if middleView != nil {
(middleView as? MoleculeViewProtocol)?.set(with: moleculeModel, delegateObject, additionalData)
} else if let molecule = MoleculeObjectMapping.shared()?.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
} else if let molecule = ModelRegistry.createMolecule(moleculeModel, delegateObject: delegateObject, additionalData: additionalData) {
addMiddleView(molecule)
}
}

View File

@ -15,6 +15,10 @@ open class BGVideoImageMoleculeModel: BGImageMoleculeModel {
public var video: VideoModel
public override var children: [MoleculeModelProtocol] {
return [video, molecule]
}
private enum CodingKeys: String, CodingKey {
case video
}

View File

@ -29,7 +29,7 @@ open class ModuleMolecule: Container {
}
if moduleMolecule == nil {
if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(moduleModel, delegateObject: delegateObject, additionalData: additionalData) {
if let moleculeView = ModelRegistry.createMolecule(moduleModel, delegateObject: delegateObject, additionalData: additionalData) {
addSubview(moleculeView)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values))
moduleMolecule = moleculeView
@ -50,7 +50,7 @@ open class ModuleMolecule: Container {
guard let moduleMolecule = model as? ModuleMoleculeModel,
let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName),
let classType = MoleculeObjectMapping.shared()?.getMoleculeClass(moduleModel),
let classType = ModelRegistry.getMoleculeClass(moduleModel),
let height = classType.estimatedHeight(with: moduleModel, delegateObject) else {
// Critical error
return 0
@ -61,7 +61,7 @@ open class ModuleMolecule: Container {
public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
guard let moduleMolecule = model as? ModuleMoleculeModel,
let moduleModel = delegateObject?.moleculeDelegate?.getModuleWithName(moduleMolecule.moduleName),
let classType = MoleculeObjectMapping.shared()?.getMoleculeClass(moduleModel),
let classType = ModelRegistry.getMoleculeClass(moduleModel),
let name = classType.nameForReuse(with: moduleModel, delegateObject) else {
// Critical error
return "moduleMolecule<>"

View File

@ -21,7 +21,7 @@ open class MoleculeContainer: Container {
if view != nil {
(view as? MoleculeViewProtocol)?.set(with: casteModel.molecule, delegateObject, additionalData)
} else {
if let molecule = MoleculeObjectMapping.shared()?.createMolecule(casteModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
if let molecule = ModelRegistry.createMolecule(casteModel.molecule, delegateObject: delegateObject, additionalData: additionalData) {
addMolecule(molecule)
}
}
@ -32,7 +32,7 @@ open class MoleculeContainer: Container {
public override static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
guard let containerModel = model as? MoleculeContainerModelProtocol,
let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(containerModel.molecule),
let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule),
let moleculeName = moleculeClass.nameForReuse(with: containerModel.molecule, delegateObject)
else { return "\(model.moleculeName)<>" }
@ -43,7 +43,7 @@ open class MoleculeContainer: Container {
guard let containerModel = model as? MoleculeContainerModelProtocol else { return 0 }
guard let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(containerModel.molecule),
guard let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule),
let moleculeHeight = moleculeClass.estimatedHeight(with: containerModel.molecule, delegateObject)
else { return (containerModel.topPadding ?? 0) + (containerModel.bottomPadding ?? 0) }
@ -53,7 +53,7 @@ open class MoleculeContainer: Container {
public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let containerModel = model as? MoleculeContainerModelProtocol,
let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(containerModel.molecule)
let moleculeClass = ModelRegistry.getMoleculeClass(containerModel.molecule)
else { return nil }
return moleculeClass.requiredModules(with: containerModel.molecule, delegateObject, error: error)

View File

@ -15,6 +15,10 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
public var backgroundColor: Color?
public var molecule: MoleculeModelProtocol
public var children: [MoleculeModelProtocol] {
return [molecule]
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case molecule
@ -40,7 +44,7 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
try super.init(from: decoder)
}
open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)

View File

@ -8,6 +8,14 @@
import Foundation
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol {
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol, ParentMoleculeModelProtocol {
var molecule: MoleculeModelProtocol { get set }
}
public extension MoleculeContainerModelProtocol {
var children: [MoleculeModelProtocol] {
return [molecule]
}
}

View File

@ -7,7 +7,7 @@
//
public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -20,6 +20,10 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
public var body: LabelModel?
public var link: LinkModel?
public var children: [MoleculeModelProtocol] {
[eyebrow, headline, body, link].compactMap { (molecule: MoleculeModelProtocol?) in molecule }
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
@ -68,7 +72,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline)
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
link = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .link)
setDefaults()
@ -83,7 +87,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
try container.encodeIfPresent(headline, forKey: .headline)
try container.encodeModelIfPresent(headline, forKey: .headline)
try container.encodeIfPresent(body, forKey: .body)
try container.encodeIfPresent(link, forKey: .link)
}

View File

@ -9,7 +9,7 @@
import Foundation
@objcMembers open class HeadlineBodyModel: MoleculeModelProtocol {
@objcMembers open class HeadlineBodyModel: ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -21,6 +21,10 @@ import Foundation
public var style: Style?
public var backgroundColor: Color?
public var children: [MoleculeModelProtocol] {
return [headline, body].compactMap { $0 }
}
//--------------------------------------------------
// MARK: - Enum
//--------------------------------------------------

View File

@ -19,7 +19,7 @@ open class StringAndMoleculeStack: MoleculeStackView {
for stackItemModel in molcules {
guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(stringAndMoleculeModel.molecule, delegateObject: delegateObject
let molecule = ModelRegistry.createMolecule(stringAndMoleculeModel.molecule, delegateObject: delegateObject
, additionalData: additionalData) else {
// Throw error
return

View File

@ -212,7 +212,7 @@ open class Carousel: View {
var pagingView: (UIView & CarouselPageControlProtocol)? = nil
if let molecule = molecule,
(!molecule.hidesForSinglePage || numberOfPages > 1) {
pagingView = MoleculeObjectMapping.shared()?.createMolecule(molecule, delegateObject: delegateObject) as? (UIView & CarouselPageControlProtocol)
pagingView = ModelRegistry.createMolecule(molecule, delegateObject: delegateObject) as? (UIView & CarouselPageControlProtocol)
}
addPaging(view: pagingView, position: molecule?.position ?? 20)
@ -234,7 +234,7 @@ open class Carousel: View {
/// Returns the (identifier, class) of the molecule for the given map.
func getMoleculeInfo(with molecule: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? {
guard let className = MoleculeObjectMapping.shared()?.getMoleculeClass(molecule) else { return nil }
guard let className = ModelRegistry.getMoleculeClass(molecule) else { return nil }
return (className.nameForReuse(with: molecule, delegateObject) ?? molecule.moleculeName, className, molecule)
}

View File

@ -9,7 +9,7 @@
import UIKit
@objcMembers public class CarouselModel: MoleculeModelProtocol, FormFieldProtocol {
@objcMembers public class CarouselModel: ParentMoleculeModelProtocol, FormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
@ -144,3 +144,11 @@ import UIKit
try container.encode(selectedIndex, forKey: .selectedIndex)
}
}
extension CarouselModel {
public var children: [MoleculeModelProtocol] {
return molecules
}
}

View File

@ -43,7 +43,7 @@ open class MoleculeStackView: Stack<StackModel> {
guard let stackItemModels = stackModel?.molecules else { return }
for model in stackItemModels {
if let stackItem = MoleculeObjectMapping.shared()?.createMolecule(model, delegateObject: delegateObject, additionalData: additionalData) as? MoleculeStackItem {
if let stackItem = ModelRegistry.createMolecule(model, delegateObject: delegateObject, additionalData: additionalData) as? MoleculeStackItem {
stackItems.append(stackItem)
}
}

View File

@ -199,7 +199,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
}
var name = "stack<"
for case let item in model.molecules {
if let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(item),
if let moleculeClass = ModelRegistry.getMoleculeClass(item),
let nameForReuse = moleculeClass.nameForReuse(with: item, delegateObject) {
name.append(nameForReuse + ",")
} else {
@ -218,7 +218,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
for case let item in model.molecules {
if item.gone { continue }
let height = (MoleculeObjectMapping.shared()?.getMoleculeClass(item))?.estimatedHeight(with: item, delegateObject) ?? 0
let height = (ModelRegistry.getMoleculeClass(item))?.estimatedHeight(with: item, delegateObject) ?? 0
if !horizontal {
// Vertical stack aggregates the items
let spacing = item.spacing ?? model.spacing
@ -237,7 +237,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
var modules: [String] = []
for case let item in model.molecules {
if let modulesForMolecule = (MoleculeObjectMapping.shared()?.getMoleculeClass(item))?.requiredModules(with: item, delegateObject, error: error) {
if let modulesForMolecule = (ModelRegistry.getMoleculeClass(item))?.requiredModules(with: item, delegateObject, error: error) {
modules += modulesForMolecule
}
}

View File

@ -7,7 +7,8 @@
//
@objcMembers public class StackModel: ContainerModel, StackModelProtocol, MoleculeModelProtocol {
@objcMembers public class StackModel: ContainerModel, StackModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -24,6 +25,10 @@
public var spacing: CGFloat = StackModel.defaultSpacing
public var useStackSpacingBeforeFirstItem = false
public var children: [MoleculeModelProtocol] {
return molecules
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
@ -77,4 +82,5 @@
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
}
}

View File

@ -8,9 +8,15 @@
import Foundation
public protocol StackModelProtocol {
public protocol StackModelProtocol: ParentMoleculeModelProtocol {
var molecules: [StackItemModelProtocol & MoleculeModelProtocol] { get set }
var axis: NSLayoutConstraint.Axis { get set }
var spacing: CGFloat { get set }
var useStackSpacingBeforeFirstItem: Bool { get set }
}
extension StackModelProtocol {
public var children: [MoleculeModelProtocol] { return molecules }
}

View File

@ -7,7 +7,7 @@ public enum MolecularError: Swift.Error {
}
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol {
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol {
var moleculeName: String { get }
var backgroundColor: Color? { get set }
}
@ -20,3 +20,69 @@ public extension MoleculeModelProtocol {
static var categoryCodingKey: String { "moleculeName" }
}
extension KeyedDecodingContainer where Key: CodingKey {
/// Decodes to a registered molecule based on the identifier
public func decodeMoleculeIfPresent<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> T? {
guard let model: MoleculeModelProtocol = try decodeModelIfPresent(codingKey: codingKey) else { return nil }
guard let modelT = model as? T else {
let message = "ModelRegistry Error wrong type: \(codingKey.stringValue)"
MVMCoreLoggingHandler.logDebugMessage(withDelegate: message)
throw ModelRegistry.Error.decoderOther(message: message)
}
return modelT
}
}
public extension MoleculeModelProtocol {
// Base case. No additional children to traverse.
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result {
return nextPartialResult(initialResult, self, depth)
}
// Base case. No additional children to traverse.
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
onVisit(depth, self)
}
}
public extension Array where Element == MoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result {
return reduce(initialResult) { (result, molecule) -> Result in
return molecule.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: result, nextPartialResult: nextPartialResult)
}
}
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
forEach { (molecule) in
molecule.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit)
}
}
}
// Would prefer these to be defined in MoleculeTreeTraversalProtocol that MoleculeModelProtocol inherits.
public extension Array where Element == MoleculeModelProtocol {
func countMolecules() -> Int {
return reduce(0) { (accumulator, molecule) in
return accumulator + molecule.countMolecules()
}
}
func printMolecules() {
forEach { (molecule) in
molecule.printMolecules()
}
}
func allMoleculesOfType<T>() -> [T] {
return reduce([]) { (accumulator, molecule) in
return accumulator + molecule.allMoleculesOfType()
}
}
}

View File

@ -0,0 +1,55 @@
//
// ParentModelProtocol.swift
// MVMCoreUI
//
// Created by Kyle on 3/19/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol {
var children: [MoleculeModelProtocol] { get }
}
public extension ParentMoleculeModelProtocol {
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result {
var result = initialResult
if (options == .parentFirst) {
result = nextPartialResult(result, self, depth)
}
result = children.reduce(result) { (result, molecule) -> Result in
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
return additionalParent.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
}
return molecule.reduceDepthFirstTraverse(options: options, depth: depth + 1, initialResult: result, nextPartialResult: nextPartialResult)
}
if (options == .childFirst) {
result = nextPartialResult(result, self, depth)
}
// if options == .leafOnly don't call on self.
return result
}
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) {
if (options == .parentFirst) {
onVisit(depth, self)
}
children.forEach { (molecule) in
if let additionalParent = molecule as? ParentMoleculeModelProtocol {
// Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol.
additionalParent.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit)
} else {
molecule.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit)
}
}
if (options == .childFirst) {
onVisit(depth, self)
}
// if options == .leafOnly don't call on self.
}
}

View File

@ -9,8 +9,9 @@
import Foundation
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol {
public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, MoleculeTreeTraversalProtocol {
var template: String { get }
var rootMolecules: [MoleculeModelProtocol] { get }
}
public extension TemplateModelProtocol {
@ -26,4 +27,12 @@ public extension TemplateModelProtocol {
static var categoryName: String {
return "\(TemplateModelProtocol.self)"
}
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int) -> Result) -> Result {
return rootMolecules.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: initialResult, nextPartialResult: nextPartialResult)
}
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol) -> Void) {
return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit)
}
}

View File

@ -0,0 +1,54 @@
//
// TreeTraversalProtocol.swift
// MVMCoreUI
//
// Created by Kyle on 3/19/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
public enum TreeTraversalOptions {
case parentFirst
case childFirst
case leafNodesOnly
}
public protocol MoleculeTreeTraversalProtocol {
// Future options -- Parent first depth first, leaves only.
func reduceDepthFirstTraverse<Result>(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result
func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void)
//func breadthFirstTraverse()
}
//
// Helper Extensions
//
extension MoleculeTreeTraversalProtocol {
func countMolecules(options: TreeTraversalOptions = .parentFirst) -> Int {
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: 0) { (accumulator, molecule, depth) in
return accumulator + 1
}
}
func printMolecules(options: TreeTraversalOptions = .parentFirst) {
depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in
print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]")
}
}
func allMoleculesOfType<T>(options: TreeTraversalOptions = .parentFirst) -> [T] {
return reduceDepthFirstTraverse(options: options, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
if let typedMolecule = molecule as? T {
return accumulator + [typedMolecule]
}
return accumulator
}
}
}

View File

@ -61,3 +61,44 @@ extension MoleculeViewProtocol {
}
}
}
// Convenience Functions
public extension ModelRegistry {
/// Returns the type of molecule view for the given model
static func getMoleculeClass(_ model: MoleculeModelProtocol) -> MoleculeViewProtocol.Type? {
do {
let type = try ModelRegistry.getHandler(model) as! MoleculeViewProtocol.Type
return type
} catch {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
}
return nil
}
}
/// Creates a molecule with the given model.
static func createMolecule(_ model: MoleculeModelProtocol, delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> MoleculeViewProtocol? {
guard let type = getMoleculeClass(model) else { return nil }
return type.init(model: model, delegateObject, additionalData)
}
// TODO: move below to KyleTraverse (tm)
/// Convenience function to get required modules for a give model
static func getRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let model = model else { return nil }
return ModelRegistry.getMoleculeClass(model)?.requiredModules(with: model, delegateObject, error: error)
}
/// Convenience function to add require modules for the given model to the passed in array.
static func addRequiredModules(for model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, moduleList: inout [String]?, errorList: inout [MVMCoreErrorObject]?) {
guard let model = model else { return }
let error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>? = nil
if let modules = getRequiredModules(for: model, delegateObject, error: error) {
moduleList?.append(contentsOf: modules)
}
if let error = error?.pointee {
errorList?.append(error)
}
}
}

View File

@ -22,12 +22,29 @@ public extension TemplateProtocol where Self: ViewController {
let data = try JSONSerialization.data(withJSONObject: pageJSON)
let decoder = JSONDecoder()
try decoder.add(delegateObject: delegateObjectIVar)
self.templateModel = try decodeTemplate(using: decoder, from: data)
self.model = templateModel as? MVMControllerModelProtocol
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)
}
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
return 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

@ -44,7 +44,7 @@ import Foundation
open override func viewForTop() -> UIView? {
guard let headerModel = templateModel?.header,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(headerModel, delegateObject: delegateObjectIVar)
else { return super.viewForTop() }
// Temporary, Default the horizontal padding
@ -57,7 +57,7 @@ import Foundation
override open func viewForBottom() -> UIView? {
guard let footerModel = templateModel?.footer,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(footerModel, delegateObject: delegateObjectIVar)
else { return super.viewForBottom() }
return molecule
@ -146,7 +146,7 @@ import Foundation
/// Returns the (identifier, class) of the molecule for the given map.
open func getMoleculeInfo(with item: (CollectionItemModelProtocol & MoleculeModelProtocol)?) -> (identifier: String, class: AnyClass, molecule: CollectionItemModelProtocol & MoleculeModelProtocol)? {
guard let item = item,
let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(item) else { return nil }
let moleculeClass = ModelRegistry.getMoleculeClass(item) else { return nil }
let moleculeName = moleculeClass.nameForReuse(with: item, delegateObjectIVar) ?? item.moleculeName
return (moleculeName, moleculeClass, item)
}
@ -183,12 +183,12 @@ import Foundation
open func requiredModules() -> [Any]? {
var modules: [String]? = []
var errors: [MVMCoreErrorObject]? = nil
MoleculeObjectMapping.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
MoleculeObjectMapping.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
if let molecules = templateModel?.molecules {
for molecule in molecules {
MoleculeObjectMapping.addRequiredModules(for: molecule, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: molecule, delegateObjectIVar, moduleList: &modules, errorList: &errors)
}
}

View File

@ -18,6 +18,13 @@ import Foundation
}
public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]?
public var columns: Int?
public override var rootMolecules: [MoleculeModelProtocol] {
if let molecules = molecules {
return super.rootMolecules + molecules
}
return super.rootMolecules
}
//--------------------------------------------------
// MARK: - Initializer

View File

@ -20,6 +20,13 @@ import Foundation
public var line: LineModel?
public var scrollToRowIndex: Int?
public override var rootMolecules: [MoleculeModelProtocol] {
if let molecules = molecules {
return super.rootMolecules + molecules
}
return super.rootMolecules
}
/// This template requires content.
func validateModelHasContent() throws {
if header == nil,

View File

@ -54,7 +54,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
open override func viewForTop() -> UIView {
guard let headerModel = templateModel?.header,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(headerModel, delegateObject: delegateObjectIVar)
else { return super.viewForTop() }
// Temporary, Default the horizontal padding
@ -67,7 +67,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
override open func viewForBottom() -> UIView {
guard let footerModel = templateModel?.footer,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(footerModel, delegateObject: delegateObjectIVar)
else { return super.viewForBottom() }
return molecule
@ -222,7 +222,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
func createMoleculeInfo(with listItem: MoleculeModelProtocol?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? {
guard let listItem = listItem,
let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(listItem)
let moleculeClass = ModelRegistry.getMoleculeClass(listItem)
else { return nil }
let moleculeName = moleculeClass.nameForReuse(with: listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName
@ -267,12 +267,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
open func requiredModules() -> [Any]? {
var modules: [String]? = []
var errors: [MVMCoreErrorObject]? = nil
MoleculeObjectMapping.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
MoleculeObjectMapping.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
if let molecules = templateModel?.molecules {
for molecule in molecules {
MoleculeObjectMapping.addRequiredModules(for: molecule, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: molecule, delegateObjectIVar, moduleList: &modules, errorList: &errors)
}
}

View File

@ -57,7 +57,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
open override func viewForTop() -> UIView? {
guard let headerModel = templateModel?.header,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(headerModel, delegateObject: delegateObjectIVar)
else { return nil }
return molecule
@ -82,7 +82,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
override open func viewForBottom() -> UIView? {
guard let footerModel = templateModel?.footer,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(footerModel, delegateObject: delegateObjectIVar)
else { return nil }
return molecule
@ -103,9 +103,9 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
open func requiredModules() -> [Any]? {
var modules: [String]? = []
var errors: [MVMCoreErrorObject]? = nil
MoleculeObjectMapping.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
MoleculeObjectMapping.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
MoleculeObjectMapping.addRequiredModules(for: templateModel?.moleculeStack, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.header, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.footer, delegateObjectIVar, moduleList: &modules, errorList: &errors)
ModelRegistry.addRequiredModules(for: templateModel?.moleculeStack, delegateObjectIVar, moduleList: &modules, errorList: &errors)
return modules
}
}

View File

@ -15,6 +15,10 @@ import Foundation
}
public var moleculeStack: StackModel
public override var rootMolecules: [MoleculeModelProtocol] {
return [header, moleculeStack, footer].compactMap { $0 }
}
public init(pageType: String, moleculeStack: StackModel) {
self.moleculeStack = moleculeStack
super.init(pageType: pageType)

View File

@ -29,7 +29,8 @@ import Foundation
public var screenHeading: String?
public var navigationBar: (NavigationItemModelProtocol & MoleculeModelProtocol)?
public var formRules: [FormGroupRule]?
public var behaviors: [PageBehaviorProtocol]?
public var behaviors: [PageBehaviorModelProtocol]?
public var rootMolecules: [MoleculeModelProtocol] { [] }
public var tabBarHidden: Bool = false
public var tabBarIndex: Int?

View File

@ -9,11 +9,16 @@
import Foundation
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
public var anchorHeader: Bool = false
public var header: MoleculeModelProtocol?
public var anchorFooter: Bool = false
public var footer: MoleculeModelProtocol?
public override var rootMolecules: [MoleculeModelProtocol] {
return [header, footer].compactMap { $0 }
}
public override init(pageType: String) {
super.init(pageType: pageType)
}

View File

@ -14,6 +14,13 @@ import Foundation
}
public var middle: MoleculeModelProtocol?
public override var rootMolecules: [MoleculeModelProtocol] {
if let middle = middle {
return super.rootMolecules + [middle]
}
return super.rootMolecules
}
public init(pageType: String, header: MoleculeModelProtocol?, middle: MoleculeModelProtocol?, footer: MoleculeModelProtocol?) {
super.init(pageType: pageType)
self.header = header

View File

@ -24,7 +24,7 @@ import UIKit
open override func viewForTop() -> UIView? {
guard let headerModel = templateModel?.header,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(headerModel, delegateObject: delegateObjectIVar)
else { return nil }
return molecule
@ -32,7 +32,7 @@ import UIKit
open override func viewForMiddle() -> UIView? {
guard let middleModel = templateModel?.middle,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(middleModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(middleModel, delegateObject: delegateObjectIVar)
else { return nil }
return molecule
@ -40,7 +40,7 @@ import UIKit
override open func viewForBottom() -> UIView? {
guard let footerModel = templateModel?.footer,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar)
let molecule = ModelRegistry.createMolecule(footerModel, delegateObject: delegateObjectIVar)
else { return nil }
return molecule

View File

@ -9,6 +9,6 @@
import Foundation
public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorsTemplateProtocol {
public protocol MVMControllerModelProtocol: TemplateModelProtocol, FormHolderModelProtocol, PageBehaviorHandlerModelProtocol {
}

View File

@ -74,8 +74,8 @@ open class ScrollingViewController: ViewController {
}
open func scrollViewDidScroll(_ scrollView: UIScrollView) {
executeBehaviors { (behavior: PageScrolledBehavior) in
behavior.pageScrolled(scrollView: scrollView)
executeBehaviors { [weak self] (behavior: PageScrolledBehavior) in
behavior.pageScrolled(scrollView: scrollView, self?.delegateObjectIVar)
}
}

View File

@ -8,7 +8,7 @@
import UIKit
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol {
@objc open class ViewController: UIViewController, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MoleculeDelegateProtocol, FormHolderProtocol, MVMCoreActionDelegateProtocol, MVMCoreLoadDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, ObservingTextFieldDelegate, MVMCoreUIDetailViewProtocol, PageProtocol, PageBehaviorHandlerProtocol {
//--------------------------------------------------
// MARK: - Properties
@ -34,6 +34,8 @@ import UIKit
public var formValidator: FormValidator?
public var behaviors: [PageBehaviorProtocol]?
public var needsUpdateUI = false
private var observingForResponses = false
private var initialLoadFinished = false
@ -380,16 +382,16 @@ import UIKit
pageShown()
}
executeBehaviors { (behavior: PageVisibilityBehavior) in
behavior.onPageShown()
executeBehaviors { [weak self] (behavior: PageVisibilityBehavior) in
behavior.onPageShown(self?.delegateObjectIVar)
}
}
open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
executeBehaviors { (behavior: PageVisibilityBehavior) in
behavior.onPageHidden()
executeBehaviors { [weak self] (behavior: PageVisibilityBehavior) in
behavior.onPageHidden(self?.delegateObjectIVar)
}
}
@ -620,6 +622,6 @@ import UIKit
//--------------------------------------------------
func executeBehaviors<T>(_ behaviorBlock:(_ behavior:T)->Void) {
model?.behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
}
}

View File

@ -0,0 +1,56 @@
//
// GetContactBehavior.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/22/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
import Contacts
public protocol PageGetContactBehaviorConsumerProtocol {
func getMatchParameters() -> (NSPredicate, [CNKeyDescriptor])?
func consume(contacts: [CNContact])
}
public class PageGetContactBehaviorModel: PageBehaviorModelProtocol {
public class var identifier: String { "pageGetContactBehavior" }
public var shouldAllowMultipleInstances: Bool { false }
public init() {}
}
public class PageGetContactBehavior: PageVisibilityBehavior {
var delegate: MVMCoreUIDelegateObject?
public required init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
self.delegate = delegateObject
}
public func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) {
// Ask for permission
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 }
// Iterate models and provide contact
let store = CNContactStore()
let consumers: [PageGetContactBehaviorConsumerProtocol] = model.allMoleculesOfType()
for consumer in consumers {
guard let parameters = consumer.getMatchParameters(),
let contacts = try? store.unifiedContacts(matching: parameters.0, keysToFetch: parameters.1) else { return }
consumer.consume(contacts: contacts)
}
// Tell template to update
MVMCoreDispatchUtility.performBlock(onMainThread: {
// TODO: move to protocol function instead
(self?.delegate?.moleculeDelegate as? ViewController)?.handleNewData()
})
}
}
public func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?) {}
}

View File

@ -1,63 +0,0 @@
//
// PageBehaviors.swift
// MVMCoreUI
//
// Created by Kyle on 5/8/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol PageBehaviorProtocol: ModelProtocol {
/// The type of rule
var behaviorName: String { get }
}
public extension PageBehaviorProtocol {
var behaviorName: String {
get { Self.identifier }
}
static var categoryCodingKey: String {
"behaviorName"
}
static var categoryName: String {
"\(PageBehaviorProtocol.self)"
}
}
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
func onPageShown()
func onPageHidden()
}
public protocol PageScrolledBehavior: PageBehaviorProtocol {
func pageScrolled(scrollView: UIScrollView)
}
public protocol PageBehaviorsTemplateProtocol {
var behaviors: [PageBehaviorProtocol]? { get set }
}
public extension PageBehaviorsTemplateProtocol {
mutating func add(behavior: PageBehaviorProtocol) {
var newBehaviors = behaviors ?? []
newBehaviors.append(behavior)
self.behaviors = newBehaviors
}
}
public extension MVMCoreUIDelegateObject {
weak var behaviorTemplateDelegate: (PageBehaviorsTemplateProtocol & NSObjectProtocol)? {
get {
return (moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorsTemplateProtocol & NSObjectProtocol)
}
}
}

View File

@ -0,0 +1,25 @@
//
// PageBehaviorHandlerModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
public protocol PageBehaviorHandlerModelProtocol {
var behaviors: [PageBehaviorModelProtocol]? { get set }
}
public extension PageBehaviorHandlerModelProtocol {
/// Adds the behavior model to the behaviors if possible.
mutating func add(behavior: PageBehaviorModelProtocol) {
var newBehaviors = behaviors ?? []
guard !behavior.shouldAllowMultipleInstances,
!newBehaviors.contains(where: { $0.behaviorName == behavior.behaviorName
}) else { return }
newBehaviors.append(behavior)
self.behaviors = newBehaviors
}
}

View File

@ -0,0 +1,36 @@
//
// PageBehaviorHandlerProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol PageBehaviorHandlerProtocol {
var behaviors: [PageBehaviorProtocol]? { get set }
}
public extension PageBehaviorHandlerProtocol {
/// Creates the behaviors and sets the variable.
mutating func createBehaviors(for model: PageBehaviorHandlerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
guard let behaviorModels = model.behaviors else {
behaviors = nil
return
}
var behaviors: [PageBehaviorProtocol] = []
for behaviorModel in behaviorModels {
do {
let handlerType = try ModelRegistry.getHandler(behaviorModel) as! PageBehaviorProtocol.Type
let behavior = handlerType.init(model: behaviorModel, delegateObject: delegateObject)
behaviors.append(behavior)
} catch {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.shared()?.addError(toLog: errorObject)
}
}
}
self.behaviors = behaviors.count > 0 ? behaviors : nil
}
}

View File

@ -0,0 +1,35 @@
//
// PageBehaviorModelProtocol.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
public protocol PageBehaviorModelProtocol: ModelProtocol {
/// The type of rule
var behaviorName: String { get }
/// If the behavior should allow multiple instances
var shouldAllowMultipleInstances: Bool { get }
}
public extension PageBehaviorModelProtocol {
var behaviorName: String {
get { type(of:self).identifier }
}
static var shouldAllowMultipleInstances: Bool {
get { true }
}
static var categoryCodingKey: String {
"behaviorName"
}
static var categoryName: String {
"\(PageBehaviorModelProtocol.self)"
}
}

View File

@ -0,0 +1,34 @@
//
// PageBehaviorProtocol.swift
// MVMCoreUI
//
// Created by Kyle on 5/8/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public protocol PageBehaviorProtocol: ModelHandlerProtocol {
/// Initializes the behavior with the model
init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?)
}
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?)
func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?)
}
public protocol PageScrolledBehavior: PageBehaviorProtocol {
func pageScrolled(scrollView: UIScrollView,_ delegateObject: MVMCoreUIDelegateObject?)
}
public extension MVMCoreUIDelegateObject {
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
get {
return (moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
}
}
}

View File

@ -0,0 +1,11 @@
//
// PageBehaviorProtocolRequirer.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/29/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
public protocol PageBehaviorProtocolRequirer {
func getRequiredBehaviors() -> [PageBehaviorModelProtocol]
}

View File

@ -1,33 +0,0 @@
//
// PageScrolledClosureBehavior.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 2/11/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
public class PageScrolledClosureBehavior: PageScrolledBehavior {
public static var identifier = "pageScrolledClosureBehavior"
public var pageScrolledHandler: (_ scrollView: UIScrollView) -> Void
public init(with onPageScrolledHandler: @escaping (_ scrollView: UIScrollView) -> Void) {
self.pageScrolledHandler = onPageScrolledHandler
}
// This class is not meant to be decoded and encoded really.
public required init(from decoder: Decoder) throws {
throw ModelRegistry.Error.decoderOther(message: "PageScrolledClosureBehavior does not decode.")
}
public func encode(to encoder: Encoder) throws {
throw ModelRegistry.Error.decoderOther(message: "PageScrolledClosureBehavior does not encode.")
}
public func pageScrolled(scrollView: UIScrollView) {
pageScrolledHandler(scrollView)
}
}

View File

@ -1,40 +0,0 @@
//
// PageVisibilityClosureBehavior.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 2/11/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
public class PageVisibilityClosureBehavior: PageVisibilityBehavior {
public static var identifier = "pageVisibilityClosureBehavior"
public var pageShownHandler: () -> Void
public var pageHiddenHandler: () -> Void
public init(with onPageShownHandler: @escaping () -> Void, onPageHiddenHandler: @escaping () -> Void) {
self.pageShownHandler = onPageShownHandler
self.pageHiddenHandler = onPageHiddenHandler
}
// This class is not meant to be decoded and encoded really.
public required init(from decoder: Decoder) throws {
throw ModelRegistry.Error.decoderOther(message: "PageVisibilityClosureBehavior does not decode.")
}
public func encode(to encoder: Encoder) throws {
throw ModelRegistry.Error.decoderOther(message: "PageVisibilityClosureBehavior does not encode.")
}
//MARK:- PageVisibilityBehavior
public func onPageShown() {
pageShownHandler()
}
public func onPageHidden() {
pageHiddenHandler()
}
}

View File

@ -6,52 +6,14 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior {
public class ScreenBrightnessModifierBehaviorModel: PageBehaviorModelProtocol {
public var shouldAllowMultipleInstances: Bool = false
public static var identifier = "screenBrightnessModifier"
@Clamping(range: 0...1) var screenBrightness: CGFloat
var originalScreenBrightness: CGFloat?
//MARK:- PageVisibilityBehavior
public func onPageShown() {
changeScreenBrightness()
}
public func onPageHidden() {
restoreScreenBrightness()
}
//MARK:- Behavior
func changeScreenBrightness() {
guard originalScreenBrightness == nil else { return }
originalScreenBrightness = UIScreen.main.brightness
UIScreen.main.brightness = screenBrightness
NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
}
func restoreScreenBrightness() {
guard let originalScreenBrightness = originalScreenBrightness else { return }
UIScreen.main.brightness = originalScreenBrightness
self.originalScreenBrightness = nil
NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
}
@objc func willResignActive() {
restoreScreenBrightness()
NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
}
@objc func didBecomeActive() {
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
changeScreenBrightness()
}
//MARK:- Codable
private enum CodingKeys: String, CodingKey {
case screenBrightness
}
@ -66,3 +28,49 @@ public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior {
try container.encode(screenBrightness, forKey: .screenBrightness)
}
}
public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior {
var model: PageBehaviorModelProtocol
required public init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
self.model = model
}
//MARK:- PageVisibilityBehavior
public func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?) {
changeScreenBrightness()
}
public func onPageHidden(_ delegateObject: MVMCoreUIDelegateObject?) {
restoreScreenBrightness()
}
//MARK:- Behavior
func changeScreenBrightness() {
guard let model = model as? ScreenBrightnessModifierBehaviorModel,
model.originalScreenBrightness == nil else { return }
model.originalScreenBrightness = UIScreen.main.brightness
UIScreen.main.brightness = model.screenBrightness
NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
}
func restoreScreenBrightness() {
guard let model = model as? ScreenBrightnessModifierBehaviorModel,
let originalScreenBrightness = model.originalScreenBrightness else { return }
UIScreen.main.brightness = originalScreenBrightness
model.originalScreenBrightness = nil
NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
}
@objc func willResignActive() {
restoreScreenBrightness()
NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
}
@objc func didBecomeActive() {
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
changeScreenBrightness()
}
}

View File

@ -99,7 +99,7 @@ import UIKit
/// Convenience function for setting the navigation titleView.
public static func setNavigationTitleView(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) {
let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
if let titleViewModel = navigationItemModel?.titleView, let molecule = MoleculeObjectMapping.shared()?.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) {
if let titleViewModel = navigationItemModel?.titleView, let molecule = ModelRegistry.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) {
viewController.navigationItem.titleView = molecule
}
}

View File

@ -0,0 +1,248 @@
//
// ModelMapping.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/31/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import MVMCore
open class CoreUIModelMapping: ModelMapping {
open override class func registerObjects() {
super.registerObjects()
registerMolecules()
registerRules()
registerActions()
registerBehaviors()
registerLabelAttributes()
}
open class func registerMolecules() {
// MARK:- Stacks
try? ModelRegistry.register(handler: MoleculeStackView.self, for: StackModel.self)
try? ModelRegistry.register(handler: UnOrderedList.self, for: UnOrderedListModel.self)
try? ModelRegistry.register(handler: NumberedList.self, for: NumberedListModel.self)
// MARK:- Label
try? ModelRegistry.register(handler: Label.self, for: LabelModel.self)
// MARK:- TextView
try? ModelRegistry.register(handler: TextViewEntryField.self, for: TextViewEntryFieldModel.self)
// MARK:- Buttons
try? ModelRegistry.register(handler: PillButton.self, for: ButtonModel.self)
try? ModelRegistry.register(handler: TwoButtonView.self, for: TwoButtonViewModel.self)
try? ModelRegistry.register(handler: ExternalLink.self, for: ExternalLinkModel.self)
try? ModelRegistry.register(handler: Link.self, for: LinkModel.self)
try? ModelRegistry.register(handler: CaretLink.self, for: CaretLinkModel.self)
// MARK:- Entry Field
try? ModelRegistry.register(handler: TextEntryField.self, for: TextEntryFieldModel.self)
try? ModelRegistry.register(handler: MdnEntryField.self, for: MdnEntryFieldModel.self)
try? ModelRegistry.register(handler: DigitEntryField.self, for: DigitEntryFieldModel.self)
try? ModelRegistry.register(handler: ItemDropdownEntryField.self, for: ItemDropdownEntryFieldModel.self)
try? ModelRegistry.register(handler: DateDropdownEntryField.self, for: DateDropdownEntryFieldModel.self)
try? ModelRegistry.register(handler: MultiItemDropdownEntryField.self, for: MultiItemDropdownEntryFieldModel.self)
// MARK:- Selectors
try? ModelRegistry.register(handler: RadioButton.self, for: RadioButtonModel.self)
try? ModelRegistry.register(handler: RadioBoxes.self, for: RadioBoxesModel.self)
try? ModelRegistry.register(handler: Checkbox.self, for: CheckboxModel.self)
try? ModelRegistry.register(handler: RadioSwatches.self, for: RadioSwatchesModel.self)
try? ModelRegistry.register(handler: Tags.self, for: TagsModel.self)
try? ModelRegistry.register(handler: Tag.self, for: TagModel.self)
try? ModelRegistry.register(handler: Heart.self, for: HeartModel.self)
try? ModelRegistry.register(handler: Stars.self, for: StarsModel.self)
try? ModelRegistry.register(handler: Star.self, for: StarModel.self)
// MARK:- Other Atoms
try? ModelRegistry.register(handler: ProgressBar.self, for: ProgressBarModel.self)
try? ModelRegistry.register(handler: MultiProgress.self, for: MultiProgressBarModel.self)
try? ModelRegistry.register(handler: CaretView.self, for: CaretViewModel.self)
try? ModelRegistry.register(handler: DashLine.self, for: DashLineModel.self)
try? ModelRegistry.register(handler: LoadImageView.self, for: ImageViewModel.self)
try? ModelRegistry.register(handler: Line.self, for: LineModel.self)
try? ModelRegistry.register(handler: Wheel.self, for: WheelModel.self)
try? ModelRegistry.register(handler: Toggle.self, for: ToggleModel.self)
try? ModelRegistry.register(handler: CheckboxLabel.self, for: CheckboxLabelModel.self)
try? ModelRegistry.register(handler: Arrow.self, for: ArrowModel.self)
try? ModelRegistry.register(handler: RadioButtonLabel.self, for: RadioButtonLabelModel.self)
try? ModelRegistry.register(handler: WebView.self, for: WebViewModel.self)
try? ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self)
try? ModelRegistry.register(handler: Video.self, for: VideoModel.self)
// MARK:- Horizontal Combination Molecules
try? ModelRegistry.register(handler: StringAndMoleculeView.self, for: StringAndMoleculeModel.self)
try? ModelRegistry.register(handler: ImageHeadlineBody.self, for: ImageHeadlineBodyModel.self)
try? ModelRegistry.register(handler: Tabs.self, for: TabsModel.self)
try? ModelRegistry.register(handler: TwoLinkView.self, for: TwoLinkViewModel.self)
// MARK:- Vertical Combination Molecules
try? ModelRegistry.register(handler: HeadlineBody.self, for: HeadlineBodyModel.self)
try? ModelRegistry.register(handler: HeadLineBodyCaretLinkImage.self, for: HeadlineBodyCaretLinkImageModel.self)
try? ModelRegistry.register(handler: EyebrowHeadlineBodyLink.self, for: EyebrowHeadlineBodyLinkModel.self)
try? ModelRegistry.register(handler: HeadlineBodyLink.self, for: HeadlineBodyLinkModel.self)
try? ModelRegistry.register(handler: HeadlineBodyButton.self, for: HeadlineBodyButtonModel.self)
try? ModelRegistry.register(handler: BGImageHeadlineBodyButton.self, for: BGImageHeadlineBodyButtonModel.self)
try? ModelRegistry.register(handler: ThreeHeadlineBodyLink.self, for: ThreeHeadlineBodyLinkModel.self)
// MARK:- Left Right Molecules
try? ModelRegistry.register(handler: CornerLabels.self, for: CornerLabelsModel.self)
try? ModelRegistry.register(handler: LeftRightLabelView.self, for: LeftRightLabelModel.self)
try? ModelRegistry.register(handler: LabelToggle.self, for: LabelToggleModel.self)
try? ModelRegistry.register(handler: HeadlineBodyToggle.self, for: HeadlineBodyToggleModel.self)
try? ModelRegistry.register(handler: HeadlineBodyLinkToggle.self, for: HeadlineBodyLinkToggleModel.self)
try? ModelRegistry.register(handler: ActionDetailWithImage.self, for: ActionDetailWithImageModel.self)
// MARK:- List items
try? ModelRegistry.register(handler: MoleculeTableViewCell.self, for: MoleculeListItemModel.self)
try? ModelRegistry.register(handler: DropDownFilterTableViewCell.self, for: DropDownListItemModel.self)
try? ModelRegistry.register(handler: AccordionMoleculeTableViewCell.self, for: AccordionListItemModel.self)
try? ModelRegistry.register(handler: TabsTableViewCell.self, for: TabsListItemModel.self)
try? ModelRegistry.register(handler: ListProgressBarData.self, for: ListProgressBarDataModel.self)
// MARK:- Other Items
try? ModelRegistry.register(handler: MoleculeStackItem.self, for: MoleculeStackItemModel.self)
try? ModelRegistry.register(handler: StackItem.self, for: StackItemModel.self)
try? ModelRegistry.register(handler: MoleculeCollectionViewCell.self, for: MoleculeCollectionItemModel.self)
try? ModelRegistry.register(handler: CarouselItem.self, for: CarouselItemModel.self)
// MARK:- Other Container Molecules
try? ModelRegistry.register(handler: MoleculeContainer.self, for: MoleculeContainerModel.self)
try? ModelRegistry.register(handler: MoleculeHeaderView.self, for: MoleculeHeaderModel.self)
try? ModelRegistry.register(handler: FooterView.self, for: FooterModel.self)
try? ModelRegistry.register(handler: Scroller.self, for: ScrollerModel.self)
try? ModelRegistry.register(handler: ModuleMolecule.self, for: ModuleMoleculeModel.self)
try? ModelRegistry.register(handler: BGImageMolecule.self, for: BGImageMoleculeModel.self)
try? ModelRegistry.register(handler: BGVideoImageMolecule.self, for: BGVideoImageMoleculeModel.self)
try? ModelRegistry.register(handler: MoleculeSectionHeader.self, for: MoleculeSectionHeaderModel.self)
try? ModelRegistry.register(handler: MoleculeSectionFooter.self, for: MoleculeSectionFooterModel.self)
// MARK:- Other Molecules
try? ModelRegistry.register(handler: DoughnutChartView.self, for: DoughnutChartModel.self)
// Navigation Molecules
try? ModelRegistry.register(NavigationItemModel.self)
try? ModelRegistry.register(NavigationImageButtonModel.self)
try? ModelRegistry.register(NavigationLabelButtonModel.self)
// MARK:- Other Organisms
try? ModelRegistry.register(handler: Carousel.self, for: CarouselModel.self)
try? ModelRegistry.register(handler: BarsIndicatorView.self, for: BarsCarouselIndicatorModel.self)
try? ModelRegistry.register(handler: NumericIndicatorView.self, for: NumericCarouselIndicatorModel.self)
// MARK:- Designed List Items
try? ModelRegistry.register(handler: ListLeftVariableIconWithRightCaret.self, for: ListLeftVariableIconWithRightCaretModel.self)
try? ModelRegistry.register(handler: ListLeftVariableIconWithRightCaretBodyText.self, for: ListLeftVariableIconWithRightCaretBodyTextModel.self)
try? ModelRegistry.register(handler: ListLeftVariableIconWithRightCaretAllTextLinks.self, for: ListLeftVariableIconWithRightCaretAllTextLinksModel.self)
try? ModelRegistry.register(handler: ListLeftVariableCheckboxAllTextAndLinks.self, for: ListLeftVariableCheckboxAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListLeftVariableRadioButtonAndPaymentMethod.self, for: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
try? ModelRegistry.register(handler: ListLeftVariableRadioButtonBodyText.self, for: ListLeftVariableRadioButtonBodyTextModel.self)
try? ModelRegistry.register(handler: ListLeftVariableRadioButtonAllTextAndLinks.self, for: ListLeftVariableRadioButtonAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListLeftVariableCheckboxBodyText.self, for: ListLeftVariableCheckboxBodyTextModel.self)
try? ModelRegistry.register(handler: ListLeftVariableIconAllTextLinks.self, for: ListLeftVariableIconAllTextLinksModel.self)
try? ModelRegistry.register(handler: ListLeftVariableNumberedListAllTextAndLinks.self, for: ListLeftVariableNumberedListAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListLeftVariableNumberedListBodyText.self, for: ListLeftVariableNumberedListBodyTextModel.self)
try? ModelRegistry.register(handler: ListRVWheel.self, for: ListRVWheelModel.self)
try? ModelRegistry.register(handler: ListRightVariablePayments.self, for: ListRightVariablePaymentsModel.self)
try? ModelRegistry.register(handler: ListRightVariableTotalData.self, for: ListRightVariableTotalDataModel.self)
try? ModelRegistry.register(handler: ListRightVariableTextLinkAllTextAndLinks.self, for: ListRightVariableTextLinkAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListRightVariableButtonAllTextAndLinks.self, for: ListRightVariableButtonAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListRightVariablePriceChangeBodyText.self, for: ListRightVariablePriceChangeBodyTextModel.self)
try? ModelRegistry.register(handler: ListRightVariablePriceChangeAllTextAndLinks.self, for: ListRightVariablePriceChangeAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListRightVariableToggleAllTextAndLinks.self, for: ListRightVariableToggleAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListRightVariableRightCaretAllTextAndLinks.self, for: ListRightVariableRightCaretAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListOneColumnFullWidthTextAllTextAndLinks.self, for: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
try? ModelRegistry.register(handler: ListOneColumnFullWidthTextBodyText.self, for: ListOneColumnFullWidthTextBodyTextModel.self)
try? ModelRegistry.register(handler: ListTwoColumnCompareChanges.self, for: ListTwoColumnCompareChangesModel.self)
try? ModelRegistry.register(handler: ListTwoColumnPriceDetails.self, for: ListTwoColumnPriceDetailsModel.self)
try? ModelRegistry.register(handler: ListTwoColumnPriceDescription.self, for: ListTwoColumnPriceDescriptionModel.self)
try? ModelRegistry.register(handler: ListTwoColumnDropdownSelectors.self, for: ListTwoColumnDropdownSelectorsModel.self)
try? ModelRegistry.register(handler: ListThreeColumnInternationalData.self, for: ListThreeColumnInternationalDataModel.self)
try? ModelRegistry.register(handler: ListThreeColumnDataUsage.self, for: ListThreeColumnDataUsageModel.self)
try? ModelRegistry.register(handler: ListThreeColumnBillChanges.self, for: ListThreeColumnBillChangesModel.self)
try? ModelRegistry.register(handler: ListThreeColumnBillHistory.self, for: ListThreeColumnBillHistoryModel.self)
try? ModelRegistry.register(handler: ListThreeColumnSpeedTest.self, for: ListThreeColumnSpeedTestModel.self)
try? ModelRegistry.register(handler: ListFourColumnDataUsageListItem.self, for: ListFourColumnDataUsageListItemModel.self)
try? ModelRegistry.register(handler: ListProgressBarThin.self, for: ListProgressBarThinModel.self)
try? ModelRegistry.register(handler: ListStoreLocator.self, for: ListStoreLocatorModel.self)
try? ModelRegistry.register(handler: ListStarRating.self, for: ListStarRatingModel.self)
// MARK:- Designed Section Dividers
try? ModelRegistry.register(handler: ListFourColumnDataUsageDivider.self, for: ListFourColumnDataUsageDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnPlanDataDivider.self, for: ListThreeColumnPlanDataDividerModel.self)
try? ModelRegistry.register(handler: ListOneColumnTextWithWhitespaceDividerShort.self, for: ListOneColumnTextWithWhitespaceDividerShortModel.self)
try? ModelRegistry.register(handler: ListOneColumnTextWithWhitespaceDividerTall.self, for: ListOneColumnTextWithWhitespaceDividerTallModel.self)
try? ModelRegistry.register(handler: ListOneColumnFullWidthTextDividerSubsection.self, for: ListOneColumnFullWidthTextDividerSubsectionModel.self)
try? ModelRegistry.register(handler: ListTwoColumnSubsectionDivider.self, for: ListTwoColumnSubsectionDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnInternationalDataDivider.self, for: ListThreeColumnInternationalDataDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnSpeedTestDivider.self, for: ListThreeColumnSpeedTestDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnBillChangesDivider.self, for: ListThreeColumnBillChangesDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnDataUsageDivider.self, for: ListThreeColumnDataUsageDividerModel.self)
try? ModelRegistry.register(handler: ListThreeColumnBillHistoryDivider.self, for: ListThreeColumnBillHistoryDividerModel.self)
// MARK:- Designed Headers
try? ModelRegistry.register(handler: HeadersH1Button.self, for: HeadersH1ButtonModel.self)
try? ModelRegistry.register(handler: HeadersH1LandingPageHeader.self, for: HeadersH1LandingPageHeaderModel.self)
try? ModelRegistry.register(handler: HeadersH1NoButtonsBodyText.self, for: HeadersH1NoButtonsBodyTextModel.self)
try? ModelRegistry.register(handler: HeadersH2NoButtonsBodyText.self, for: HeadersH2NoButtonsBodyTextModel.self)
try? ModelRegistry.register(handler: HeadersH2TinyButton.self, for: HeadersH2TinyButtonModel.self)
try? ModelRegistry.register(handler: HeadersH2Buttons.self, for: HeadersH2ButtonsModel.self)
try? ModelRegistry.register(handler: HeadersH2PricingTwoRows.self, for: HeadersH2PricingTwoRowsModel.self)
try? ModelRegistry.register(handler: HeadersH2Link.self, for: HeadersH2LinkModel.self)
try? ModelRegistry.register(handler: HeadersH2CaretLink.self, for: HeadersH2CaretLinkModel.self)
// MARK:- Device Items
try? ModelRegistry.register(handler: ListDeviceComplexButtonMedium.self, for: ListDeviceComplexButtonMediumModel.self)
try? ModelRegistry.register(handler: ListDeviceComplexButtonSmall.self, for: ListDeviceComplexButtonSmallModel.self)
try? ModelRegistry.register(handler: ListDeviceComplexLinkSmall.self, for: ListDeviceComplexLinkSmallModel.self)
try? ModelRegistry.register(handler: ListDeviceComplexLinkMedium.self, for: ListDeviceComplexLinkMediumModel.self)
// MARK:- LockUps
try? ModelRegistry.register(handler: LockUpsPlanNames.self, for: LockUpsPlanNamesModel.self)
try? ModelRegistry.register(handler: LockupsPlanSMLXL.self, for: LockupsPlanSMLXLModel.self)
// MARK: - Top Notifications
try? ModelRegistry.register(handler: NotificationView.self, for: NotificationModel.self)
try? ModelRegistry.register(handler: CollapsableNotification.self, for: CollapsableNotificationModel.self)
}
open class func registerLabelAttributes() {
try? ModelRegistry.register(LabelAttributeFontModel.self)
try? ModelRegistry.register(LabelAttributeColorModel.self)
try? ModelRegistry.register(LabelAttributeImageModel.self)
try? ModelRegistry.register(LabelAttributeUnderlineModel.self)
try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self)
try? ModelRegistry.register(LabelAttributeActionModel.self)
}
open class func registerBehaviors() {
try? ModelRegistry.register(handler: ScreenBrightnessModifierBehavior.self, for: ScreenBrightnessModifierBehaviorModel.self)
try? ModelRegistry.register(handler: PageGetContactBehavior.self, for: PageGetContactBehaviorModel.self)
}
open override class func registerActions() {
super.registerActions()
try? ModelRegistry.register(ActionPopupModel.self)
try? ModelRegistry.register(ActionAlertModel.self)
try? ModelRegistry.register(ActionTopAlertModel.self)
try? ModelRegistry.register(ActionCollapseNotificationModel.self)
try? ModelRegistry.register(ActionOpenPanelModel.self)
try? ModelRegistry.register(ActionTopNotificationModel.self)
}
open class func registerRules() {
try? ModelRegistry.register(RuleRequiredModel.self)
try? ModelRegistry.register(RuleAnyRequiredModel.self)
try? ModelRegistry.register(RuleAnyValueChangedModel.self)
try? ModelRegistry.register(RuleAllValueChangedModel.self)
try? ModelRegistry.register(RuleEqualsModel.self)
try? ModelRegistry.register(RuleEqualsIgnoreCaseModel.self)
try? ModelRegistry.register(RuleRegexModel.self)
}
}

View File

@ -9,10 +9,10 @@
import UIKit
@objcMembers open class CoreUIObject: MVMCoreObject {
public var moleculeMap: MoleculeObjectMapping?
public var globalTopAlertDelegate: MVMCoreGlobalTopAlertDelegateProtocol?
open override func defaultInitialSetup() {
CoreUIModelMapping.registerObjects()
loadHandler = MVMCoreLoadHandler()
cache = MVMCoreCache()
sessionHandler = MVMCoreSessionTimeHandler()
@ -20,8 +20,5 @@ import UIKit
session = MVMCoreUISession()
viewControllerMapping = MVMCoreUIViewControllerMappingObject()
loggingDelegate = MVMCoreUILoggingHandler()
moleculeMap = MoleculeObjectMapping()
MoleculeObjectMapping.registerObjects()
clientParameterRegistry = ClientParameterRegistry()
}
}

View File

@ -88,10 +88,10 @@ public extension MVMCoreUITopAlertView {
let delegateObject = getDelegateObject()
guard let newJson = topAlertObject.json,
let newModel = decodeTopNotification(with: newJson, delegateObject: delegateObject),
let newModelName = MoleculeObjectMapping.shared()?.getMoleculeClass(newModel.molecule)?.nameForReuse(with: newModel.molecule, delegateObject),
let newModelName = ModelRegistry.getMoleculeClass(newModel.molecule)?.nameForReuse(with: newModel.molecule, delegateObject),
let currentJson = self.topAlertObject?.json,
let currentModel = decodeTopNotification(with: currentJson, delegateObject: delegateObject),
let currentModelName = MoleculeObjectMapping.shared()?.getMoleculeClass(currentModel.molecule)?.nameForReuse(with: currentModel.molecule, delegateObject),
let currentModelName = ModelRegistry.getMoleculeClass(currentModel.molecule)?.nameForReuse(with: currentModel.molecule, delegateObject),
newModelName == currentModelName,
let molecule = currentAlert as? MoleculeViewProtocol else {
// Log that we couldn't update.
@ -119,7 +119,7 @@ public extension MVMCoreUITopAlertView {
let delegateObject = MVMCoreUIDelegateObject.create(withDelegateForAll: self)
guard let json = topAlertObject.json else { return nil }
let model = try TopNotificationModel.decode(json: json, delegateObject: delegateObject)
guard let molecule = MoleculeObjectMapping.shared()?.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: nil) else {
guard let molecule = ModelRegistry.createMolecule(model.molecule, delegateObject: delegateObject, additionalData: nil) else {
throw ModelRegistry.Error.decoderOther(message: "Molecule not mapped")
}
if let castView = molecule as? StatusBarUI {