Merge branch 'develop' into feature/account_settings_push_enablement

This commit is contained in:
Nowfal E Salam 2023-04-14 18:23:54 +05:30
commit 850b030b66
28 changed files with 684 additions and 66 deletions

View File

@ -22,9 +22,9 @@ download_artifacts:
- bash_shell
environment:
name: oneartifactory
url: https://oneartifactoryprod.verizon.com/artifactory
url: https://oneartifactoryci.verizon.com/artifactory
variables:
ARTIFACTORY_URL: https://oneartifactoryprod.verizon.com/artifactory
ARTIFACTORY_URL: https://oneartifactoryci.verizon.com/artifactory
build_project:
stage: build
@ -47,9 +47,9 @@ deploy_snapshot:
- bash_shell
environment:
name: oneartifactory
url: https://oneartifactoryprod.verizon.com/artifactory
url: https://oneartifactoryci.verizon.com/artifactory
variables:
ARTIFACTORY_URL: https://oneartifactoryprod.verizon.com/artifactory
ARTIFACTORY_URL: https://oneartifactoryci.verizon.com/artifactory
#promote_snapshot:
# stage: go live
@ -65,9 +65,9 @@ deploy_snapshot:
# - bash_shell
# environment:
# name: oneartifactory
# url: https://oneartifactoryprod.verizon.com/artifactory
# url: https://oneartifactoryci.verizon.com/artifactory
# variables:
# ARTIFACTORY_URL: https://oneartifactoryprod.verizon.com/artifactory
# ARTIFACTORY_URL: https://oneartifactoryci.verizon.com/artifactory
#
#create_version_tag:
# stage: tag

View File

@ -597,9 +597,18 @@
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; };
EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; };
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilelet.swift */; };
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; };
EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; };
EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; };
EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */; };
EA985C872981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */; };
EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */; };
EA985C8B2983259900F2FF2E /* VDS-LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */; };
EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; };
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; };
EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; };
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */; };
EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */; };
EAB14BC327D9378D0012AB2C /* RuleAnyModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */; };
EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC1402763BB8D00E78B40 /* FormLabel.swift */; };
@ -1201,9 +1210,18 @@
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = "<group>"; };
EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIUpdatableModelProtocol.swift; sourceTree = "<group>"; };
EA985C3D2970938F00F2FF2E /* Tilelet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilelet.swift; sourceTree = "<group>"; };
EA985C3F2970939A00F2FF2E /* TileletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileletModel.swift; sourceTree = "<group>"; };
EA985C5F2970A3F000F2FF2E /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = ../SharedFrameworks/VDSTypographyTokens.xcframework; sourceTree = "<group>"; };
EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Enums+Codable.swift"; sourceTree = "<group>"; };
EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Tilelet+Codable.swift"; sourceTree = "<group>"; };
EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-TextStyle.swift"; sourceTree = "<group>"; };
EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-LabelAttributeModel.swift"; sourceTree = "<group>"; };
EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = "<group>"; };
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = "<group>"; };
EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = "<group>"; };
EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSMoleculeViewProtocol.swift; sourceTree = "<group>"; };
EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleCompareModelProtocol.swift; sourceTree = "<group>"; };
EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModelProtocol.swift; sourceTree = "<group>"; };
EABFC1402763BB8D00E78B40 /* FormLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormLabel.swift; sourceTree = "<group>"; };
@ -1218,7 +1236,9 @@
files = (
D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */,
AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */,
EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */,
187FEB2A2844D2A600BF29C2 /* VDSFormControlsTokens.xcframework in Frameworks */,
EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1611,6 +1631,10 @@
D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */,
D2E0FFF726AF68530085D696 /* UITableViewRowAnimation+Extension.swift */,
4457904D27ECE989002B1E1E /* UIImageRenderingMode+Extension.swift */,
EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */,
EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */,
EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */,
EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -2064,6 +2088,8 @@
D29DF0E421E4F3C7003B2FB9 /* Frameworks */ = {
isa = PBXGroup;
children = (
EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */,
EA985C5F2970A3F000F2FF2E /* VDS.framework */,
187FEB292844D2A600BF29C2 /* VDSFormControlsTokens.xcframework */,
AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */,
D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */,
@ -2261,6 +2287,8 @@
AA37CBD42519072F0027344C /* Stars.swift */,
AA07EA902510A442009A2AE3 /* StarModel.swift */,
AA07EA922510A451009A2AE3 /* Star.swift */,
EA985C3D2970938F00F2FF2E /* Tilelet.swift */,
EA985C3F2970939A00F2FF2E /* TileletModel.swift */,
);
path = Views;
sourceTree = "<group>";
@ -2458,6 +2486,7 @@
D2B9D0E3265EEE9D0084735C /* MoleculeListProtocol.swift */,
011B58EE23A2AA850085F53C /* ModelProtocols */,
27559EFB27D691D3000836C1 /* ViewMaskingProtocol.swift */,
EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */,
);
path = Protocols;
sourceTree = "<group>";
@ -2741,6 +2770,7 @@
D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */,
EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */,
011D95A924057AC7000E3791 /* FormGroupWatcherFieldProtocol.swift in Sources */,
EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */,
BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */,
D20C700B250BFDE40095B21C /* MVMCoreUITopAlertView+Extension.swift in Sources */,
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */,
@ -2765,6 +2795,7 @@
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */,
32D2609724C19E2100B56344 /* LockupsPlanSMLXLModel.swift in Sources */,
EA985C872981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift in Sources */,
D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */,
D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */,
AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */,
@ -2783,7 +2814,9 @@
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */,
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */,
D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */,
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
@ -2968,6 +3001,7 @@
FD99130028E21E4900542CC3 /* RuleNotEqualsModel.swift in Sources */,
BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */,
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */,
EA985C8B2983259900F2FF2E /* VDS-LabelAttributeModel.swift in Sources */,
944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */,
D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */,
C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */,
@ -3092,6 +3126,7 @@
BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */,
012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */,
94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */,
EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */,
AAB8549824DC01BD00477C40 /* ListThreeColumnBillHistoryDividerModel.swift in Sources */,
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
@ -3178,6 +3213,7 @@
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */,
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */,
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,

