From e7f21b980fd3f022226df0d1bd9260c61febcb69 Mon Sep 17 00:00:00 2001 From: Kyle Hedden Date: Wed, 9 Aug 2023 16:37:03 -0400 Subject: [PATCH 01/20] serialize timer updates to prevent cold dispatch collisions --- MVMCoreUI/Notification/NotificationHandler.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index ff9d90ad..c1e064d7 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -562,7 +562,9 @@ extension NotificationOperation { guard isExecuting, !isCancelled else { return } self.log(message: "Operation Updated") - updateStopTimer() + displayableQueue.async(flags: .barrier) { [self] in + updateStopTimer() + } Task { await transitionDelegate.update(with: notificationModel, delegateObject: delegateObject) NotificationHandler.shared()?.onNotificationUpdated.send((notification, notificationModel)) From d3fe47522cf4db0b4d348c50a08746deaea9a7b1 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Tue, 15 Aug 2023 16:23:13 -0400 Subject: [PATCH 02/20] Swiftification of Navigation Handler --- MVMCoreUI/Alerts/AlertOperation.swift | 58 +++++++------- .../FormFields/TextFields/MdnEntryField.swift | 4 +- .../CollapsableNotification.swift | 2 +- .../NavigationController.swift | 75 ++++++++++--------- .../UINavigationController+Extension.swift | 3 +- ...MCoreUISplitViewController+Extension.swift | 65 ++++++++++++---- .../MVMCoreUISplitViewController.m | 3 +- .../SubNav/SubNavManagerController.swift | 6 +- .../Notification/NotificationHandler.swift | 45 +++++------ MVMCoreUI/Utility/MVMCoreUIUtility.m | 1 - 10 files changed, 156 insertions(+), 106 deletions(-) diff --git a/MVMCoreUI/Alerts/AlertOperation.swift b/MVMCoreUI/Alerts/AlertOperation.swift index bbffbd32..088a6ff5 100644 --- a/MVMCoreUI/Alerts/AlertOperation.swift +++ b/MVMCoreUI/Alerts/AlertOperation.swift @@ -51,30 +51,33 @@ public class AlertOperation: MVMCoreOperation { // Observe for when it is removed. observeForCurrentAlertViewDismissal() - // Adds the presentation to the animation queue. - let blockingOperation = MVMCoreOperation() - self.blockingOperation = blockingOperation - Task { @MainActor in - MVMCoreNavigationHandler.shared()?.present(alertController, animated: true, delegate: nil) { [weak self] in - guard let self = self else { - blockingOperation.markAsFinished() - return - } - Task { - // We finished but it was not displayed yet. It's possible that it was cancelled. Finish this task - if await !self.properties.getIsDisplayed() { - self.markAsFinished() - } else { - (CoreUIObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject) - if self.isCancelled { - await self.dismissAlertView() - } - } - } + Task(priority: .high) { + guard let viewControllerToPresentOn = await NavigationHandler.shared().getViewControllerToPresentOn() else { + markAsFinished() + return } - // Block navigations until this alert is removed. - MVMCoreNavigationHandler.shared()?.addNavigationOperation(blockingOperation) + // Presents the alert. + let presentationOperation = await NavigationOperation(with: .present(viewController: alertController, onController: viewControllerToPresentOn), tryToReplace: false) + + let blockingOperation = MVMCoreOperation() + blockingOperation.addDependency(presentationOperation) + self.blockingOperation = blockingOperation + + // Block other navigation until this alert is removed. + NavigationHandler.shared().navigationQueue.addOperation(blockingOperation) + + await NavigationHandler.shared().navigate(with: presentationOperation) + + // We finished but it was not displayed yet. It's possible that it was cancelled. Finish this task + if await !self.properties.getIsDisplayed() { + self.markAsFinished() + } else { + (CoreUIObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject) + if self.isCancelled { + await self.dismissAlertView() + } + } } } @@ -89,10 +92,13 @@ public class AlertOperation: MVMCoreOperation { private func dismissAlertView() async { guard await properties.getIsDisplayed() else { return } await withCheckedContinuation { continuation in - Task { @MainActor in - MVMCoreNavigationHandler.shared()?.dismiss(alertController, animated: true, delegate: nil) { - continuation.resume() - } + Task { + let dismissOperation = await NavigationOperation(with: .dismiss(viewController: alertController)) + dismissOperation.queuePriority = .veryHigh + let task = Task(priority: .high) { await NavigationHandler.shared().navigate(with: dismissOperation) } + blockingOperation?.markAsFinished() + _ = await task.result + continuation.resume() } } } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift index 502682c2..910712d5 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/MdnEntryField.swift @@ -144,7 +144,9 @@ import MVMCore picker.displayedPropertyKeys = ["phoneNumbers"] picker.predicateForEnablingContact = NSPredicate(format: "phoneNumbers.@count > 0") picker.predicateForSelectionOfProperty = NSPredicate(format: "key == 'phoneNumbers'") - MVMCoreNavigationHandler.shared()?.present(picker, animated: true) + Task(priority: .userInitiated) { + await NavigationHandler.shared().present(viewController: picker, animated: true) + } } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift index 9e11ac02..4c677029 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/CollapsableNotification.swift @@ -114,7 +114,7 @@ import MVMCore open func performBlockOperation(with block: @escaping (MVMCoreBlockOperation) -> Void) { let operation = MVMCoreBlockOperation(block: block)! - MVMCoreNavigationHandler.shared()?.addNavigationOperation(operation) + NavigationHandler.shared().navigationQueue.addOperation(operation) } /// Collapses after a delay diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift index eb43201a..c613d3a7 100644 --- a/MVMCoreUI/Containers/NavigationController/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -7,9 +7,12 @@ // import UIKit +import MVMCore +import Combine @objcMembers open class NavigationController: UINavigationController, MVMCoreViewManagerViewControllerProtocol { public weak var manager: (UIViewController & MVMCoreViewManagerProtocol)? + private var cancellables: Set = [] /// Getter for the main navigation controller public static func navigationController() -> Self? { @@ -20,9 +23,9 @@ import UIKit public static func setupNavigationController() -> Self? { let navigationController = self.init() MVMCoreUISession.sharedGlobal()?.navigationController = navigationController - MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController - MVMCoreNavigationHandler.shared()?.navigationController = navigationController - MVMCoreNavigationHandler.shared()?.addDelegate(navigationController) + NavigationHandler.shared().viewControllerToPresentOn = navigationController + NavigationHandler.shared().navigationController = navigationController + navigationController.subscribe() navigationController.setNavigationBarUI(with: NavigationItemModel()) return navigationController } @@ -34,14 +37,44 @@ import UIKit return navigationController } - /// Convenience function to return the navigation model of the lowest controller traversing managers if applicable. + /** Subscribes for events. + Updates the navigation item of the new view controller when one is pushed. + Based on ``NavigationItemModelProtocol`` of ``PageProtocol/pageModel``. Traverses the manager for the view controller if necessary. + */ + @MainActor + public func subscribe() { + NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] navigationType in + guard let self = self, + self == navigationType.getNavigationController(), + let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + if let model = getNavigationModel(from: newViewController) { + self.setNavigationItem(with: model, for: viewController) + self.setNavigationBarUI(with: model) + } + self.manager?.willDisplay?(newViewController) + }.store(in: &cancellables) + + NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + guard let self = self, + self == navigationType.getNavigationController(), + let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + self.manager?.displayedViewController?(newViewController) + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + controller.viewControllerReady?(inManager: self) + } + }.store(in: &cancellables) + } + + /// Convenience function to return the navigation model of the view controller. public func getNavigationModel(from viewController: UIViewController) -> NavigationItemModelProtocol? { return (viewController as? PageProtocol)?.pageModel?.navigationBar } /// Verifies the controller is the currently displayed controller. public func isDisplayed(viewController: UIViewController) -> Bool { - guard let topViewController = topViewController, + guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, viewController == MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { return false } @@ -84,8 +117,10 @@ extension NavigationController: MVMCoreViewManagerProtocol { manager?.willDisplay?(viewController) } + /// Updates the navigation item/bar of the current view controller based on the passed in model and view controller. + @MainActor private func updateNavigationView(with model: NavigationItemModelProtocol, for viewController: UIViewController) { - guard let topViewController = topViewController else { return } + guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last else { return } setNavigationItem(with: model, for: topViewController, coordinatingWith: viewController as? PageBehaviorHandlerProtocol) setNavigationBarUI(with: model) @@ -99,34 +134,6 @@ extension NavigationController: MVMCoreViewManagerProtocol { } } -extension NavigationController: MVMCorePresentationDelegateProtocol { - public func navigationController(_ navigationController: UINavigationController, prepareDisplayFor viewController: UIViewController) { - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) - } - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController), - let model = getNavigationModel(from: newViewController) else { return } - setNavigationItem(with: model, for: viewController) - setNavigationBarUI(with: model) - } - - public func navigationController(_ navigationController: UINavigationController, willDisplay viewController: UIViewController) { - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - manager?.willDisplay?(newViewController) - } - - public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - manager?.displayedViewController?(newViewController) - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - controller.viewControllerReady?(inManager: self) - } - } -} - extension UIColor { func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage { return UIGraphicsImageRenderer(size: size).image { rendererContext in diff --git a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift index e1d3a247..5ffe202c 100644 --- a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift +++ b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift @@ -7,6 +7,7 @@ // import Foundation +import MVMCore public extension UINavigationController { @@ -38,7 +39,7 @@ public extension UINavigationController { if model.hidesSystemBackButton, model.alwaysShowBackButton != false { if let backButtonModel = model.backButton, - MVMCoreNavigationHandler.shared()?.getViewControllers(for: self)?.count ?? 0 > 1 || model.alwaysShowBackButton ?? false { + MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).count ?? 0 > 1 || model.alwaysShowBackButton ?? false { leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let leftItemModels = model.additionalLeftButtons { diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index 8b509827..dadd5025 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -20,7 +20,8 @@ public protocol StatusBarUI { // Navigation bar update functions public extension MVMCoreUISplitViewController { - /// Updates the state for various controls (navigation, tab, progress) for the controller. + /// Updates the state for various controls (top navigation controller item, tab, progress) for the controller. + @MainActor func updateState(with viewController: UIViewController) { guard let navigationController = navigationController, navigationController.isDisplayed(viewController: viewController) else { return } @@ -30,7 +31,9 @@ public extension MVMCoreUISplitViewController { } // MARK: - Progress Bar - /// Updates the progress bar based on the page json for the view controller. + /** Updates the progress bar based on the page json for the view controller. + Uses a string value between 0 and 100 from key progressPercent in the MVMCoreViewControllerProtocol.loadObject.pageJSON. + */ func updateProgressBar(for viewController: UIViewController) { guard let viewController = viewController as? MVMCoreViewControllerProtocol else { return } var progress: Float = 0.0 @@ -42,12 +45,16 @@ public extension MVMCoreUISplitViewController { } // MARK: - Tab Bar - /// Updates the tab bar based on the page json for the view controller. + /** Updates the tab bar based on the page json for the view controller. + For the index: checks the view controller's pageModel (``PageProtocol``) property ``TabPageModelProtocol/tabBarIndex``, else tabBarIndex in action map that led to this page, else the previous tab bar index of this page. + For hidden: checks the view controller's pageModel (``PageProtocol``) property ``TabPageModelProtocol/tabBarHidden``, else tabBarHidden in action map that led to this page, else it is visibile. + */ + @MainActor func updateTabBar(for viewController: UIViewController) { let mvmViewController = viewController as? MVMCoreViewControllerProtocol tabBar?.delegateObject = mvmViewController?.delegateObject?() as? MVMCoreUIDelegateObject - let navigationIndex = (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController)?.count ?? 1) - 1 + let navigationIndex = (navigationController != nil ? (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController!).count ?? 1) : 1) - 1 // Set the highlighted index. In terms of priority, Page > Action > Previous. if let index = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarIndex { @@ -80,10 +87,13 @@ public extension MVMCoreUISplitViewController { } // MARK: - Navigation Bar - /// Convenience function. Sets the navigation and split view properties for the view controller. Panel access is determined if view controller is a detail view protocol. + /** Convenience function. Sets the navigation and split view properties for the view controller. + Panel access is determined if view controller is a ``MVMCoreUIDetailViewProtocol`` + */ + @MainActor func setNavigationBar(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) { guard navigationController == self.navigationController, - viewController == getCurrentDetailViewController() else { + self.navigationController?.isDisplayed(viewController: viewController) == true else { /// Not the split view navigation controller, skip split functions. return } @@ -97,9 +107,13 @@ public extension MVMCoreUISplitViewController { setNavigationIconColor(navigationItemModel.tintColor.uiColor) } - /// Sets the left navigation items for the view controller based on model and splitview. + /** Sets the left navigation items for the top view controller based on the model and viewController. + Panel access is determined if view controller is a ``MVMCoreUIDetailViewProtocol`` + */ + @MainActor func setLeftNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let topViewController = navigationController.topViewController else { return } + guard let viewControllers = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController), + let topViewController = viewControllers.last else { return } var leftItems: [UIBarButtonItem] = [] let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject @@ -110,7 +124,7 @@ public extension MVMCoreUISplitViewController { if let forceBackButton = navigationItemModel?.alwaysShowBackButton { showBackButton = forceBackButton } else { - showBackButton = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController)?.count ?? 0 > 1 + showBackButton = viewControllers.count > 1 } if showBackButton { if let backButtonModel = navigationItemModel?.backButton { @@ -144,9 +158,12 @@ public extension MVMCoreUISplitViewController { topViewController.navigationItem.setLeftBarButtonItems(leftItems.count > 0 ? leftItems : nil, animated: !DisableAnimations.boolValue) } - /// Sets the right navigation items for the view controller based on model and splitview. + /** Sets the right navigation items for the top view controller based on the model and viewController. + Panel access is determined if view controller is a ``MVMCoreUIDetailViewProtocol`` + */ + @MainActor func setRightNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let topViewController = navigationController.topViewController else { return } + guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController).last else { return } let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject var rightItems: [UIBarButtonItem] = [] @@ -173,6 +190,9 @@ public extension MVMCoreUISplitViewController { topViewController.navigationItem.setRightBarButtonItems(rightItems.count > 0 ? rightItems : nil, animated: !DisableAnimations.boolValue) } + /** If the current detail view controller has a navigation model. + ``NavigationController/getNavigationModel(from:)`` from ``getCurrentDetailViewController()`` + */ @objc func navigationBarModelExists() -> Bool { // Legacy Navigation guard let currentViewController = getCurrentDetailViewController(), @@ -180,8 +200,9 @@ public extension MVMCoreUISplitViewController { return true } - /// Convenience function to update the navigation bar if the controller is the current lowest controller. - @objc func updateNavigationBarFor(viewController: UIViewController) { + /// Convenience function to update the navigation bar if the controller is the current detail controller. + @MainActor @objc + func updateNavigationBarFor(viewController: UIViewController) { guard let navigationController = navigationController, navigationController.isDisplayed(viewController: viewController), let model = navigationController.getNavigationModel(from: viewController) else { return } @@ -201,9 +222,13 @@ public extension MVMCoreUISplitViewController { return .default } - /// Updates the status bar background color and style. - @objc func setStatusBarForCurrentViewController() { - let viewController = getCurrentViewController() as? MVMCoreUIDetailViewProtocol + /** Updates the status bar background color and style for the passed view controller. + The background color is fetched from ``MVMCoreUIDetailViewProtocol/defaultStatusBarBackgroundColor()``, else the current navigation bar background, else the current status bar background color. + The backgroundStytle is fetched from ``MVMCoreUIDetailViewProtocol/defaultStatusBarStyle()`` else ``getStatusBarStyle(for:)`` + */ + @MainActor + func setStatusBar(for viewController: UIViewController?) { + let viewController = viewController as? MVMCoreUIDetailViewProtocol let backgroundColor = viewController?.defaultStatusBarBackgroundColor?() ?? navigationController?.navigationBar.standardAppearance.backgroundColor ?? statusBarView?.backgroundColor @@ -213,6 +238,14 @@ public extension MVMCoreUISplitViewController { setStatusBarBackgroundColor(backgroundColor, style: style) } + + /** Updates the status bar background color and style for the current view controller. + See ``setStatusBar(for:)`` + */ + @MainActor + @objc func setStatusBarForCurrentViewController() { + setStatusBar(for: getCurrentViewController()) + } } extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index 045dd0bf..c499596a 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -7,7 +7,6 @@ // #import "MVMCoreUISplitViewController.h" -@import MVMCore.MVMCoreNavigationHandler; @import MVMCore.MVMCoreDispatchUtility; @import MVMCore.MVMCoreViewManagerProtocol; @import MVMCore.MVMCoreActionUtility; @@ -1074,7 +1073,7 @@ CGFloat const PanelAnimationDuration = 0.2; // Returns the desired view or falls back. Hot fix until we can get away from using these functions... + (CGRect)getBounds:(UIView *)desiredView { - UIView *view = desiredView ?: [MVMCoreNavigationHandler sharedNavigationHandler].navigationController.view ?: [MVMCoreGetterUtility getKeyWindow].rootViewController.view; + UIView *view = desiredView ?: [self mainSplitViewController].navigationController.view ?: [MVMCoreGetterUtility getKeyWindow].rootViewController.view; return view ? view.bounds : [UIScreen mainScreen].bounds; } diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index db339cf8..c2c01c1b 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -205,7 +205,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } } - public func navigationController(_ navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { // Only percent interact if we've already loaded the view controller guard let customInteractor = customInteractor, let index = index, @@ -272,7 +272,9 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, if let controller = viewControllers[indexPath.row] { // Load controller from the cache needToTrackTabSelect = true - MVMCoreNavigationHandler.shared()?.replaceTopViewController(with: controller, navigationController: subNavigationController, animated: true, delegate: self, replaceInStack: false, completionHandler: nil) + Task(priority: .userInitiated) { + await NavigationHandler.shared().replace(viewController: controller, navigationController: subNavigationController, tryToReplace: false, animated: true) + } } else if let tabsModel = tabs.tabsModel, let action = tabsModel.tabs[indexPath.row].action { // Perform the tab action diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index ff9d90ad..2c367f90 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -268,7 +268,7 @@ public class NotificationOperation: MVMCoreOperation { } })! transitionOperation.completionBlock = completionBlock - MVMCoreNavigationHandler.shared()?.addNavigationOperation(transitionOperation) + NavigationHandler.shared().navigationQueue.addOperation(transitionOperation) return transitionOperation } @@ -314,6 +314,8 @@ open class NotificationHandler { private var transitionDelegate: NotificationTransitionDelegateProtocol + private var cancellable: Cancellable? + // MARK: - Publishers /// Publishes when a notification will show. @@ -354,7 +356,26 @@ open class NotificationHandler { /// Registers to know when pages change. private func registerForPageChanges() { - MVMCoreNavigationHandler.shared()?.addDelegate(self) + cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + // Update displayable for each top alert operation when page type changes, in top queue priority order. + guard let self = self, + self.queue.operations.count > 0, + let navigationController = navigationType.getNavigationController(), + navigationController == MVMCoreUISplitViewController.main()?.navigationController, + let viewController = navigationController.viewControllers.last, + let traversedController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + let pageType = (traversedController as? MVMCoreViewControllerProtocol)?.pageType + Task { + self.queue.operations.compactMap { + $0 as? NotificationOperation + }.sorted { + $0.notificationModel.priority.rawValue > $1.notificationModel.priority.rawValue + }.forEach { + $0.updateDisplayable(by: pageType) + } + self.reevaluteQueue() + } + } } /// Checks for new top alert json @@ -534,26 +555,6 @@ open class NotificationHandler { } } -extension NotificationHandler: MVMCorePresentationDelegateProtocol { - // Update displayable for each top alert operation when page type changes, in top queue priority order. - public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { - guard queue.operations.count > 0 else { return } - let viewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) - guard viewController == MVMCoreUISplitViewController.main()?.getCurrentViewController() else { return } - let pageType = (viewController as? MVMCoreViewControllerProtocol)?.pageType - Task { - queue.operations.compactMap { - $0 as? NotificationOperation - }.sorted { - $0.notificationModel.priority.rawValue > $1.notificationModel.priority.rawValue - }.forEach { - $0.updateDisplayable(by: pageType) - } - reevaluteQueue() - } - } -} - extension NotificationOperation { /// Updates the operation and notification with the new model. public func update(with model: NotificationModel, delegateObject: MVMCoreUIDelegateObject?) { diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.m b/MVMCoreUI/Utility/MVMCoreUIUtility.m index 01a8c435..e99a6383 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.m +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.m @@ -11,7 +11,6 @@ #import "MVMCoreUISession.h" #import "MVMCoreUISplitViewController.h" #import -@import MVMCore.MVMCoreNavigationHandler; @import MVMCore.MVMCoreGetterUtility; @implementation MVMCoreUIUtility From ba8aa92994ed1111adce1723d3185a9f8edbcf02 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 21 Aug 2023 17:03:49 -0400 Subject: [PATCH 03/20] ONEAPP-5208: Swiftify the navigation handler --- .../NavigationController.swift | 20 +++++++++------- .../UINavigationController+Extension.swift | 9 ++++++- ...MCoreUISplitViewController+Extension.swift | 19 +++++++++++---- .../MVMCoreUISplitViewController.m | 23 +++--------------- .../SubNav/SubNavInteractor.swift.swift | 10 ++++++-- .../SubNav/SubNavManagerController.swift | 4 ++-- .../Notification/NotificationHandler.swift | 4 ++-- .../MVMCoreUIActionHandler.swift | 4 +++- .../Utility/MVMCoreUIUtility+Extension.swift | 24 ++++++++++++++++++- MVMCoreUI/Utility/MVMCoreUIUtility.m | 17 ++++--------- 10 files changed, 79 insertions(+), 55 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift index c613d3a7..36be6d45 100644 --- a/MVMCoreUI/Containers/NavigationController/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -43,11 +43,14 @@ import Combine */ @MainActor public func subscribe() { - NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] navigationType in + NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] operation in guard let self = self, - self == navigationType.getNavigationController(), - let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + self == operation.navigationType.getNavigationController(), + let viewController = NavigationHandler.shared().getViewControllers(for: self).last, let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) + } if let model = getNavigationModel(from: newViewController) { self.setNavigationItem(with: model, for: viewController) self.setNavigationBarUI(with: model) @@ -55,10 +58,10 @@ import Combine self.manager?.willDisplay?(newViewController) }.store(in: &cancellables) - NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in guard let self = self, - self == navigationType.getNavigationController(), - let viewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, + self == operation.navigationType.getNavigationController(), + let viewController = NavigationHandler.shared().getViewControllers(for: self).last, let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } self.manager?.displayedViewController?(newViewController) if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { @@ -74,8 +77,7 @@ import Combine /// Verifies the controller is the currently displayed controller. public func isDisplayed(viewController: UIViewController) -> Bool { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last, - viewController == MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { + guard viewController == getViewController() else { return false } return true @@ -120,7 +122,7 @@ extension NavigationController: MVMCoreViewManagerProtocol { /// Updates the navigation item/bar of the current view controller based on the passed in model and view controller. @MainActor private func updateNavigationView(with model: NavigationItemModelProtocol, for viewController: UIViewController) { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).last else { return } + guard let topViewController = NavigationHandler.shared().getViewControllers(for: self).last else { return } setNavigationItem(with: model, for: topViewController, coordinatingWith: viewController as? PageBehaviorHandlerProtocol) setNavigationBarUI(with: model) diff --git a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift index 5ffe202c..625f0a25 100644 --- a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift +++ b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift @@ -39,7 +39,7 @@ public extension UINavigationController { if model.hidesSystemBackButton, model.alwaysShowBackButton != false { if let backButtonModel = model.backButton, - MVMCoreNavigationHandler.shared()?.getViewControllers(for: self).count ?? 0 > 1 || model.alwaysShowBackButton ?? false { + NavigationHandler.shared().getViewControllers(for: self).count > 1 || model.alwaysShowBackButton ?? false { leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let leftItemModels = model.additionalLeftButtons { @@ -114,4 +114,11 @@ public extension UINavigationController { setNavigationBarHidden(model.hidden, animated: true) } + + @MainActor + func getViewController() -> UIViewController? { + guard let topViewController = getViewControllers().last, + let viewController = MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { return nil } + return viewController + } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index dadd5025..20f4449c 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -54,7 +54,7 @@ public extension MVMCoreUISplitViewController { let mvmViewController = viewController as? MVMCoreViewControllerProtocol tabBar?.delegateObject = mvmViewController?.delegateObject?() as? MVMCoreUIDelegateObject - let navigationIndex = (navigationController != nil ? (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController!).count ?? 1) : 1) - 1 + let navigationIndex = (navigationController != nil ? NavigationHandler.shared().getViewControllers(for: navigationController!).count : 1) - 1 // Set the highlighted index. In terms of priority, Page > Action > Previous. if let index = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarIndex { @@ -112,8 +112,8 @@ public extension MVMCoreUISplitViewController { */ @MainActor func setLeftNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let viewControllers = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController), - let topViewController = viewControllers.last else { return } + let viewControllers = NavigationHandler.shared().getViewControllers(for: navigationController) + guard let topViewController = viewControllers.last else { return } var leftItems: [UIBarButtonItem] = [] let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject @@ -163,7 +163,7 @@ public extension MVMCoreUISplitViewController { */ @MainActor func setRightNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - guard let topViewController = MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController).last else { return } + guard let topViewController = NavigationHandler.shared().getViewControllers(for: navigationController).last else { return } let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject var rightItems: [UIBarButtonItem] = [] @@ -268,6 +268,17 @@ extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol { } @objc public extension MVMCoreUISplitViewController { + @objc func goBack() { + Task(priority: .userInitiated) { @MainActor in + if let viewController = getCurrentDetailViewController() as? MVMCoreUIDetailViewProtocol, + let backButtonPressed = viewController.backButtonPressed { + backButtonPressed() + } else { + await NavigationHandler.shared().popTopViewController() + } + } + } + /// Subscribes for notification events. @objc func subscribeForNotifications() { guard cancellables == nil else { return } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index c499596a..c43d17d9 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -191,14 +191,7 @@ CGFloat const PanelAnimationDuration = 0.2; } - (IBAction)backButtonPressed:(id)sender { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - UIViewController *detailViewController = [self getCurrentDetailViewController]; - if ([detailViewController conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)] && [detailViewController respondsToSelector:@selector(backButtonPressed)]) { - [((UIViewController *)detailViewController) backButtonPressed]; - } else { - [[MVMCoreNavigationHandler sharedNavigationHandler] popTopViewControllerAnimated:YES]; - } - }]; + [self goBack]; } - (IBAction)rightPanelButtonPressed:(id)sender { @@ -257,7 +250,7 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; - if (self.navigationController && [MVMCoreNavigationHandler.sharedNavigationHandler getViewControllersForNavigationController:self.navigationController].count > 1) { + if (self.navigationController && [self.navigationController getViewControllers].count > 1) { [leftBarButtonItems addObject:self.backButton]; } if ((accessible && !extended) && self.leftPanelButton) { @@ -1098,17 +1091,7 @@ CGFloat const PanelAnimationDuration = 0.2; } - (UIViewController *)getCurrentVisibleController { - UIViewController *baseViewController = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn ?: [MVMCoreGetterUtility getKeyWindow].rootViewController; - UIViewController *viewController = nil; - while (baseViewController.presentedViewController && !baseViewController.presentedViewController.isBeingDismissed) { - viewController = baseViewController.presentedViewController; - baseViewController = viewController; - } - // if it is not presented viewcontroller, existing BAU logic will be working - if (!viewController) { - viewController = [MVMCoreUIUtility getViewControllerTraversingManagers:self.navigationController.topViewController]; - } - return viewController; + return [MVMCoreUIUtility getCurrentVisibleController]; } - (UIViewController *)getCurrentDetailViewController { diff --git a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift index 233a1f57..eb4dcdda 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift @@ -90,6 +90,8 @@ fileprivate enum SubNavPanningDirection : Int { switch (pan.state) { case .began: + print("sssss \(#function) began") + // Begin the transition to the next page. panning = true if velocityX < 0 && pannableFrameRight.contains(locationInView) { @@ -117,11 +119,15 @@ fileprivate enum SubNavPanningDirection : Int { shouldCompleteTransition = percentage > 0.65; update(percentage) delegate?.update(percentage: percentage) - + print("sssss \(#function) changed \(percentage)") + case .cancelled: cancel() - + print("sssss \(#function) cancelled") + case .ended: + print("sssss \(#function) ended") + if ((percentage < 0) != (velocityX < 0)) && abs(velocityX) > 50 { // If we are moving back toward the previous view we want to cancel. (the speed threshold is for shaky hands) cancel() diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index c2c01c1b..7bdee349 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -229,7 +229,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, hideNavigationBarLine(true) } - public func navigationController(_ navigationController: UINavigationController, willDisplay viewController: UIViewController) { + public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { guard navigationController == subNavigationController else { return } if let viewController = viewController as? UIViewController & MVMCoreViewManagerViewControllerProtocol & MVMCoreViewControllerProtocol { @@ -247,7 +247,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, commitTo(controller: viewController) } - public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { + public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { guard navigationController == subNavigationController else { return } // Need to track swipe action. if needToTrackTabSelect { diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index c031ac77..627d611a 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -356,11 +356,11 @@ open class NotificationHandler { /// Registers to know when pages change. private func registerForPageChanges() { - cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] navigationType in + cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in // Update displayable for each top alert operation when page type changes, in top queue priority order. guard let self = self, self.queue.operations.count > 0, - let navigationController = navigationType.getNavigationController(), + let navigationController = operation.navigationType.getNavigationController(), navigationController == MVMCoreUISplitViewController.main()?.navigationController, let viewController = navigationController.viewControllers.last, let traversedController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift index b2c3d42c..49a3d5e9 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift @@ -57,6 +57,8 @@ import SafariServices @MainActor open func openURL(inSafariWebView url: URL) { let safariViewController = SFSafariViewController(url: url) - MVMCoreNavigationHandler.shared()?.present(safariViewController, animated: true) + Task(priority: .high) { + await NavigationHandler.shared().present(viewController: safariViewController) + } } } diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift index ffb74ef9..e04de6bb 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift +++ b/MVMCoreUI/Utility/MVMCoreUIUtility+Extension.swift @@ -7,7 +7,7 @@ // import UIKit - +import MVMCore public extension MVMCoreUIUtility { @@ -66,3 +66,25 @@ public extension MVMCoreUIUtility { return nil } } + +@objc +public extension MVMCoreUIUtility { + @objc @MainActor + static func getVisibleViewController() -> UIViewController? { + var viewController = NavigationHandler.shared().getViewControllerToPresentOn() + while let presentedController = viewController?.presentedViewController, + !presentedController.isBeingDismissed { + viewController = presentedController + } + if let navigationController = viewController as? UINavigationController { + viewController = navigationController.topViewController + } + if let viewController = viewController { + return getViewControllerTraversingManagers(viewController) + } else if let viewController = MVMCoreUISession.sharedGlobal()?.navigationController?.topViewController { + return getViewControllerTraversingManagers(viewController) + } else { + return nil + } + } +} diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.m b/MVMCoreUI/Utility/MVMCoreUIUtility.m index e99a6383..ad7366df 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.m +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.m @@ -51,19 +51,10 @@ } + (UIViewController *)getCurrentVisibleController { - UIViewController *baseViewController = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn ?: [MVMCoreGetterUtility getKeyWindow].rootViewController; - UIViewController *viewController = nil; - while (baseViewController.presentedViewController && !baseViewController.presentedViewController.isBeingDismissed) { - viewController = baseViewController.presentedViewController; - baseViewController = viewController; - } - if ([viewController isKindOfClass:[UINavigationController class]]) { - viewController = ((UINavigationController *)viewController).topViewController; - } - // if it is not presented viewcontroller, existing BAU logic will be working - if (!viewController) { - viewController = [self getViewControllerTraversingManagers:[MVMCoreUISession sharedGlobal].navigationController.topViewController]; - } + __block UIViewController *viewController = nil; + [MVMCoreDispatchUtility performSyncBlockOnMainThread:^{ + viewController = [self getVisibleViewController]; + }]; return viewController; } From 07fcca17fc269044fc849f40510b90fdd64ded9d Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 21 Aug 2023 17:20:27 -0400 Subject: [PATCH 04/20] Remove debug comments --- MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift index eb4dcdda..233a1f57 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavInteractor.swift.swift @@ -90,8 +90,6 @@ fileprivate enum SubNavPanningDirection : Int { switch (pan.state) { case .began: - print("sssss \(#function) began") - // Begin the transition to the next page. panning = true if velocityX < 0 && pannableFrameRight.contains(locationInView) { @@ -119,15 +117,11 @@ fileprivate enum SubNavPanningDirection : Int { shouldCompleteTransition = percentage > 0.65; update(percentage) delegate?.update(percentage: percentage) - print("sssss \(#function) changed \(percentage)") - + case .cancelled: cancel() - print("sssss \(#function) cancelled") - + case .ended: - print("sssss \(#function) ended") - if ((percentage < 0) != (velocityX < 0)) && abs(velocityX) > 50 { // If we are moving back toward the previous view we want to cancel. (the speed threshold is for shaky hands) cancel() From caab123781f92eeb958514c19308bf88922ce7e4 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 21 Aug 2023 18:03:05 -0400 Subject: [PATCH 05/20] update check for notification handler --- MVMCoreUI/Notification/NotificationHandler.swift | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index 627d611a..8971bd5a 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -357,15 +357,14 @@ open class NotificationHandler { /// Registers to know when pages change. private func registerForPageChanges() { cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in - // Update displayable for each top alert operation when page type changes, in top queue priority order. - guard let self = self, - self.queue.operations.count > 0, - let navigationController = operation.navigationType.getNavigationController(), - navigationController == MVMCoreUISplitViewController.main()?.navigationController, - let viewController = navigationController.viewControllers.last, - let traversedController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - let pageType = (traversedController as? MVMCoreViewControllerProtocol)?.pageType + guard let self = self else { return } Task { + // Update displayable for each top alert operation when page type changes, in top queue priority order. + guard self.queue.operations.count > 0, + let navigationController = await operation.navigationType.getNavigationController(), + await navigationController == MVMCoreUISplitViewController.main()?.navigationController, + let viewController = await navigationController.getViewController() else { return } + let pageType = (viewController as? MVMCoreViewControllerProtocol)?.pageType self.queue.operations.compactMap { $0 as? NotificationOperation }.sorted { From e8fcf1ac5ddc5f6961223d9dbd1f0ce068beb707 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 28 Aug 2023 11:13:40 -0400 Subject: [PATCH 06/20] ONEAPP-5208: Review feedback --- .../NavigationController.swift | 36 +++++++++---------- .../Notification/NotificationHandler.swift | 4 ++- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift index 36be6d45..8f72a792 100644 --- a/MVMCoreUI/Containers/NavigationController/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -43,29 +43,27 @@ import Combine */ @MainActor public func subscribe() { - NavigationHandler.shared().onNavigationWillBegin.sink { [weak self] operation in + NavigationHandler.shared().onNavigation.sink { [weak self] (event, operation) in guard let self = self, self == operation.navigationType.getNavigationController(), let viewController = NavigationHandler.shared().getViewControllers(for: self).last, let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) - } - if let model = getNavigationModel(from: newViewController) { - self.setNavigationItem(with: model, for: viewController) - self.setNavigationBarUI(with: model) - } - self.manager?.willDisplay?(newViewController) - }.store(in: &cancellables) - - NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in - guard let self = self, - self == operation.navigationType.getNavigationController(), - let viewController = NavigationHandler.shared().getViewControllers(for: self).last, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - self.manager?.displayedViewController?(newViewController) - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - controller.viewControllerReady?(inManager: self) + switch event { + case .willNavigate: + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) + } + if let model = getNavigationModel(from: newViewController) { + self.setNavigationItem(with: model, for: viewController) + self.setNavigationBarUI(with: model) + } + self.manager?.willDisplay?(newViewController) + case .didNavigate: + self.manager?.displayedViewController?(newViewController) + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + controller.viewControllerReady?(inManager: self) + } + @unknown default: break } }.store(in: &cancellables) } diff --git a/MVMCoreUI/Notification/NotificationHandler.swift b/MVMCoreUI/Notification/NotificationHandler.swift index 8971bd5a..9ecc2efb 100644 --- a/MVMCoreUI/Notification/NotificationHandler.swift +++ b/MVMCoreUI/Notification/NotificationHandler.swift @@ -356,7 +356,9 @@ open class NotificationHandler { /// Registers to know when pages change. private func registerForPageChanges() { - cancellable = NavigationHandler.shared().onNavigationDidFinish.sink { [weak self] operation in + cancellable = NavigationHandler.shared().onNavigation + .filter({ $0.0 == .didNavigate }) + .sink { [weak self] (event, operation) in guard let self = self else { return } Task { // Update displayable for each top alert operation when page type changes, in top queue priority order. From 0e68df5624f056ab3401d77ac699a8588e15fa93 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 30 Aug 2023 15:58:21 -0500 Subject: [PATCH 07/20] fixed refactor bug Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index c87e091c..41d68493 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -37,8 +37,11 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ padding = viewModel.padding aspectRatio = viewModel.aspectRatio width = viewModel.width - textWidth = viewModel.textWidth - textPercentage = viewModel.textPercentage + if let value = viewModel.textWidth { + textWidth = .value(value) + } else if let percentage = viewModel.textPercentage { + textWidth = .percentage(percentage) + } titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData) subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData) badgeModel = viewModel.badge From 7da47bb77a1bfeb97e1fcfb748e21acfde40eadf Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Tue, 5 Sep 2023 21:02:24 -0400 Subject: [PATCH 08/20] Add an optional ID field to every molecule. --- .../Atomic/Atoms/Buttons/ButtonModel.swift | 5 ++++ .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 4 +++ .../Atoms/Buttons/ImageButtonModel.swift | 4 ++- .../Atomic/Atoms/Buttons/Link/LinkModel.swift | 4 +++ .../Atoms/FormFields/Tags/TagModel.swift | 3 ++ .../Atoms/FormFields/Tags/TagsModel.swift | 5 ++++ .../TextFields/EntryFieldModel.swift | 4 +++ .../Atoms/Selectors/CheckboxModel.swift | 2 ++ .../Atomic/Atoms/Selectors/HeartModel.swift | 5 ++++ .../Atoms/Selectors/RadioBoxModel.swift | 6 ++++ .../Atoms/Selectors/RadioBoxesModel.swift | 3 ++ .../Atoms/Selectors/RadioButtonModel.swift | 5 ++++ .../Atoms/Selectors/RadioSwatchModel.swift | 5 ++++ .../Atoms/Selectors/RadioSwatchesModel.swift | 5 ++++ .../Atomic/Atoms/Selectors/ToggleModel.swift | 6 ++++ MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift | 7 +++-- .../Atomic/Atoms/Views/CaretViewModel.swift | 2 ++ .../CarouselIndicatorModel.swift | 2 ++ .../Atoms/Views/CheckboxLabelModel.swift | 2 ++ .../Atomic/Atoms/Views/DashLineModel.swift | 6 ++++ .../Atomic/Atoms/Views/ImageViewModel.swift | 2 ++ .../Atomic/Atoms/Views/Label/LabelModel.swift | 7 +++-- .../Atoms/Views/LeftRightLabelModel.swift | 2 ++ MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 6 ++++ .../Atoms/Views/LoadingSpinnerModel.swift | 8 +++-- .../Atoms/Views/MultiProgressModel.swift | 6 ++++ .../Atomic/Atoms/Views/ProgressBarModel.swift | 5 ++++ MVMCoreUI/Atomic/Atoms/Views/StarModel.swift | 5 ++++ MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift | 4 +++ .../Atomic/Atoms/Views/TileletModel.swift | 1 + .../Atomic/Atoms/Views/Video/VideoModel.swift | 2 ++ .../Atomic/Atoms/Views/WebViewModel.swift | 5 ++++ MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift | 6 ++++ .../LockUps/LockUpsPlanNamesModel.swift | 5 ++++ .../LockUps/LockupsPlanSMLXLModel.swift | 5 ++++ .../LockUps/TitleLockupModel.swift | 4 +++ .../Doughnut/DoughnutChartItemModel.swift | 4 ++- .../Doughnut/DoughnutChartModel.swift | 4 ++- .../ImageHeadlineBodyModel.swift | 2 ++ .../RadioButtonLabelModel.swift | 2 ++ .../TabBarModel.swift | 5 ++++ .../TabsModel.swift | 5 ++++ .../TwoButtonViewModel.swift | 1 + .../TwoLinkViewModel.swift | 5 ++++ .../ActionDetailWithImageModel.swift | 2 ++ .../LeftRightViews/CornerLabelsModel.swift | 1 + .../HeadlineBodyLinkToggleModel.swift | 1 + .../HeadlineBodyToggleModel.swift | 1 + .../ToggleMolecules/LabelToggleModel.swift | 5 ++++ .../Buttons/NavigationImageButtonModel.swift | 6 +++- .../Buttons/NavigationLabelButtonModel.swift | 7 ++++- .../NavigationBar/NavigationItemModel.swift | 4 +++ .../OtherContainers/ModuleMoleculeModel.swift | 8 ++++- .../NotificationXButtonModel.swift | 6 ++++ .../EyebrowHeadlineBodyLinkModel.swift | 4 +++ .../HeadlineBodyButtonModel.swift | 5 ++++ .../HeadlineBodyCaretLinkImageModel.swift | 1 + .../HeadlineBodyLinkModel.swift | 2 ++ .../HeadlineBodyModel.swift | 14 +++++++++ .../StringAndMoleculeModel.swift | 5 ++++ .../ThreeHeadlineBodyLinkModel.swift | 5 ++++ .../Organisms/Carousel/CarouselModel.swift | 5 ++++ .../MoleculeModelProtocol.swift | 10 +++---- .../ParentMoleculeModelProtocol.swift | 30 ++++++++++++++----- .../TemplateModelProtocol.swift | 2 +- .../MoleculeTreeTraversalProtocol.swift | 11 +++++-- .../Containers/Views/ContainerModel.swift | 7 +++++ 67 files changed, 300 insertions(+), 28 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index 8818107b..b3c23e87 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -18,6 +18,8 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat //-------------------------------------------------- //Making static property as class property so that subclasses can override getter function of the property open class var identifier: String { "button" } + public var id: String = { return UUID().uuidString }() + public var accessibilityIdentifier: String? public var accessibilityText: String? public var title: String @@ -174,6 +176,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -201,6 +204,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat 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 accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) title = try typeContainer.decode(String.self, forKey: .title) @@ -263,6 +267,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(title, forKey: .title) try container.encode(enabled, forKey: .enabled) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 71431d0f..399219cb 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -16,6 +16,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea //-------------------------------------------------- public static var identifier: String = "caretLink" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var accessibilityIdentifier: String? public var title: String @@ -41,6 +42,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case backgroundColor case accessibilityIdentifier case title @@ -61,6 +63,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) @@ -94,6 +97,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(title, forKey: .title) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift index 560027f3..df24270d 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift @@ -14,8 +14,9 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro //-------------------------------------------------- public static var identifier: String = "imageButton" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? - public var image: ImageViewModel? public var accessibilityText: String? @@ -34,6 +35,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro } private enum CodingKeys: String, CodingKey { + case id case moleculeName case image case backgroundColor diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index 38bcb491..5b290d6e 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -15,6 +15,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode //-------------------------------------------------- public class var identifier: String { "link" } + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -48,6 +49,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -91,6 +93,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) @@ -137,6 +140,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(title, forKey: .title) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift index 823d2478..d7148baa 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift @@ -11,11 +11,14 @@ import MVMCore @objcMembers public class TagModel: MoleculeModelProtocol { public static var identifier: String = "tag" + public var id: String = { return UUID().uuidString }() + public var label: LabelModel public var action: ActionModelProtocol? public var backgroundColor: Color? private enum CodingKeys: String, CodingKey { + case id case moleculeName case label case action diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift index 6330bb94..24adcc43 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift @@ -11,10 +11,13 @@ import MVMCore @objcMembers public class TagsModel: MoleculeModelProtocol { public static var identifier: String = "tags" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var tags: [TagModel] private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case tags @@ -30,12 +33,14 @@ import MVMCore 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 tags = try typeContainer.decode([TagModel].self, forKey: .tags) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tags, forKey: .tags) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 7b3eee03..92ad5c53 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -16,6 +16,7 @@ import Foundation //-------------------------------------------------- public class var identifier: String { "" } + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -63,6 +64,7 @@ import Foundation //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -138,6 +140,7 @@ import Foundation 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decodeIfPresent(String.self, forKey: .title) @@ -166,6 +169,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 7b6b36d8..6f30282e 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -20,6 +20,7 @@ //-------------------------------------------------- public static var identifier: String = "checkbox" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var accessibilityIdentifier: String? public var selected: Bool = false @@ -51,6 +52,7 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case accessibilityIdentifier case checked diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index 4be1343a..7580e6e0 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -14,6 +14,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- public static var identifier: String = "heart" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var isActive: Bool = false @@ -27,6 +29,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -49,6 +52,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { 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 + if let isActive = try typeContainer.decodeIfPresent(Bool.self, forKey: .isActive) { self.isActive = isActive } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift index 27defd48..cf592ecb 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBox" + public var id: String = { return UUID().uuidString }() + public var text: String public var subText: String? public var backgroundColor: Color? @@ -30,6 +32,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case text case subText @@ -58,6 +61,8 @@ import MVMCore 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) subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText) selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) @@ -81,6 +86,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(text, forKey: .text) try container.encodeIfPresent(subText, forKey: .subText) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift index 6348eac5..f4f538d6 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBoxes" + public var id: String = { return UUID().uuidString }() + public var boxes: [RadioBoxModel] public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -49,6 +51,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case enabled case readOnly diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift index 86eb36e9..497a0b1c 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift @@ -15,6 +15,8 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "radioButton" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var state: Bool = false @@ -35,6 +37,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -80,6 +83,8 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { 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 + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { self.state = state } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift index f0a194e9..1f47abc4 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatch" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var color: Color = Color(uiColor: .mvmBlue) @@ -29,6 +31,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -54,6 +57,7 @@ import MVMCore 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) @@ -79,6 +83,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index d5d3992a..9a154167 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatches" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var swatches: [RadioSwatchModel] @@ -43,6 +45,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -67,6 +70,7 @@ import MVMCore 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches) @@ -81,6 +85,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift index e8d50851..3973f0bc 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift @@ -13,6 +13,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "toggle" + public var id: String = { return UUID().uuidString }() + public var accessibilityIdentifier: String? public var backgroundColor: Color? public var selected: Bool = false @@ -36,6 +38,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case state case animated @@ -86,6 +89,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { 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 + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { self.selected = state } @@ -128,6 +133,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encodeModelIfPresent(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift index 388f1669..05b54373 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift @@ -17,8 +17,9 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { public static var identifier: String { return "arrow" } - public var moleculeName: String? + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var disabledColor: Color = Color(uiColor: .mvmCoolGray3) public var color: Color = Color(uiColor: .mvmBlack) @@ -57,6 +58,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case disabledColor @@ -75,7 +77,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { @@ -113,6 +115,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(disabledColor, forKey: .disabledColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index 1e2595ec..a5ebc86d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -15,6 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "caretView" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var strokeColor: Color = Color(uiColor: .mvmBlack) public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) @@ -28,6 +29,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case strokeColor diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index 164bb306..d1d762c1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -18,6 +18,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro return "" } + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var moleculeName: String? public var numberOfPages: Int = 0 @@ -44,6 +45,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case currentIndex diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift index 58f398b6..11252461 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift @@ -18,6 +18,8 @@ public enum CheckboxPosition: String, Codable { @objcMembers open class CheckboxLabelModel: MoleculeModelProtocol { open class var identifier: String { "checkboxLabel" } public var moleculeName: String = CheckboxLabelModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var checkboxAlignment: CheckboxPosition? public var checkbox: CheckboxModel diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift index 95cc40fd..30864afc 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift @@ -15,6 +15,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "dashLine" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var dashColor: Color = Color(uiColor: .mvmCoolGray3) @@ -35,6 +37,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -56,6 +59,8 @@ import MVMCore 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 + if let dashColor = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor) { self.dashColor = dashColor } @@ -74,6 +79,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(dashColor, forKey: .dashColor) try container.encode(isHidden, forKey: .isHidden) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift index c61739a7..4c37a2d8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift @@ -13,6 +13,7 @@ //-------------------------------------------------- open class var identifier: String { "image" } + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var moleculeName: String = ImageViewModel.identifier @@ -45,6 +46,7 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case image diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift index 76b534a5..19284756 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift @@ -7,13 +7,14 @@ // -@objcMembers open class LabelModel: MoleculeModelProtocol, Identifiable { +@objcMembers open class LabelModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- open class var identifier: String { "label" } public var id: String + public var backgroundColor: Color? public var text: String public var accessibilityText: String? @@ -35,8 +36,8 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case id + case moleculeName case text case accessibilityText case textColor @@ -110,7 +111,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(id, forKey: .id) try container.encode(text, forKey: .text) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift index 07c534f8..1574567a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift @@ -15,6 +15,8 @@ import UIKit public static var identifier: String = "leftRightLabelView" public var moleculeName: String = LeftRightLabelModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var leftText: LabelModel public var rightText: LabelModel? diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index cc9e7333..4850ac21 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -53,6 +53,8 @@ import VDSColorTokens //-------------------------------------------------- public static var identifier: String = "line" + public var id: String = { return UUID().uuidString }() + public var type: Style = .secondary public var frequency: Frequency? = .allExceptTop @@ -120,6 +122,7 @@ import VDSColorTokens //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case type case backgroundColor @@ -138,6 +141,8 @@ import VDSColorTokens 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 + if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) { self.type = type } @@ -158,6 +163,7 @@ import VDSColorTokens public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encode(type, forKey: .type) try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) diff --git a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift index ddfba326..064d6c38 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift @@ -13,9 +13,10 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - public var backgroundColor: Color? public static var identifier: String = "loadingSpinner" + public var id: String = { return UUID().uuidString }() + + public var backgroundColor: Color? public var strokeColor = Color(uiColor: .mvmBlack) public var lineWidth: CGFloat = 4 public var diameter: CGFloat = 40 @@ -25,6 +26,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case strokeColor @@ -45,6 +47,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) if let diameter = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .diameter) { @@ -62,6 +65,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(diameter, forKey: .diameter) diff --git a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift index fb70ffd0..cadee43d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift @@ -19,13 +19,17 @@ import Foundation } @objcMembers public class MultiProgressBarModel: MoleculeModelProtocol { + public static var identifier: String = "multiProgressBar" + public var id: String = { return UUID().uuidString }() + public var progressList: [SingleProgressBarModel] public var backgroundColor: Color? public var thickness: CGFloat? public var roundedCorners: Bool? private enum CodingKeys: String, CodingKey { + case id case moleculeName case progressList case thickness @@ -39,6 +43,7 @@ import Foundation 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 progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) @@ -47,6 +52,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(progressList, forKey: .progressList) try container.encodeIfPresent(thickness, forKey: .thickness) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift index 7cef8936..fd24858e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift @@ -10,6 +10,8 @@ import Foundation @objcMembers public class ProgressBarModel: MoleculeModelProtocol { public static var identifier: String = "progressBar" + public var id: String = { return UUID().uuidString }() + @Percent public var percent: CGFloat public var color: Color = Color(uiColor: .mfCerulean()) public var backgroundColor: Color? = Color(uiColor: .mfLightSilver()) @@ -17,6 +19,7 @@ import Foundation public var thickness: CGFloat? private enum CodingKeys: String, CodingKey { + case id case moleculeName case roundedCorners case thickness @@ -31,6 +34,7 @@ import Foundation 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 percent = try typeContainer.decode(CGFloat.self, forKey: .percent) if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { self.color = color @@ -44,6 +48,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(percent, forKey: .percent) try container.encode(color, forKey: .color) diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift index 56f4f7ad..520425f7 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift @@ -13,6 +13,8 @@ open class StarModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "star" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? @Percent public var percent: CGFloat = 0 public var borderColor: Color? @@ -23,6 +25,7 @@ open class StarModel: MoleculeModelProtocol { // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case percent @@ -43,6 +46,7 @@ open class StarModel: MoleculeModelProtocol { 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 if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) { self.percent = percent } @@ -56,6 +60,7 @@ open class StarModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(percent, forKey: .percent) diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift index f79f638e..a2d04d66 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift @@ -13,6 +13,8 @@ import MVMCore // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "stars" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var starBackgroundColor: Color? public var stars: [StarModel] @@ -25,6 +27,7 @@ import MVMCore // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case starBackgroundColor @@ -48,6 +51,7 @@ import MVMCore //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + stars = try typeContainer.decode([StarModel].self, forKey: .stars) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index 620e0940..a7e09cb2 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -15,6 +15,7 @@ open class TileletModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "tilelet" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var color: TileContainer.BackgroundColor public var padding: TileContainer.Padding diff --git a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift index 7c348760..b34cc7aa 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift @@ -10,6 +10,7 @@ import Foundation open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { public static var identifier = "video" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var video: String public var showControls = false @@ -43,6 +44,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { private var resignActiveListener: Any? private enum CodingKeys: String, CodingKey { + case id case moleculeName case video case showControls diff --git a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift index 4cb2bd55..e953e2ab 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift @@ -12,6 +12,8 @@ import MVMCore @objcMembers public class WebViewModel: MoleculeModelProtocol { public static var identifier: String = "webview" public var moleculeName: String = WebViewModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var url: URL? public var htmlString: String? @@ -23,6 +25,7 @@ import MVMCore } private enum CodingKeys: String, CodingKey{ + case id case moleculeName case backgroundColor case url @@ -39,6 +42,7 @@ import MVMCore 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) url = try typeContainer.decodeIfPresent(URL.self, forKey: .url) htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString) @@ -51,6 +55,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(url, forKey: .url) diff --git a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift index 85e4fffb..32284277 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift @@ -19,6 +19,8 @@ public enum GraphStyle: String, Codable { public class WheelModel: MoleculeModelProtocol { public static var identifier: String = "wheel" + public var id: String = { return UUID().uuidString }() + public var style: GraphStyle = .unlimited { didSet { updateStyle() @@ -43,6 +45,7 @@ public class WheelModel: MoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case style case size case diameter @@ -56,6 +59,8 @@ public class WheelModel: MoleculeModelProtocol { 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 + if let style = try typeContainer.decodeIfPresent(GraphStyle.self, forKey: .style) { self.style = style } @@ -84,6 +89,7 @@ public class WheelModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(style, forKey: .style) try container.encode(size, forKey: .size) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift index 0d68da42..5a172208 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift @@ -13,6 +13,8 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "planNamesLockup" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var headline: LabelModel public var subHeadline: LabelModel @@ -31,6 +33,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headline @@ -43,6 +46,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { //-------------------------------------------------- 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headline = try typeContainer.decode(LabelModel.self, forKey: .headline) subHeadline = try typeContainer.decode(LabelModel.self, forKey: .subHeadline) @@ -51,6 +55,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headline, forKey: .headline) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift index 433bc322..ee684645 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift @@ -14,6 +14,8 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "planLockup" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var planLabel : LabelModel public var headline : LabelModel @@ -43,6 +45,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case planLabel @@ -57,6 +60,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) planLabel = try typeContainer.decode(LabelModel.self, forKey: .planLabel) headline = try typeContainer.decode(LabelModel.self, forKey: .headline) @@ -67,6 +71,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(planLabel, forKey: .planLabel) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift index 4548207d..9e55db1b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift @@ -16,6 +16,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco public static var identifier: String = "titleLockup" public var moleculeName: String = TitleLockupModel.identifier + public var id: String = { return UUID().uuidString }() public var eyebrow: LabelModel? public var title: LabelModel @@ -130,6 +131,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case eyebrow @@ -145,6 +147,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco 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 title = try typeContainer.decodeMolecule(codingKey: .title) eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) subTitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subTitle) @@ -164,6 +167,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(eyebrow, forKey: .eyebrow) try container.encodeModel(title, forKey: .title) diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift index ee4e664a..187fc8a5 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift @@ -14,9 +14,11 @@ import Foundation // MARK: - Properties //-------------------------------------------------- - public var backgroundColor: Color? public static var identifier: String = "doughnutChartItem" public var moleculeName: String = DoughnutChartItemModel.identifier + public var id: String = { return UUID().uuidString }() + + public var backgroundColor: Color? public var label: LabelModel @Percent public var percent: CGFloat public var color: Color diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift index fbb034c6..07d7756f 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift @@ -14,9 +14,11 @@ import Foundation // MARK: - Properties //-------------------------------------------------- - public var backgroundColor: Color? public static var identifier: String = "doughnutChart" public var moleculeName: String = DoughnutChartModel.identifier + public var id: String = { return UUID().uuidString }() + + public var backgroundColor: Color? public var title: LabelModel? public var subtitle: LabelModel? public var sections: [DoughnutChartItemModel] diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift index 2c188d6b..08fe6db3 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift @@ -15,6 +15,8 @@ public class ImageHeadlineBodyModel: MoleculeModelProtocol { public static var identifier: String = "imageHeadlineBody" public var moleculeName: String = ImageHeadlineBodyModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var image: ImageViewModel public var headlineBody: HeadlineBodyModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index 69bca3fc..ea574220 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -15,6 +15,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioButtonLabel" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var moleculeName: String = RadioButtonLabelModel.identifier public var radioButton: RadioButtonModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index 3b62210c..a40d303f 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -11,6 +11,8 @@ import VDSColorTokens open class TabBarModel: MoleculeModelProtocol { public static var identifier: String = "tabBar" + public var id: String = { return UUID().uuidString }() + open var tabs: [TabBarItemModel] private var _backgroundColor: Color? @@ -58,6 +60,7 @@ open class TabBarModel: MoleculeModelProtocol { open var selectedTab: Int = 0 private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case tabs @@ -73,6 +76,7 @@ open class TabBarModel: MoleculeModelProtocol { 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 tabs = try typeContainer.decode([TabBarItemModel].self, forKey: .tabs) if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { backgroundColor = color @@ -93,6 +97,7 @@ open class TabBarModel: MoleculeModelProtocol { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tabs, forKey: .tabs) try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift index 6e154895..e938c119 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift @@ -11,6 +11,8 @@ import VDSColorTokens open class TabsModel: MoleculeModelProtocol { public static var identifier: String = "tabs" + public var id: String = { return UUID().uuidString }() + open var tabs: [TabItemModel] open var style: NavigationItemStyle? @@ -71,6 +73,7 @@ open class TabsModel: MoleculeModelProtocol { open var selectedIndex: Int = 0 private enum CodingKeys: String, CodingKey { + case id case moleculeName case tabs case backgroundColor @@ -87,6 +90,7 @@ open class TabsModel: MoleculeModelProtocol { 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 tabs = try typeContainer.decode([TabItemModel].self, forKey: .tabs) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) _selectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) @@ -100,6 +104,7 @@ open class TabsModel: MoleculeModelProtocol { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tabs, forKey: .tabs) try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 718cfc30..3f7eeba8 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -15,6 +15,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "twoButtonView" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift index 57962c09..089e1160 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift @@ -10,11 +10,14 @@ import Foundation public class TwoLinkViewModel: MoleculeModelProtocol { public static var identifier: String = "twoLinkView" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var rightLink: LinkModel? public var leftLink: LinkModel? private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case rightLink @@ -28,6 +31,7 @@ public class TwoLinkViewModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) rightLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .rightLink) leftLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .leftLink) @@ -35,6 +39,7 @@ public class TwoLinkViewModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(rightLink, forKey: .rightLink) diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift index 7c8bd202..cb237b05 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift @@ -11,6 +11,8 @@ import Foundation public class ActionDetailWithImageModel: MoleculeModelProtocol { public static var identifier: String = "actionDetailWithImage" public var moleculeName: String = ActionDetailWithImageModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var headlineBodyButton: HeadlineBodyButtonModel public var image: ImageViewModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift index aabd29e7..88a42067 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -11,6 +11,7 @@ import MVMCore public class CornerLabelsModel: ParentMoleculeModelProtocol { public static var identifier: String = "cornerLabels" + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var topLeftLabel: LabelModel? public var topRightLabel: LabelModel? diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift index 19c1f4d6..15d9c78c 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift @@ -10,6 +10,7 @@ import Foundation public class HeadlineBodyLinkToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLinkToggle" public var moleculeName: String = HeadlineBodyLinkToggleModel.identifier + public var id: String = { return UUID().uuidString }() public var backgroundColor: Color? public var headlineBodyLink: HeadlineBodyLinkModel public var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift index 800c976b..fffd53f7 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift @@ -12,6 +12,7 @@ import Foundation open class HeadlineBodyToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyToggle" public var moleculeName: String = HeadlineBodyToggleModel.identifier + public var id: String = { return UUID().uuidString }() open var backgroundColor: Color? open var headlineBody: HeadlineBodyModel open var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift index ee0c5f78..845296dd 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift @@ -12,6 +12,8 @@ import MVMCore public class LabelToggleModel: MoleculeModelProtocol { public static var identifier: String = "labelToggle" public var moleculeName: String = LabelToggleModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var label: LabelModel public var toggle: ToggleModel @@ -22,6 +24,7 @@ public class LabelToggleModel: MoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case label @@ -30,6 +33,7 @@ public class LabelToggleModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey:.backgroundColor) label = try typeContainer.decode(LabelModel.self, forKey:.label) toggle = try typeContainer.decode(ToggleModel.self, forKey:.toggle) @@ -38,6 +42,7 @@ public class LabelToggleModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(label, forKey: .label) try container.encode(toggle, forKey: .toggle) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index f0b0bbc0..0c702899 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -13,9 +13,11 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule // MARK: - Properties //-------------------------------------------------- + public static var identifier: String = "navigationImageButton" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var accessibilityIdentifier: String? - public static var identifier: String = "navigationImageButton" public var image: String public var action: ActionModelProtocol public var accessibilityText: String? @@ -35,6 +37,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case image case action case accessibilityIdentifier @@ -60,6 +63,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(image, forKey: .image) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encode(moleculeName, forKey: .moleculeName) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift index d72c6ae0..f8152d20 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -12,8 +12,10 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo // MARK: - Properties //-------------------------------------------------- - open var backgroundColor: Color? open class var identifier: String { "navigationLabelButton" } + public var id: String = { return UUID().uuidString }() + + open var backgroundColor: Color? open var accessibilityIdentifier: String? open var title: String open var action: ActionModelProtocol @@ -32,6 +34,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case accessibilityIdentifier case title @@ -44,6 +47,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo 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 accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action) @@ -51,6 +55,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encode(title, forKey: .title) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 64b61480..025e9dd4 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -19,6 +19,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc //-------------------------------------------------- open class var identifier: String { "navigationBar" } + public var id: String = { return UUID().uuidString }() private let defaultHidesSystemBackButton = true @@ -74,6 +75,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case title case hidden @@ -96,6 +98,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc 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 title = try typeContainer.decodeIfPresent(String.self, forKey: .title) if let hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) { self.hidden = hidden @@ -122,6 +125,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(title, forKey: .title) try container.encode(hidden, forKey: .hidden) diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift index 931e7c04..0c499c1b 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift @@ -9,11 +9,15 @@ import Foundation open class ModuleMoleculeModel: MoleculeModelProtocol { - public var backgroundColor: Color? + public static var identifier: String = "moduleMolecule" + public var id: String = { return UUID().uuidString }() + + public var backgroundColor: Color? public var moduleName: String private enum CodingKeys: String, CodingKey { + case id case moduleName } @@ -23,11 +27,13 @@ open class ModuleMoleculeModel: MoleculeModelProtocol { 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 moduleName = try typeContainer.decode(String.self, forKey:.moduleName) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moduleName, forKey: .moduleName) } } diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift index 71324dff..02f55d83 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift @@ -10,12 +10,16 @@ import Foundation import MVMCore public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtocol { + public static var identifier: String = "notificationXButton" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var color: Color? public var action: ActionModelProtocol = ActionNoopModel() private enum CodingKeys: String, CodingKey { + case id case moleculeName case color case action @@ -28,6 +32,7 @@ public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtoco public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) { self.action = action @@ -36,6 +41,7 @@ public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtoco public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(color, forKey: .color) try container.encodeModel(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 83f5b4bd..56378b13 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -13,6 +13,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule //-------------------------------------------------- public static var identifier: String = "eyebrowHeadlineBodyLink" + public var id: String = { return UUID().uuidString }() public var moleculeName: String = EyebrowHeadlineBodyLinkModel.identifier public var backgroundColor: Color? public var eyebrow: LabelModel? @@ -56,6 +57,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case eyebrow @@ -70,6 +72,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline) @@ -84,6 +87,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(eyebrow, forKey: .eyebrow) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift index 70a08d3b..346d7ce3 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift @@ -14,6 +14,8 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyButton" public var moleculeName: String = HeadlineBodyButtonModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var headlineBody: HeadlineBodyModel @@ -45,6 +47,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headlineBody @@ -58,6 +61,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody) button = try typeContainer.decode(ButtonModel.self, forKey: .button) @@ -67,6 +71,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headlineBody, forKey: .headlineBody) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift index 5d7752fe..452947ba 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift @@ -61,6 +61,7 @@ public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProto //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headlineBody diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift index 9f16e3ce..edca0398 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift @@ -16,6 +16,8 @@ public class HeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLink" public var moleculeName: String = HeadlineBodyLinkModel.identifier + public var id: String = { return UUID().uuidString }() + public var headlineBody: HeadlineBodyModel public var link: LinkModel public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 20df223a..3cb6d28e 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -14,8 +14,10 @@ public static var identifier: String = "headlineBody" public var moleculeName: String = HeadlineBodyModel.identifier + public var id: String = { return UUID().uuidString }() public var headline: LabelModel? public var body: LabelModel? + public var another: LabelToggle? public var style: Style? public var backgroundColor: Color? @@ -23,6 +25,15 @@ [headline, body].compactMap { $0 } } + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { + return [ + \HeadlineBodyModel.headline, + \HeadlineBodyModel.body, + ].contains { + replaceChildMolecule(on: self, keyPath: $0, replacementMolecule: replacementMolecule) + } + } + //-------------------------------------------------- // MARK: - Enum //-------------------------------------------------- @@ -57,6 +68,7 @@ //----------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case headline case body @@ -66,6 +78,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 headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline) body = try typeContainer.decodeMoleculeIfPresent(codingKey: .body) style = try typeContainer.decodeIfPresent(Style.self, forKey: .style) @@ -74,6 +87,7 @@ public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(headline, forKey: .headline) try container.encodeIfPresent(body, forKey: .body) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift index b1b12a54..808a1469 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift @@ -13,6 +13,8 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "stringAndMoleculeModel" + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var string: String public var molecule: MoleculeModelProtocol @@ -33,6 +35,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case string @@ -46,6 +49,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) string = try typeContainer.decode(String.self, forKey: .string) molecule = try typeContainer.decodeModel(codingKey: .molecule) @@ -54,6 +58,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(string, forKey: .string) try container.encodeModel(molecule, forKey: .molecule) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift index efdc058c..564834ac 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift @@ -16,6 +16,8 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "threeHeadlineBodyLink" public var moleculeName: String = ThreeHeadlineBodyLinkModel.identifier + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var headline1: LabelModel @@ -41,6 +43,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headline1 @@ -56,6 +59,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headline1 = try typeContainer.decode(LabelModel.self, forKey: .headline1) headline2 = try typeContainer.decode(LabelModel.self, forKey: .headline2) @@ -67,6 +71,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headline1, forKey: .headline1) try container.encode(headline2, forKey: .headline2) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift index bc3877e5..0521aebd 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift @@ -19,6 +19,8 @@ import UIKit return "carousel" } + public var id: String = { return UUID().uuidString }() + public var backgroundColor: Color? public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] public var index: Int = 0 @@ -78,6 +80,7 @@ import UIKit //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case molecules @@ -108,6 +111,7 @@ import UIKit 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 molecules = try typeContainer.decodeModels(codingKey: .molecules) index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0 selectable = try typeContainer.decodeIfPresent(Bool.self, forKey: .selectable) ?? false @@ -144,6 +148,7 @@ import UIKit public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModels(molecules, forKey: .molecules) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift index 6845d44b..31adc6ef 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift @@ -5,10 +5,10 @@ public enum MolecularError: Swift.Error { case countImbalance(String) } - public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol, MoleculeMaskingProtocol { var moleculeName: String { get } var backgroundColor: Color? { get set } + var id: String { get } } public extension MoleculeModelProtocol { @@ -20,7 +20,6 @@ public extension MoleculeModelProtocol { static var categoryCodingKey: String { "moleculeName" } } - // Helpers made due to swift not able to reconcile which category. extension KeyedDecodingContainer where Key: CodingKey { /// Decodes to a registered molecule based on the identifier @@ -53,8 +52,9 @@ public extension MoleculeModelProtocol { } // Base case. No additional children to traverse. - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { - onVisit(depth, self) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) { + var stop = false + onVisit(depth, self, &stop) } } @@ -67,7 +67,7 @@ public extension Array where Element == MoleculeModelProtocol { } } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) { forEach { (molecule) in molecule.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit) } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift index 2ec05db4..5f2905aa 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift @@ -8,10 +8,11 @@ import Foundation -public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol { +public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol, AnyObject { var children: [MoleculeModelProtocol] { get } + func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool } public extension ParentMoleculeModelProtocol { @@ -35,21 +36,36 @@ public extension ParentMoleculeModelProtocol { return result } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) { + var stop = false if (options == .parentFirst) { - onVisit(depth, self) + onVisit(depth, self, &stop) + guard !stop else { return } } - children.forEach { (molecule) in - if let additionalParent = molecule as? ParentMoleculeModelProtocol { + for child in children { + if let additionalParent = child 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) + child.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) } + guard !stop else { return } } if (options == .childFirst) { - onVisit(depth, self) + onVisit(depth, self, &stop) } // if options == .leafOnly don't call on self. } + + /// Top level test to replace child molecules. Each parent molecule should attempt to replace. + func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool { return false } + + /// Helper function for replacing molecules on a path. + func replaceChildMolecule(on target: P, keyPath: ReferenceWritableKeyPath, replacementMolecule: MoleculeModelProtocol) -> Bool { + if let currentMolecule = target[keyPath: keyPath], currentMolecule.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { + target[keyPath: keyPath] = newHeadline + return true + } + return false + } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index 531a48d1..2cd233b0 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -30,7 +30,7 @@ public extension TemplateModelProtocol { return rootMolecules.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: initialResult, nextPartialResult: nextPartialResult) } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol) -> Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) { return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit) } } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift index d10a2d19..a2da7cf4 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift @@ -19,7 +19,7 @@ public protocol MoleculeTreeTraversalProtocol { func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) //func breadthFirstTraverse() } @@ -37,7 +37,7 @@ public extension MoleculeTreeTraversalProtocol { } func printMolecules(options: TreeTraversalOptions = .parentFirst) { - depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in + depthFirstTraverse(options: options, depth: 1) { depth, molecule, stop in print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]") } } @@ -50,4 +50,11 @@ public extension MoleculeTreeTraversalProtocol { return accumulator } } + + func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) { + depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in + guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return } + stop = parentMolecule.replaceChildMolecule(with: replacementMolecule) + } + } } diff --git a/MVMCoreUI/Containers/Views/ContainerModel.swift b/MVMCoreUI/Containers/Views/ContainerModel.swift index 731e9c95..c99cb5fd 100644 --- a/MVMCoreUI/Containers/Views/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/ContainerModel.swift @@ -13,6 +13,8 @@ open class ContainerModel: ContainerModelProtocol, Codable { // MARK: - Properties //-------------------------------------------------- + public var id: String = { return UUID().uuidString }() + public var horizontalAlignment: UIStackView.Alignment? public var useHorizontalMargins: Bool? public var leftPadding: CGFloat? @@ -30,6 +32,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case horizontalAlignment case useHorizontalMargins case leftPadding @@ -74,6 +77,9 @@ open class ContainerModel: ContainerModelProtocol, Codable { 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 + if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) { verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString) } @@ -92,6 +98,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: verticalAlignment), forKey: .verticalAlignment) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment) try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins) From 94defaa6bce5c265a989512eab1c5cb7333e964b Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Thu, 7 Sep 2023 08:34:28 -0400 Subject: [PATCH 09/20] Remove test code. --- .../Molecules/VerticalCombinationViews/HeadlineBodyModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 3cb6d28e..ecdeed40 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -17,7 +17,6 @@ public var id: String = { return UUID().uuidString }() public var headline: LabelModel? public var body: LabelModel? - public var another: LabelToggle? public var style: Style? public var backgroundColor: Color? From b6c3159b526568d57c3478ee97ca8a898328d424 Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Thu, 7 Sep 2023 09:20:44 -0400 Subject: [PATCH 10/20] Change ID default initializer, DecodableDefault for implicit decoding models. Add missing id encodes and decodes. --- MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift | 2 +- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift | 5 ++++- MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift | 3 ++- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift | 3 ++- MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift | 2 +- .../Atomic/Atoms/Selectors/RadioSwatchesModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift | 5 ++++- .../Views/CarouselIndicator/CarouselIndicatorModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/StarModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift | 5 ++++- MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift | 4 +++- MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift | 2 +- .../LockUps/LockUpsPlanNamesModel.swift | 2 +- .../LockUps/LockupsPlanSMLXLModel.swift | 2 +- .../DesignedComponents/LockUps/TitleLockupModel.swift | 2 +- .../Molecules/Doughnut/DoughnutChartItemModel.swift | 2 +- .../Atomic/Molecules/Doughnut/DoughnutChartModel.swift | 2 +- .../ImageHeadlineBodyModel.swift | 2 +- .../RadioButtonLabelModel.swift | 2 +- .../HorizontalCombinationViews/TabBarModel.swift | 2 +- .../Molecules/HorizontalCombinationViews/TabsModel.swift | 2 +- .../HorizontalCombinationViews/TwoButtonViewModel.swift | 5 ++++- .../HorizontalCombinationViews/TwoLinkViewModel.swift | 2 +- .../LeftRightViews/ActionDetailWithImageModel.swift | 2 +- .../Molecules/LeftRightViews/CornerLabelsModel.swift | 5 ++++- .../ToggleMolecules/HeadlineBodyLinkToggleModel.swift | 2 +- .../ToggleMolecules/HeadlineBodyToggleModel.swift | 2 +- .../ToggleMolecules/LabelToggleModel.swift | 2 +- .../Buttons/NavigationImageButtonModel.swift | 3 ++- .../Buttons/NavigationLabelButtonModel.swift | 2 +- .../Molecules/NavigationBar/NavigationItemModel.swift | 2 +- .../Molecules/OtherContainers/ModuleMoleculeModel.swift | 2 +- .../TopNotification/NotificationXButtonModel.swift | 2 +- .../EyebrowHeadlineBodyLinkModel.swift | 2 +- .../HeadlineBodyButtonModel.swift | 2 +- .../VerticalCombinationViews/HeadlineBodyLinkModel.swift | 2 +- .../VerticalCombinationViews/HeadlineBodyModel.swift | 2 +- .../StringAndMoleculeStack/StringAndMoleculeModel.swift | 2 +- .../ThreeHeadlineBodyLinkModel.swift | 2 +- MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift | 2 +- MVMCoreUI/Atomic/Organisms/StackModel.swift | 9 +++++++++ .../ModelProtocols/ParentMoleculeModelProtocol.swift | 8 ++++++++ MVMCoreUI/Containers/Views/ContainerModel.swift | 2 +- 63 files changed, 108 insertions(+), 61 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index b3c23e87..08afefde 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -18,7 +18,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat //-------------------------------------------------- //Making static property as class property so that subclasses can override getter function of the property open class var identifier: String { "button" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var accessibilityIdentifier: String? public var accessibilityText: String? diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 399219cb..3a5429e1 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -16,7 +16,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea //-------------------------------------------------- public static var identifier: String = "caretLink" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? public var title: String diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift index df24270d..a61ec150 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift @@ -14,7 +14,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro //-------------------------------------------------- public static var identifier: String = "imageButton" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var image: ImageViewModel? @@ -54,6 +54,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) image = try typeContainer.decodeIfPresent(ImageViewModel.self, forKey: .image) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) @@ -79,6 +80,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(image, forKey: .image) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index 5b290d6e..62ba0422 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -15,7 +15,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode //-------------------------------------------------- public class var identifier: String { "link" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift index d7148baa..40cb98b7 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift @@ -11,7 +11,7 @@ import MVMCore @objcMembers public class TagModel: MoleculeModelProtocol { public static var identifier: String = "tag" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var label: LabelModel public var action: ActionModelProtocol? @@ -41,6 +41,7 @@ import MVMCore 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 label = try typeContainer.decode(LabelModel.self, forKey: .label) action = try typeContainer.decodeModelIfPresent(codingKey: .action) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -48,6 +49,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(label, forKey: .label) try container.encodeModelIfPresent(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift index 24adcc43..22ce1d9a 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift @@ -11,7 +11,7 @@ import MVMCore @objcMembers public class TagsModel: MoleculeModelProtocol { public static var identifier: String = "tags" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var tags: [TagModel] diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 92ad5c53..6f58cf64 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -16,7 +16,7 @@ import Foundation //-------------------------------------------------- public class var identifier: String { "" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 6f30282e..604a8a8d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -20,7 +20,7 @@ //-------------------------------------------------- public static var identifier: String = "checkbox" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? public var selected: Bool = false @@ -109,6 +109,8 @@ 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 + accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { @@ -182,6 +184,7 @@ public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index 7580e6e0..cb301e22 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -14,7 +14,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- public static var identifier: String = "heart" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -80,6 +80,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(isActive, forKey: .isActive) try container.encode(activeColor, forKey: .activeColor) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift index cf592ecb..acec6e83 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift @@ -13,7 +13,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBox" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var text: String public var subText: String? diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift index f4f538d6..f1c652f7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift @@ -13,7 +13,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBoxes" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var boxes: [RadioBoxModel] public var backgroundColor: Color? @@ -78,6 +78,7 @@ import MVMCore 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 selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) @@ -94,6 +95,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(boxes, forKey: .boxes) try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift index 497a0b1c..99b5cdb7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift @@ -15,7 +15,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "radioButton" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -110,6 +110,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(state, forKey: .state) try container.encode(enabled, forKey: .enabled) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift index 1f47abc4..91f13b48 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift @@ -13,7 +13,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatch" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index 9a154167..f424593b 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -13,7 +13,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatches" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift index 3973f0bc..429a5769 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift @@ -13,7 +13,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "toggle" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var accessibilityIdentifier: String? public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift index 05b54373..7697143e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift @@ -18,7 +18,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { return "arrow" } public var moleculeName: String? - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var disabledColor: Color = Color(uiColor: .mvmCoolGray3) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index a5ebc86d..380328d5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -15,7 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "caretView" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var strokeColor: Color = Color(uiColor: .mvmBlack) public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) @@ -53,6 +53,8 @@ import MVMCore 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 + if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) { self.strokeColor = strokeColor } @@ -80,6 +82,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index d1d762c1..f5c0adeb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -18,7 +18,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro return "" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var moleculeName: String? public var numberOfPages: Int = 0 @@ -68,6 +68,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro 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 moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -114,6 +115,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(numberOfPages, forKey: .numberOfPages) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift index 11252461..f5a65103 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift @@ -18,7 +18,7 @@ public enum CheckboxPosition: String, Codable { @objcMembers open class CheckboxLabelModel: MoleculeModelProtocol { open class var identifier: String { "checkboxLabel" } public var moleculeName: String = CheckboxLabelModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var checkboxAlignment: CheckboxPosition? diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift index 30864afc..8e533fde 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift @@ -15,7 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "dashLine" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift index 4c37a2d8..7f8fa7b6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift @@ -13,7 +13,7 @@ //-------------------------------------------------- open class var identifier: String { "image" } - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var moleculeName: String = ImageViewModel.identifier diff --git a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift index 1574567a..91aef2a9 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift @@ -15,7 +15,7 @@ import UIKit public static var identifier: String = "leftRightLabelView" public var moleculeName: String = LeftRightLabelModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var leftText: LabelModel diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 4850ac21..3b4c57e9 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -53,7 +53,7 @@ import VDSColorTokens //-------------------------------------------------- public static var identifier: String = "line" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var type: Style = .secondary public var frequency: Frequency? = .allExceptTop diff --git a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift index 064d6c38..b74807fb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift @@ -14,7 +14,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "loadingSpinner" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var strokeColor = Color(uiColor: .mvmBlack) diff --git a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift index cadee43d..d664afa6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift @@ -21,7 +21,7 @@ import Foundation @objcMembers public class MultiProgressBarModel: MoleculeModelProtocol { public static var identifier: String = "multiProgressBar" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var progressList: [SingleProgressBarModel] public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift index fd24858e..439fad3d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift @@ -10,7 +10,7 @@ import Foundation @objcMembers public class ProgressBarModel: MoleculeModelProtocol { public static var identifier: String = "progressBar" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString @Percent public var percent: CGFloat public var color: Color = Color(uiColor: .mfCerulean()) diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift index 520425f7..7b427cde 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift @@ -13,7 +13,7 @@ open class StarModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "star" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? @Percent public var percent: CGFloat = 0 diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift index a2d04d66..10e6400a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift @@ -13,7 +13,7 @@ import MVMCore // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "stars" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var starBackgroundColor: Color? @@ -52,6 +52,7 @@ import MVMCore 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 stars = try typeContainer.decode([StarModel].self, forKey: .stars) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor) @@ -67,6 +68,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(stars, forKey: .stars) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index a7e09cb2..b41d9eef 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -15,7 +15,7 @@ open class TileletModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "tilelet" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var color: TileContainer.BackgroundColor public var padding: TileContainer.Padding @@ -31,6 +31,7 @@ open class TileletModel: MoleculeModelProtocol { public var action: ActionModelProtocol? private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case color @@ -48,6 +49,7 @@ open class TileletModel: MoleculeModelProtocol { } required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString 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 @@ -87,6 +89,7 @@ open class TileletModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(color, forKey: .color) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift index b34cc7aa..27567926 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift @@ -10,7 +10,7 @@ import Foundation open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { public static var identifier = "video" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var video: String public var showControls = false @@ -59,6 +59,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { 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 video = try typeContainer.decode(String.self, forKey:.video) if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) { self.showControls = showControls @@ -74,6 +75,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(video, forKey: .video) try container.encode(showControls, forKey: .showControls) diff --git a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift index e953e2ab..28d619a8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift @@ -12,7 +12,7 @@ import MVMCore @objcMembers public class WebViewModel: MoleculeModelProtocol { public static var identifier: String = "webview" public var moleculeName: String = WebViewModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var url: URL? diff --git a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift index 32284277..4fed14cb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift @@ -19,7 +19,7 @@ public enum GraphStyle: String, Codable { public class WheelModel: MoleculeModelProtocol { public static var identifier: String = "wheel" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var style: GraphStyle = .unlimited { didSet { diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift index 5a172208..acbf276d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift @@ -13,7 +13,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "planNamesLockup" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var headline: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift index ee684645..3e1c1bcc 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift @@ -14,7 +14,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "planLockup" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var planLabel : LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift index 9e55db1b..89d32ca9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift @@ -16,7 +16,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco public static var identifier: String = "titleLockup" public var moleculeName: String = TitleLockupModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var eyebrow: LabelModel? public var title: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift index 187fc8a5..ce2e4fac 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift @@ -16,7 +16,7 @@ import Foundation public static var identifier: String = "doughnutChartItem" public var moleculeName: String = DoughnutChartItemModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var label: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift index 07d7756f..4dbcb4bb 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift @@ -16,7 +16,7 @@ import Foundation public static var identifier: String = "doughnutChart" public var moleculeName: String = DoughnutChartModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var title: LabelModel? diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift index 08fe6db3..04aeb0fa 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift @@ -15,7 +15,7 @@ public class ImageHeadlineBodyModel: MoleculeModelProtocol { public static var identifier: String = "imageHeadlineBody" public var moleculeName: String = ImageHeadlineBodyModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var image: ImageViewModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index ea574220..7839bcdc 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -15,7 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioButtonLabel" - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var moleculeName: String = RadioButtonLabelModel.identifier diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index a40d303f..b984a9da 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -11,7 +11,7 @@ import VDSColorTokens open class TabBarModel: MoleculeModelProtocol { public static var identifier: String = "tabBar" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString open var tabs: [TabBarItemModel] diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift index e938c119..3671e5e1 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift @@ -11,7 +11,7 @@ import VDSColorTokens open class TabsModel: MoleculeModelProtocol { public static var identifier: String = "tabs" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString open var tabs: [TabItemModel] diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 3f7eeba8..b5d07c4a 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -15,7 +15,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "twoButtonView" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? @@ -29,6 +29,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case primaryButton @@ -50,6 +51,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) //set context value for 'primary' style to be set for the primaryButton in case the @@ -67,6 +69,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(primaryButton, forKey: .primaryButton) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift index 089e1160..c9ae177b 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift @@ -10,7 +10,7 @@ import Foundation public class TwoLinkViewModel: MoleculeModelProtocol { public static var identifier: String = "twoLinkView" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var rightLink: LinkModel? diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift index cb237b05..99ef07fd 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift @@ -11,7 +11,7 @@ import Foundation public class ActionDetailWithImageModel: MoleculeModelProtocol { public static var identifier: String = "actionDetailWithImage" public var moleculeName: String = ActionDetailWithImageModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var headlineBodyButton: HeadlineBodyButtonModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift index 88a42067..dc8f2396 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -11,7 +11,7 @@ import MVMCore public class CornerLabelsModel: ParentMoleculeModelProtocol { public static var identifier: String = "cornerLabels" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var topLeftLabel: LabelModel? public var topRightLabel: LabelModel? @@ -27,6 +27,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case backgroundColor case topLeftLabel case topRightLabel @@ -38,6 +39,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { 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 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) molecule = try typeContainer.decodeModelIfPresent(codingKey: .molecule) topLeftLabel = try typeContainer.decodeMoleculeIfPresent(codingKey: .topLeftLabel) @@ -48,6 +50,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModelIfPresent(molecule, forKey: .molecule) try container.encodeModelIfPresent(topLeftLabel, forKey: .topLeftLabel) diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift index 15d9c78c..0783d542 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift @@ -10,7 +10,7 @@ import Foundation public class HeadlineBodyLinkToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLinkToggle" public var moleculeName: String = HeadlineBodyLinkToggleModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var backgroundColor: Color? public var headlineBodyLink: HeadlineBodyLinkModel public var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift index fffd53f7..419097aa 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift @@ -12,7 +12,7 @@ import Foundation open class HeadlineBodyToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyToggle" public var moleculeName: String = HeadlineBodyToggleModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String open var backgroundColor: Color? open var headlineBody: HeadlineBodyModel open var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift index 845296dd..fe8cc16a 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift @@ -12,7 +12,7 @@ import MVMCore public class LabelToggleModel: MoleculeModelProtocol { public static var identifier: String = "labelToggle" public var moleculeName: String = LabelToggleModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var label: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index 0c702899..ab1c993e 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -14,7 +14,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule //-------------------------------------------------- public static var identifier: String = "navigationImageButton" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -52,6 +52,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule 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 accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) image = try typeContainer.decode(String.self, forKey: .image) action = try typeContainer.decodeModel(codingKey: .action) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift index f8152d20..33529e77 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -13,7 +13,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo //-------------------------------------------------- open class var identifier: String { "navigationLabelButton" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString open var backgroundColor: Color? open var accessibilityIdentifier: String? diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 025e9dd4..d39cdeaf 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -19,7 +19,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc //-------------------------------------------------- open class var identifier: String { "navigationBar" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString private let defaultHidesSystemBackButton = true diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift index 0c499c1b..b34922db 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift @@ -11,7 +11,7 @@ import Foundation open class ModuleMoleculeModel: MoleculeModelProtocol { public static var identifier: String = "moduleMolecule" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var moduleName: String diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift index 02f55d83..ac1c8905 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift @@ -12,7 +12,7 @@ import MVMCore public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public static var identifier: String = "notificationXButton" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var color: Color? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 56378b13..0d46916e 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -13,7 +13,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule //-------------------------------------------------- public static var identifier: String = "eyebrowHeadlineBodyLink" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var moleculeName: String = EyebrowHeadlineBodyLinkModel.identifier public var backgroundColor: Color? public var eyebrow: LabelModel? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift index 346d7ce3..1b713720 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift @@ -14,7 +14,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyButton" public var moleculeName: String = HeadlineBodyButtonModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift index edca0398..a715f7f7 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift @@ -16,7 +16,7 @@ public class HeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLink" public var moleculeName: String = HeadlineBodyLinkModel.identifier - public var id: String = { return UUID().uuidString }() + @DecodableDefault.UUID public var id: String public var headlineBody: HeadlineBodyModel public var link: LinkModel diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index ecdeed40..a3eaf918 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -14,7 +14,7 @@ public static var identifier: String = "headlineBody" public var moleculeName: String = HeadlineBodyModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var headline: LabelModel? public var body: LabelModel? public var style: Style? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift index 808a1469..8ffc24e4 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift @@ -13,7 +13,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "stringAndMoleculeModel" - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var string: String diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift index 564834ac..8f413429 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift @@ -16,7 +16,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "threeHeadlineBodyLink" public var moleculeName: String = ThreeHeadlineBodyLinkModel.identifier - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift index 0521aebd..5bfd8d0f 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift @@ -19,7 +19,7 @@ import UIKit return "carousel" } - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var backgroundColor: Color? public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] diff --git a/MVMCoreUI/Atomic/Organisms/StackModel.swift b/MVMCoreUI/Atomic/Organisms/StackModel.swift index 6310fcea..da6c067e 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModel.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModel.swift @@ -25,6 +25,15 @@ return molecules } + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { + guard let replacementMolecule = replacementMolecule as? StackItemModelProtocol & MoleculeModelProtocol else { return false } + guard let matchingIndex = molecules.firstIndex(where: { molecule in + molecule.id == replacementMolecule.id + }) else { return false } + molecules[matchingIndex] = replacementMolecule + return true + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift index 5f2905aa..78377a25 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift @@ -68,4 +68,12 @@ public extension ParentMoleculeModelProtocol { } return false } + + func replaceChildMolecule(on target: P, keyPath: ReferenceWritableKeyPath, replacementMolecule: MoleculeModelProtocol) -> Bool { + if target[keyPath: keyPath].id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { + target[keyPath: keyPath] = newHeadline + return true + } + return false + } } diff --git a/MVMCoreUI/Containers/Views/ContainerModel.swift b/MVMCoreUI/Containers/Views/ContainerModel.swift index c99cb5fd..b54590dd 100644 --- a/MVMCoreUI/Containers/Views/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/ContainerModel.swift @@ -13,7 +13,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { // MARK: - Properties //-------------------------------------------------- - public var id: String = { return UUID().uuidString }() + public var id: String = UUID().uuidString public var horizontalAlignment: UIStackView.Alignment? public var useHorizontalMargins: Bool? From 0e300ca5a75d007f19706b5126081482d82b281a Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Thu, 7 Sep 2023 12:46:05 -0400 Subject: [PATCH 11/20] DecodableDefault.UUID -> UUIDString --- MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift | 2 +- MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift | 2 +- .../Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift | 2 +- MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift | 2 +- .../HorizontalCombinationViews/ImageHeadlineBodyModel.swift | 2 +- .../HorizontalCombinationViews/RadioButtonLabelModel.swift | 2 +- .../Molecules/LeftRightViews/ActionDetailWithImageModel.swift | 2 +- .../ToggleMolecules/HeadlineBodyLinkToggleModel.swift | 2 +- .../ToggleMolecules/HeadlineBodyToggleModel.swift | 2 +- .../VerticalCombinationViews/HeadlineBodyLinkModel.swift | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift index f5a65103..ca0acd79 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift @@ -18,7 +18,7 @@ public enum CheckboxPosition: String, Codable { @objcMembers open class CheckboxLabelModel: MoleculeModelProtocol { open class var identifier: String { "checkboxLabel" } public var moleculeName: String = CheckboxLabelModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var checkboxAlignment: CheckboxPosition? diff --git a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift index 7f8fa7b6..5079fc93 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift @@ -13,7 +13,7 @@ //-------------------------------------------------- open class var identifier: String { "image" } - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var moleculeName: String = ImageViewModel.identifier diff --git a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift index 91aef2a9..2f442dc8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift @@ -15,7 +15,7 @@ import UIKit public static var identifier: String = "leftRightLabelView" public var moleculeName: String = LeftRightLabelModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var leftText: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift index ce2e4fac..7ac68d0a 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift @@ -16,7 +16,7 @@ import Foundation public static var identifier: String = "doughnutChartItem" public var moleculeName: String = DoughnutChartItemModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var label: LabelModel diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift index 4dbcb4bb..3333ae77 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift @@ -16,7 +16,7 @@ import Foundation public static var identifier: String = "doughnutChart" public var moleculeName: String = DoughnutChartModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var title: LabelModel? diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift index 04aeb0fa..84518c8c 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift @@ -15,7 +15,7 @@ public class ImageHeadlineBodyModel: MoleculeModelProtocol { public static var identifier: String = "imageHeadlineBody" public var moleculeName: String = ImageHeadlineBodyModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var image: ImageViewModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index 7839bcdc..571848dc 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -15,7 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioButtonLabel" - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var moleculeName: String = RadioButtonLabelModel.identifier diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift index 99ef07fd..2e7b7500 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift @@ -11,7 +11,7 @@ import Foundation public class ActionDetailWithImageModel: MoleculeModelProtocol { public static var identifier: String = "actionDetailWithImage" public var moleculeName: String = ActionDetailWithImageModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var headlineBodyButton: HeadlineBodyButtonModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift index 0783d542..84a03adf 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift @@ -10,7 +10,7 @@ import Foundation public class HeadlineBodyLinkToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLinkToggle" public var moleculeName: String = HeadlineBodyLinkToggleModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var headlineBodyLink: HeadlineBodyLinkModel public var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift index 419097aa..4c86ed76 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift @@ -12,7 +12,7 @@ import Foundation open class HeadlineBodyToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyToggle" public var moleculeName: String = HeadlineBodyToggleModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String open var backgroundColor: Color? open var headlineBody: HeadlineBodyModel open var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift index a715f7f7..6c2113bf 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift @@ -16,7 +16,7 @@ public class HeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLink" public var moleculeName: String = HeadlineBodyLinkModel.identifier - @DecodableDefault.UUID public var id: String + @DecodableDefault.UUIDString public var id: String public var headlineBody: HeadlineBodyModel public var link: LinkModel From b19d009cffe571773db231e64faecac65f3a60b9 Mon Sep 17 00:00:00 2001 From: "Hedden, Kyle Matthew" Date: Thu, 7 Sep 2023 13:07:49 -0400 Subject: [PATCH 12/20] unnecessary coding key --- .../HeadlineBodyCaretLinkImageModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift index 452947ba..5d7752fe 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyCaretLinkImageModel.swift @@ -61,7 +61,6 @@ public class HeadlineBodyCaretLinkImageModel: ContainerModel, MoleculeModelProto //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case id case moleculeName case backgroundColor case headlineBody From 9a191d9516b2d13364b163a636f509e8d67bde86 Mon Sep 17 00:00:00 2001 From: Sumanth Nadigadda Date: Fri, 15 Sep 2023 11:22:48 +0530 Subject: [PATCH 13/20] defect: Passing subNavManager's delegate to NavigationHandler, so that the delegate can update the viewcontroller for the tab updates --- MVMCoreUI/Managers/SubNav/SubNavManagerController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 7bdee349..458c0169 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -273,7 +273,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, // Load controller from the cache needToTrackTabSelect = true Task(priority: .userInitiated) { - await NavigationHandler.shared().replace(viewController: controller, navigationController: subNavigationController, tryToReplace: false, animated: true) + await NavigationHandler.shared().replace(viewController: controller, navigationController:subNavigationController, delegateObject:delegateObject(), tryToReplace: false, animated: true) } } else if let tabsModel = tabs.tabsModel, let action = tabsModel.tabs[indexPath.row].action { From 1e12517c555078320f257b2f16af4066083760f3 Mon Sep 17 00:00:00 2001 From: Sourabh Bhardwaj Date: Mon, 25 Sep 2023 19:38:01 +0530 Subject: [PATCH 14/20] Fixed headline body component's accessbility label issue --- .../List/OneColumn/ListOneColumnFullWidthTextBodyText.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyText.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyText.swift index 7a17dd1b..f9cfcc95 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyText.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/OneColumn/ListOneColumnFullWidthTextBodyText.swift @@ -55,11 +55,11 @@ import Foundation isAccessibilityElement = true var message = "" - if let headlineLabel = headlineBody.headlineLabel.text { + if let headlineLabel = headlineBody.headlineLabel.accessibilityLabel ?? headlineBody.headlineLabel.text { message += headlineLabel + ", " } - if let messageLabel = headlineBody.messageLabel.text { + if let messageLabel = headlineBody.messageLabel.accessibilityLabel ?? headlineBody.messageLabel.text { message += messageLabel } From ab50921e88fbb95d0a0f1f57d71b0e7d4e444612 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 27 Sep 2023 15:34:49 -0500 Subject: [PATCH 15/20] added color extension for isDark Signed-off-by: Matt Bruce --- MVMCoreUI/Categories/UIColor+MFConvenience.h | 4 ++++ MVMCoreUI/Categories/UIColor+MFConvenience.m | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.h b/MVMCoreUI/Categories/UIColor+MFConvenience.h index 97280ba1..2bb81cd8 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.h +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.h @@ -187,4 +187,8 @@ + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color; + (nonnull UIColor *)mfGetColorForHexWithTransparency:(nonnull NSString *)hexString; + +// Returns if the color is dark or not +- (BOOL)isDark; + @end diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index 8786df01..c185e7bb 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -403,4 +403,10 @@ } } +- (BOOL)isDark { + CGFloat greyScale = 0; + [self getWhite:&greyScale alpha:nil]; + return greyScale < 0.5; +} + @end From f98c6059b8b2a307c699429b759d55d62a0502cd Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 27 Sep 2023 15:53:53 -0500 Subject: [PATCH 16/20] rearranged Signed-off-by: Matt Bruce --- MVMCoreUI/Categories/UIColor+MFConvenience.h | 6 +++--- MVMCoreUI/Categories/UIColor+MFConvenience.m | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.h b/MVMCoreUI/Categories/UIColor+MFConvenience.h index 2bb81cd8..10e9433d 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.h +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.h @@ -183,12 +183,12 @@ // Returns a gradient lighter color; + (nonnull UIColor *)mfGradientColor:(nullable UIColor *)color; +// Returns if the color is dark or not +- (BOOL)isDark; + #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color; + (nonnull UIColor *)mfGetColorForHexWithTransparency:(nonnull NSString *)hexString; -// Returns if the color is dark or not -- (BOOL)isDark; - @end diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index c185e7bb..ac25ec22 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -389,6 +389,12 @@ return [UIColor whiteColor]; } +- (BOOL)isDark { + CGFloat greyScale = 0; + [self getWhite:&greyScale alpha:nil]; + return greyScale < 0.5; +} + #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color { @@ -403,10 +409,4 @@ } } -- (BOOL)isDark { - CGFloat greyScale = 0; - [self getWhite:&greyScale alpha:nil]; - return greyScale < 0.5; -} - @end From a19bd60f063d0a939ebb9c96dd80784bb0e8c6ea Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 27 Sep 2023 15:56:53 -0500 Subject: [PATCH 17/20] indented Signed-off-by: Matt Bruce --- MVMCoreUI/Categories/UIColor+MFConvenience.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index ac25ec22..cd809509 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -390,9 +390,9 @@ } - (BOOL)isDark { - CGFloat greyScale = 0; - [self getWhite:&greyScale alpha:nil]; - return greyScale < 0.5; + CGFloat greyScale = 0; + [self getWhite:&greyScale alpha:nil]; + return greyScale < 0.5; } #pragma mark - Hex String From ab9d61fd156873c6fcc0225c88b9c9ffc57dca5b Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 28 Sep 2023 09:25:50 -0400 Subject: [PATCH 18/20] Link Fix --- MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift | 2 +- .../UINavigationController+Extension.swift | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift index 4f4a8b34..c6a14872 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift @@ -21,7 +21,7 @@ import VDSColorTokens else { return } // Set line to the same color as the text - if let color = titleLabel?.textColor?.cgColor { + if let color = titleColor(for: state)?.cgColor { context.setStrokeColor(color) } diff --git a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift index 625f0a25..3372c1ab 100644 --- a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift +++ b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift @@ -12,6 +12,7 @@ import MVMCore public extension UINavigationController { /// Convenience function for setting the navigation item. + @MainActor func setNavigationItem(with model: NavigationItemModelProtocol, for viewController: UIViewController, coordinatingWith pageBehaviorController: PageBehaviorHandlerProtocol? = nil) { let behaviorHandler = pageBehaviorController ?? viewController as? PageBehaviorHandlerProtocol; @@ -33,6 +34,7 @@ public extension UINavigationController { } /// Convenience function for setting the navigation buttons. + @MainActor func setNavigationButtons(with model: NavigationItemModelProtocol, for viewController: UIViewController) { let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject var leftItems: [UIBarButtonItem] = [] @@ -60,6 +62,7 @@ public extension UINavigationController { } /// Convenience function for setting the navigation titleView. + @MainActor func setNavigationTitleView(with model: NavigationItemModelProtocol, for viewController: UIViewController, coordinatingWith pageBehaviorController: PageBehaviorHandlerProtocol? = nil) { guard let titleViewModel = model.titleView else { return } @@ -87,6 +90,7 @@ public extension UINavigationController { } /// Convenience function for setting the navigation bar ui + @MainActor func setNavigationBarUI(with model: NavigationItemModelProtocol) { let navigationBar = navigationBar let font = Styler.Font.BoldTitleSmall.getFont(false) From 308700c667f3c2534a51bffd2043620d2c2407e3 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 4 Oct 2023 10:17:49 -0400 Subject: [PATCH 19/20] MVMCoreObject to swift --- .../xcshareddata/xcschemes/MVMCoreUI.xcscheme | 66 +++++++++++++++++++ MVMCoreUI/Alerts/AlertOperation.swift | 2 +- MVMCoreUI/OtherHandlers/CoreUIObject.swift | 16 ++--- MVMCoreUI/OtherHandlers/MVMCoreUISession.m | 3 +- 4 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 MVMCoreUI.xcodeproj/xcshareddata/xcschemes/MVMCoreUI.xcscheme diff --git a/MVMCoreUI.xcodeproj/xcshareddata/xcschemes/MVMCoreUI.xcscheme b/MVMCoreUI.xcodeproj/xcshareddata/xcschemes/MVMCoreUI.xcscheme new file mode 100644 index 00000000..9e236f99 --- /dev/null +++ b/MVMCoreUI.xcodeproj/xcshareddata/xcschemes/MVMCoreUI.xcscheme @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MVMCoreUI/Alerts/AlertOperation.swift b/MVMCoreUI/Alerts/AlertOperation.swift index 088a6ff5..50b71e46 100644 --- a/MVMCoreUI/Alerts/AlertOperation.swift +++ b/MVMCoreUI/Alerts/AlertOperation.swift @@ -73,7 +73,7 @@ public class AlertOperation: MVMCoreOperation { if await !self.properties.getIsDisplayed() { self.markAsFinished() } else { - (CoreUIObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject) + (MVMCoreObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject) if self.isCancelled { await self.dismissAlertView() } diff --git a/MVMCoreUI/OtherHandlers/CoreUIObject.swift b/MVMCoreUI/OtherHandlers/CoreUIObject.swift index b96e9b93..5f16a8f3 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIObject.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIObject.swift @@ -9,19 +9,17 @@ import UIKit import MVMCore -@objcMembers open class CoreUIObject: MVMCoreObject { +@objcMembers +public class CoreUIObject: NSObject { + private static var singleton = CoreUIObject() + public static func sharedInstance() -> CoreUIObject? { singleton } + private override init() {} + public var alertHandler: AlertHandler? public var topNotificationHandler: NotificationHandler? - open override func defaultInitialSetup() { + public func defaultInitialSetup() { CoreUIModelMapping.registerObjects() - loadHandler = MVMCoreLoadHandler() - cache = MVMCoreCache() - session = MVMCoreUISession() - sessionHandler = MVMCoreSessionTimeHandler() - actionHandler = MVMCoreUIActionHandler() - viewControllerMapping = MVMCoreUIViewControllerMappingObject() - loggingDelegate = MVMCoreUILoggingHandler() alertHandler = AlertHandler() } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUISession.m b/MVMCoreUI/OtherHandlers/MVMCoreUISession.m index 42a3e769..3b1d5913 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUISession.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUISession.m @@ -9,7 +9,8 @@ #import "MVMCoreUISession.h" #import "MFLoadingViewController.h" #import "NSLayoutConstraint+MFConvenience.h" -@import MVMCore.MVMCoreObject; +@import MVMCore.MVMCoreLoadingOverlayDelegateProtocol; +@import MVMCore.Swift; @interface MVMCoreUISession () From e940c9bf087da7112718d4723728eed1378b23a8 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 4 Oct 2023 17:20:54 -0400 Subject: [PATCH 20/20] add to default config --- MVMCoreUI/OtherHandlers/CoreUIObject.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MVMCoreUI/OtherHandlers/CoreUIObject.swift b/MVMCoreUI/OtherHandlers/CoreUIObject.swift index 5f16a8f3..d1fd18f9 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIObject.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIObject.swift @@ -19,7 +19,12 @@ public class CoreUIObject: NSObject { public var topNotificationHandler: NotificationHandler? public func defaultInitialSetup() { + MVMCoreObject.sharedInstance()?.defaultInitialSetup() CoreUIModelMapping.registerObjects() + MVMCoreObject.sharedInstance()?.session = MVMCoreUISession() + MVMCoreObject.sharedInstance()?.actionHandler = MVMCoreUIActionHandler() + MVMCoreObject.sharedInstance()?.viewControllerMapping = MVMCoreUIViewControllerMappingObject() + MVMCoreObject.sharedInstance()?.loggingDelegate = MVMCoreUILoggingHandler() alertHandler = AlertHandler() } }