View File

@ -314,7 +314,7 @@ import MVMCore
}
/// Adjust accessibility label based on state of Checkbox.
func updateAccessibilityLabel() {
public func updateAccessibilityLabel() {
// Attention: This needs to be addressed with the accessibility team.
// NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing!
if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state") {

View File

@ -15,8 +15,8 @@ public enum CheckboxPosition: String, Codable {
case bottom
}
@objcMembers public class CheckboxLabelModel: MoleculeModelProtocol {
public static var identifier: String = "checkboxLabel"
@objcMembers open class CheckboxLabelModel: MoleculeModelProtocol {
open class var identifier: String { "checkboxLabel" }
public var moleculeName: String = CheckboxLabelModel.identifier
public var backgroundColor: Color?
public var checkboxAlignment: CheckboxPosition?

View File

@ -741,36 +741,6 @@ public typealias ActionBlock = () -> ()
clauses.append(ActionableClause(range: range, actionBlock: actionBlock, accessibilityID: accessibleAction?.hash ?? -1))
}
/**
Provides a text container and layout manager of how the text would appear on screen.
They are used in tandem to derive low-level TextKit results of the label.
*/
public func abstractTextContainer() -> (NSTextContainer, NSLayoutManager, NSTextStorage)? {
// Must configure the attributed string to translate what would appear on screen to accurately analyze.
guard let attributedText = attributedText else { return nil }
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = textAlignment
let stagedAttributedString = NSMutableAttributedString(attributedString: attributedText)
stagedAttributedString.addAttributes([NSAttributedString.Key.paragraphStyle: paragraph], range: NSRange(location: 0, length: attributedText.string.count))
let textStorage = NSTextStorage(attributedString: stagedAttributedString)
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: .zero)
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = lineBreakMode
textContainer.maximumNumberOfLines = numberOfLines
textContainer.size = bounds.size
return (textContainer, layoutManager, textStorage)
}
public static func boundingRect(forCharacterRange range: NSRange, in label: Label) -> CGRect {
guard let abstractContainer = label.abstractTextContainer() else { return CGRect() }

View File

@ -17,6 +17,7 @@ class LabelAttributeImageModel: LabelAttributeModel {
var size: CGFloat?
var name: String?
var URL: String?
var tintColor: Color?
//--------------------------------------------------
// MARK: - Initializer
@ -34,6 +35,7 @@ class LabelAttributeImageModel: LabelAttributeModel {
case size
case name
case URL
case tintColor
}
//--------------------------------------------------
@ -55,6 +57,7 @@ class LabelAttributeImageModel: LabelAttributeModel {
size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size)
name = try typeContainer.decodeIfPresent(String.self, forKey: .name)
URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL)
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor)
try super.init(from: decoder)
}
@ -64,5 +67,6 @@ class LabelAttributeImageModel: LabelAttributeModel {
try container.encodeIfPresent(size, forKey: .size)
try container.encodeIfPresent(name, forKey: .name)
try container.encodeIfPresent(URL, forKey: .URL)
try container.encodeIfPresent(tintColor, forKey: .tintColor)
}
}

View File

@ -7,12 +7,13 @@
//
@objcMembers open class LabelModel: MoleculeModelProtocol {
@objcMembers open class LabelModel: MoleculeModelProtocol, Identifiable {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open class var identifier: String { "label" }
public var id: String
public var backgroundColor: Color?
public var text: String
public var accessibilityText: String?
@ -34,6 +35,7 @@
private enum CodingKeys: String, CodingKey {
case moleculeName
case id
case text
case accessibilityText
case textColor
@ -58,7 +60,8 @@
// MARK: - Initializer
//--------------------------------------------------
public init(text: String) {
public init(id: String = UUID().uuidString, text: String) {
self.id = id
self.text = text
}
@ -78,6 +81,7 @@
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
text = try typeContainer.decode(String.self, forKey: .text)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
@ -102,6 +106,7 @@
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(id, forKey: .id)
try container.encode(text, forKey: .text)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(textColor, forKey: .textColor)

View File

@ -0,0 +1,85 @@
//
// Tilet.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/12/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
import VDS
import Combine
/**
This class expects its height and width to be equal.
*/
open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var viewModel: TileletModel!
public var delegateObject: MVMCoreUIDelegateObject?
public var additionalData: [AnyHashable: Any]?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public convenience required init() {
self.init(frame: .zero)
}
//--------------------------------------------------
// MARK: - Public
//--------------------------------------------------
public func viewModelDidUpdate() {
color = viewModel.color
padding = viewModel.padding
aspectRatio = viewModel.aspectRatio
width = viewModel.width
textWidth = viewModel.textWidth
textPercentage = viewModel.textPercentage
titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData)
subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData)
badgeModel = viewModel.badge
descriptiveIconModel = viewModel.descriptiveIcon
directionalIconModel = viewModel.directionalIcon
//setup action
if let action = viewModel.action {
//add the subscriber
onClickSubscriber = publisher(for: .touchUpInside)
.sink {[weak self] control in
guard let self else { return }
MVMCoreUIActionHandler.performActionUnstructured(with: action,
sourceModel: self.viewModel,
additionalData: self.additionalData,
delegateObject: self.delegateObject)
}
}
}
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open func updateView(_ size: CGFloat) {}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
//since this is a class func, we can't reference it directly
public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
100
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
open override func layoutSubviews() {
super.layoutSubviews()
// Accounts for any collection size changes
DispatchQueue.main.async { [weak self] in
guard let self else { return }
self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self)
}
}
}

View File

@ -0,0 +1,103 @@
//
// TiletModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/12/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class TileletModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "tilelet"
public var backgroundColor: Color?
public var color: TileContainer.BackgroundColor
public var padding: TileContainer.Padding
public var aspectRatio: TileContainer.AspectRatio
public var badge: Tilelet.BadgeModel?
public var title: LabelModel?
public var subTitle: LabelModel?
public var descriptiveIcon: Tilelet.DescriptiveIcon?
public var directionalIcon: Tilelet.DirectionalIcon?
public var width: CGFloat?
public var textWidth: CGFloat?
public var textPercentage: CGFloat?
public var action: ActionModelProtocol?
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case color
case padding
case aspectRatio
case badge
case title
case subTitle
case descriptiveIcon
case directionalIcon
case width
case textWidth
case textPercentage
case action
}
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor)
self.color = try container.decodeIfPresent(TileContainer.BackgroundColor.self, forKey: .color) ?? TileContainer.BackgroundColor.black
self.padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? TileContainer.Padding.padding4X
self.aspectRatio = try container.decodeIfPresent(TileContainer.AspectRatio.self, forKey: .aspectRatio) ?? TileContainer.AspectRatio.none
self.badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
self.title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
self.subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
self.descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon)
self.directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon)
self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth)
self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage)
action = try container.decodeModelIfPresent(codingKey: .action)
}
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
guard let title else { return nil }
let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
let style: Tilelet.TitleModel.TextStyle? = title.fontStyle?.vdsSubsetStyle()
if let style {
return .init(text: title.text, textAttributes: attrs, textStyle: style)
} else {
return .init(text: title.text, textAttributes: attrs)
}
}
public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.SubTitleModel? {
guard let subTitle else { return nil }
let style: Tilelet.SubTitleModel.TextStyle? = subTitle.fontStyle?.vdsSubsetStyle()
if let style {
return .init(text: subTitle.text, textStyle: style)
} else {
return .init(text: subTitle.text)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(color, forKey: .color)
try container.encodeIfPresent(padding, forKey: .padding)
try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio)
try container.encodeIfPresent(badge, forKey: .badge)
try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(subTitle, forKey: .subTitle)
try container.encodeIfPresent(descriptiveIcon, forKey: .descriptiveIcon)
try container.encodeIfPresent(directionalIcon, forKey: .directionalIcon)
try container.encodeIfPresent(width, forKey: .width)
try container.encodeIfPresent(textWidth, forKey: .textWidth)
try container.encodeIfPresent(textPercentage, forKey: .textPercentage)
try container.encodeModelIfPresent(action, forKey: .action)
}
}

View File

@ -0,0 +1,18 @@
//
// VDS-Enums+Codable.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/25/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
extension Surface: Codable {}
extension Badge.FillColor: Codable {}
extension Icon.Name: Codable {}
extension Icon.Size: Codable {}
extension TileContainer.BackgroundColor: Codable {}
extension TileContainer.Padding: Codable {}
extension TileContainer.AspectRatio: Codable {}

View File

@ -0,0 +1,205 @@
//
// VDS-LabelAttributeModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/26/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
import Combine
//Meant to be used to convert Any Array of type LabelAttributeModel
extension Array where Element: MVMCoreUI.LabelAttributeModel {
public func toVDSLabelAttributeModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> [any VDS.LabelAttributeModel] {
var attributes: [any VDS.LabelAttributeModel] = []
forEach { atomicLabelAttribute in
if let attr = atomicLabelAttribute as? (any VDSLabelAttributeConvertable),
let vds = attr.convertToVDSLabelAttirbute(delegateObject: delegateObject,
additionalData: additionalData){
attributes.append(vds)
}
}
return attributes
}
}
//VDS Convertable Protocol and Extensions
public protocol VDSLabelAttributeConvertable<LabelAttributeType> {
associatedtype LabelAttributeType: VDS.LabelAttributeModel
func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> LabelAttributeType?
}
extension LabelAttributeUnderlineModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UnderlineLabelAttribute? {
guard let style = UnderlineLabelAttribute.Style(rawValue: style.rawValue) else { return nil }
var pattern: UnderlineLabelAttribute.Pattern?
if let attrPattern = pattern {
pattern = UnderlineLabelAttribute.Pattern(rawValue: attrPattern.rawValue)
}
return VDS.UnderlineLabelAttribute(location: location,
length: length,
style: style,
color: color?.uiColor,
pattern: pattern)
}
}
extension LabelAttributeActionModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ActionLabelAttribute? {
var vdsAttribute = VDS.ActionLabelAttribute(location: location, length: length)
vdsAttribute.subscriber = vdsAttribute.action.sink { [weak self] in
guard let self else { return }
MVMCoreUIActionHandler.performActionUnstructured(with: self.action,
sourceModel: nil,
additionalData: additionalData,
delegateObject: delegateObject)
}
return vdsAttribute
}
}
extension LabelAttributeFontModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> TextStyleLabelAttribute? {
var textStyle: TextStyle?
if let found = style?.vdsTextStyle() {
textStyle = found
} else if let name, let found = TextStyle(rawValue: name) {
textStyle = found
}
guard let textStyle else { return nil }
return TextStyleLabelAttribute(location: location,
length: length,
textStyle: textStyle)
}
}
extension LabelAttributeColorModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ColorLabelAttribute? {
guard let textColor else { return nil }
return ColorLabelAttribute(location: location,
length: length,
color: textColor.uiColor)
}
}
extension LabelAttributeStrikeThroughModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> StrikeThroughLabelAttribute? {
return StrikeThroughLabelAttribute(location: location,
length: length)
}
}
extension LabelAttributeImageModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> AtomicImageLabelAttribute? {
var frame: CGRect?
if let size {
frame = CGRect(x: 0, y: 0, width: size, height: size)
}
return AtomicImageLabelAttribute(location: location,
length: length,
imageName: name,
imageURL: URL,
frame: frame,
tintColor: tintColor?.uiColor)
}
}
//Custom Atomic Additions for the ImageAttachment
public class AtomicImageLabelAttribute: AttachmentLabelAttributeModel {
//--------------------------------------------------
// MARK: - Enums
//--------------------------------------------------
public enum Error: Swift.Error {
case bundleNotFound
case imageNotFound(String)
case imageNotSet
}
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
public var id = UUID()
public var location: Int
public var length: Int = 1
public var imageName: String?
public var imageURL: String?
public var image: UIImage?
public var frame: CGRect?
public var tintColor: UIColor?
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
public init(location: Int, length: Int = 1, imageName: String? = nil, imageURL: String? = nil,
image: UIImage? = nil, frame: CGRect? = nil, tintColor: UIColor?) {
self.location = location
self.length = length
self.imageName = imageName
self.imageURL = imageURL
self.image = image
self.frame = frame
self.tintColor = tintColor
fetchImage()
}
//--------------------------------------------------
// MARK: - Equatable
//--------------------------------------------------
public static func == (lhs: AtomicImageLabelAttribute, rhs: AtomicImageLabelAttribute) -> Bool {
lhs.isEqual(rhs)
}
public func isEqual(_ equatable: AtomicImageLabelAttribute) -> Bool {
return id == equatable.id && range == equatable.range && imageName == equatable.imageName && imageURL == equatable.imageURL
}
//--------------------------------------------------
// MARK: - Private Functions
//--------------------------------------------------
private func fetchImage() {
if image != nil { return }
//get a local asset
if let imageName {
if let coreImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(imageName) {
image = coreImage
}
if let vdsImage = BundleManager.shared.image(for: imageName) {
image = vdsImage
}
}//get from url
else if let imageURL {
DispatchQueue.global(qos: .default).async {
MVMCoreCache.shared()?.getImage(imageURL, useWidth: false, widthForS7: 0, useHeight: false, heightForS7: 0, localFallbackImageName: nil) { [weak self] image, data, _ in
DispatchQueue.main.sync {
self?.image = image
}
}
}
}
}
//--------------------------------------------------
// MARK: - Public Functions
//--------------------------------------------------
public func getAttachment() throws -> NSTextAttachment {
if let image {
let attachment = NSTextAttachment()
attachment.image = tintColor != nil ? image.withTintColor(tintColor!) : image
attachment.bounds = frame ?? .init(x: 0, y: 0, width: image.size.width, height: image.size.height)
return attachment
} else {
throw Error.imageNotSet
}
}
}

View File

@ -0,0 +1,31 @@
//
// VDS-TextStyle.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/25/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
extension Styler.Font {
//Converts Legacy Font to a VDS.TextStyle
public func vdsTextStyle() -> VDS.TextStyle? {
let updatedRaw = rawValue.replacingOccurrences(of: "Regular", with: "")
let newRaw = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst()
guard let style = VDS.TextStyle(rawValue: newRaw) else { return nil }
return style
}
public func vdsSubsetStyle<T: EnumSubset>() -> T? {
guard let style = vdsTextStyle() else { return nil }
guard let rawValue = style.rawValue as? T.RawValue,
let found = T(rawValue: rawValue) else {
print("Style: \(style.rawValue) is not in enum \(T.self)\ronly these cases exist:\r\(T.allCases)")
return nil
}
return found
}
}

View File

@ -0,0 +1,75 @@
//
// VDS-Tilelet+Codable.swift
// MVMCoreUI
//
// Created by Matt Bruce on 1/25/23.
// Copyright © 2023 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
extension Tilelet.BadgeModel: Codable {
private enum CodingKeys: String, CodingKey {
case text, fillColor, surface, numberOfLines, maxWidth
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let text = try container.decode(String.self, forKey: .text)
let fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red
let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light
let numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 0
let maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth)
self.init(text: text, fillColor: fillColor, surface: surface, numberOfLines: numberOfLines, maxWidth: maxWidth)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(fillColor, forKey: .fillColor)
try container.encode(surface, forKey: .surface)
try container.encode(numberOfLines, forKey: .numberOfLines)
try container.encodeIfPresent(maxWidth, forKey: .maxWidth)
}
}
extension Tilelet.DescriptiveIcon: Codable {
private enum CodingKeys: String, CodingKey {
case name, size, surface
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let name = try container.decode(Icon.Name.self, forKey: .name)
let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium
let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark
self.init(name: name, size: size, surface: surface)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(size, forKey: .size)
try container.encode(surface, forKey: .surface)
}
}
extension Tilelet.DirectionalIcon: Codable {
private enum CodingKeys: String, CodingKey {
case size, surface
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium
let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark
self.init(size: size, surface: surface)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(size, forKey: .size)
try container.encode(surface, forKey: .surface)
}
}

View File

@ -7,7 +7,7 @@
//
open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelProtocol {
open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -16,6 +16,10 @@ open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelPr
public var checkbox: CheckboxModel
public var headlineBody: HeadlineBodyModel
public var children: [MoleculeModelProtocol] {
[checkbox, headlineBody]
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------

View File

@ -9,7 +9,7 @@
import Foundation
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol {
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -35,6 +35,10 @@ public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeMod
headlineBody.style = .item
}
public var children: [MoleculeModelProtocol] {
return [headlineBody]
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------

View File

@ -7,7 +7,7 @@
//
public class ListRightVariableButtonAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol {
public class ListRightVariableButtonAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -36,6 +36,10 @@ public class ListRightVariableButtonAllTextAndLinksModel: ListItemModel, Molecul
self.button.style = .secondary
}
public var children: [MoleculeModelProtocol] {
return [button, eyebrowHeadlineBodyLink]
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------

View File

@ -47,6 +47,11 @@
self.body = body
}
public init(headline: LabelModel, body: LabelModel) {
self.headline = headline
self.body = body
}
//-----------------------------------------------------
// MARK: - Codec
//-----------------------------------------------------

View File

@ -0,0 +1,32 @@
//
// VDSMoleculeViewProtocol.swift
// MVMCoreUI
//
// Created by Matt Bruce on 10/19/22.
// Copyright © 2022 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
///-----------------------------------------------------------------------------
///MARK: -- VDSMoleculeViewProtocol (Contract between VDS -> Atomic)
///-----------------------------------------------------------------------------
public protocol VDSMoleculeViewProtocol: MoleculeViewProtocol, MVMCoreViewProtocol {
associatedtype ViewModel: MoleculeModelProtocol
var viewModel: ViewModel! { get set }
var delegateObject: MVMCoreUIDelegateObject? { get set }
var additionalData: [AnyHashable: Any]? { get set }
func viewModelDidUpdate()
}
extension VDSMoleculeViewProtocol {
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let castedModel = model as? ViewModel else { return }
self.delegateObject = delegateObject
self.additionalData = additionalData
viewModel = castedModel
viewModelDidUpdate()
}
}

View File

@ -7,12 +7,12 @@
//
@objcMembers public class ThreeLayerPageTemplateModel: ThreeLayerModelBase {
@objcMembers open class ThreeLayerPageTemplateModel: ThreeLayerModelBase {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public override class var identifier: String { "threeLayer" }
open override class var identifier: String { "threeLayer" }
public var middle: MoleculeModelProtocol?
public override var rootMolecules: [MoleculeModelProtocol] {
@ -51,7 +51,7 @@
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeModelIfPresent(header, forKey: .middle)

View File

@ -9,7 +9,7 @@
import UIKit
@objcMembers open class Control: UIControl, MoleculeViewProtocol {
open class Control: UIControl, MoleculeViewProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------

View File

@ -132,9 +132,9 @@ import MVMCore
try parsePageJSON()
} catch let parsingError {
// Log all parsing errors and fail load.
handleLoggingFor(parsingError: parsingError)
if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) {
if let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, causedBy: parsingError) {
errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
errorObject.messageToLog = describe(parsingError: parsingError)
error.pointee = errorObject
}
return false
@ -146,40 +146,54 @@ import MVMCore
}
}
///Check with behavior if it can continue
do{
let allFinishedProcessingLoad = try executeThrowingBehaviors {(behavior: PageMoleculeTransformationBehavior) in
return try behavior.shouldFinishProcessingLoad(loadObject)
}
guard allFinishedProcessingLoad else { return false }
} catch let behaviorError {
if let errorObject = MVMCoreErrorObject.createErrorObject(for: behaviorError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) {
error.pointee = errorObject
}
return false
}
return true
}
func handleLoggingFor(parsingError: Error) {
func describe(parsingError: Error) -> String {
if let registryError = parsingError as? ModelRegistry.Error {
switch (registryError) {
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })")
return "Error parsing template. Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })"
case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })")
case .decoderErrorObjectNotPresent(let codingKey, let codingPath):
return "Error parsing template. Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })"
default:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)")
return "Error parsing template. Registry error: \((registryError as NSError).localizedFailureReason ?? registryError.localizedDescription)"
}
}
if let decodingError = parsingError as? DecodingError {
switch (decodingError) {
case .keyNotFound(let codingKey, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })")
return "Error parsing template. Required key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })"
case .valueNotFound(_, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })")
return "Error parsing template. Value not found @ \(context.codingPath.map { return $0.stringValue })"
case .typeMismatch(_, let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })")
return "Error parsing template. Value type mismatch @ \(context.codingPath.map { return $0.stringValue })"
case .dataCorrupted(let context):
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })")
return "Error parsing template. Data corrupted @ \(context.codingPath.map { return $0.stringValue })"
@unknown default:
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)")
return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)"
}
}
return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)"
}
open func parsePageJSON() throws { }
@ -200,7 +214,8 @@ import MVMCore
}
guard modulesRequired.count == 0 else {
if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), messageToLog: modulesRequired.description, code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject!)) {
if let loadObject = loadObject, let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, withTitle:nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative) {
errorObject.messageToLog = modulesRequired.description
error.pointee = errorObject
}
return false
@ -473,6 +488,14 @@ import MVMCore
open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))!
switch (model) {
case let model as ActionOpenPageModel:
errorObject.silentError = model.background ?? false
default:
errorObject.silentError = false
}
MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData)
}

View File

@ -44,4 +44,8 @@ public extension PageBehaviorHandlerProtocol {
func executeBehaviors<T>(_ behaviorBlock: (_ behavior: T) -> Void) {
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
}
func executeThrowingBehaviors<T>(_ behaviourBlock: (_ behavior: T) throws -> Bool) throws -> Bool {
return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? true
}
}

View File

@ -32,6 +32,7 @@ public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol)
func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar)
func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol)
func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) throws -> Bool
}
public extension PageMoleculeTransformationBehavior {
@ -41,6 +42,7 @@ public extension PageMoleculeTransformationBehavior {
func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) {}
func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar) {}
func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol) {}
func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) throws -> Bool { return true }
}
public protocol PageVisibilityBehavior: PageBehaviorProtocol {

View File

@ -71,7 +71,8 @@ open class CoreUIModelMapping: ModelMapping {
ModelRegistry.register(handler: WebView.self, for: WebViewModel.self)
ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self)
ModelRegistry.register(handler: Video.self, for: VideoModel.self)
ModelRegistry.register(handler: Tilelet.self, for: TileletModel.self)
// MARK:- Horizontal Combination Molecules
ModelRegistry.register(handler: StringAndMoleculeView.self, for: StringAndMoleculeModel.self)
ModelRegistry.register(handler: ImageHeadlineBody.self, for: ImageHeadlineBodyModel.self)

View File

@ -41,6 +41,7 @@ import SafariServices
open override func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable : Any]?) {
super.defaultHandleActionError(error, additionalData: additionalData)
guard !error.silentError else { return }
error.silentError = true // Silence if this error is triggered again. (Legacy action handler flow.)
Task(priority: .userInitiated) { @MainActor in
let alertObject = MVMCoreAlertObject.init(popupAlertWithError: error, isGreedy: false)!
MVMCoreAlertHandler.shared()?.showAlert(with: alertObject)

View File

@ -15,6 +15,10 @@ UNIVERSAL_OUTPUTFOLDER="${BUILD_DIR}/universal"
# Update to use .xcframework
sed -i '' 's|MVMCore.framework \*\/ = {isa.*};|MVMCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MVMCore.xcframework; path = ../SharedFrameworks/MVMCore.xcframework; sourceTree = "<group>"; };|g' ./MVMCoreUI.xcodeproj/project.pbxproj
sed -i '' 's/MVMCore.framework/MVMCore.xcframework/g' ./MVMCoreUI.xcodeproj/project.pbxproj
sed -i '' 's|VDS.framework \*\/ = {isa.*};|VDS.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDS.xcframework; path = ../SharedFrameworks/VDS.xcframework; sourceTree = "<group>"; };|g' ./MVMCoreUI.xcodeproj/project.pbxproj
sed -i '' 's/VDS.framework/VDS.xcframework/g' ./MVMCoreUI.xcodeproj/project.pbxproj
sed -i '' "s|path = \.\.\/SharedFrameworks|path = ${FRAMEWORKS_DIR}|g" ./MVMCoreUI.xcodeproj/project.pbxproj
# Build device archive

View File

@ -8,7 +8,7 @@
# Create new aggregate builds
if [ -z $ARTIFACTORY_URL ]; then
ARTIFACTORY_URL="https://oneartifactoryprod.verizon.com/artifactory"
ARTIFACTORY_URL="https://oneartifactoryci.verizon.com/artifactory"
fi
BUILD_DIR=$(xcodebuild -showBuildSettings -project ./MVMCoreUI.xcodeproj | grep -w -o 'BUILD_DIR = .*' | cut -d\ -f3-)
@ -18,8 +18,10 @@ if [ ! -d $FRAMEWORKS_DIR ]; then
mkdir -p $FRAMEWORKS_DIR
fi
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/MVMCore.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/MVMCore/3.0/MVMCore-3.0-Debug-SNAPSHOT.zip
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/MVMCore.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/MVMCore/3.1/MVMCore-3.1-Debug-SNAPSHOT.zip
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSColorTokens.xcframework" GVJV_VDS_Maven/%40vds-tokens/ios/VDSColorTokens.1.0.6.xcframework.zip
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDS.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/VDS/1.0/VDS-1.0-Debug-SNAPSHOT.zip
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSColorTokens.xcframework" GVJV_VDS_Maven/@vds-tokens/ios/VDSColorTokens.1.0.6.xcframework.zip
./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSFormControlsTokens.xcframework" GVJV_VDS_Maven/@vds-tokens/ios/VDSFormControlsTokens.1.0.7.xcframework.zip

View File

@ -17,7 +17,7 @@ fi
# Create new aggregate builds
if [ -z $ARTIFACTORY_URL ]; then
ARTIFACTORY_URL="https://oneartifactoryprod.verizon.com/artifactory"
ARTIFACTORY_URL="https://oneartifactoryci.verizon.com/artifactory"
fi
# Upload