Digital PCT265 story ONEAPP-7249 - Reduce full cell reloads on updates.
This commit is contained in:
parent
3f77a261bc
commit
fd296b9623
@ -1,63 +0,0 @@
|
||||
//
|
||||
// ReadableDecodingErrors.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Kyle Hedden on 10/5/23.
|
||||
// Copyright © 2023 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol HumanReadableDecodingErrorProtocol {
|
||||
var readableDescription: String { get }
|
||||
}
|
||||
|
||||
extension JSONError: HumanReadableDecodingErrorProtocol {
|
||||
var readableDescription: String {
|
||||
switch (self) {
|
||||
case .other(let other):
|
||||
if let other = other as? HumanReadableDecodingErrorProtocol {
|
||||
return other.readableDescription
|
||||
}
|
||||
return description
|
||||
default:
|
||||
return description
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ModelRegistry.Error: HumanReadableDecodingErrorProtocol {
|
||||
var readableDescription: String {
|
||||
switch (self) {
|
||||
case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil:
|
||||
return "Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })"
|
||||
|
||||
case .decoderErrorObjectNotPresent(let codingKey, let codingPath):
|
||||
return "Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })"
|
||||
|
||||
default:
|
||||
return "Registry error: \((self as NSError).localizedFailureReason ?? self.localizedDescription)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DecodingError: HumanReadableDecodingErrorProtocol {
|
||||
var readableDescription: String {
|
||||
switch (self) {
|
||||
case .keyNotFound(let codingKey, let context):
|
||||
return "Required key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })"
|
||||
|
||||
case .valueNotFound(_, let context):
|
||||
return "Value not found @ \(context.codingPath.map { return $0.stringValue })"
|
||||
|
||||
case .typeMismatch(_, let context):
|
||||
return "Value type mismatch @ \(context.codingPath.map { return $0.stringValue })"
|
||||
|
||||
case .dataCorrupted(let context):
|
||||
return "Data corrupted @ \(context.codingPath.map { return $0.stringValue })"
|
||||
|
||||
@unknown default:
|
||||
return (self as NSError).localizedFailureReason ?? self.localizedDescription
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,12 +97,16 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||
super.updateUI(for: molecules)
|
||||
|
||||
molecules?.forEach({ molecule in
|
||||
guard let molecules else { return }
|
||||
|
||||
// For updating individual specfied molecules. (Not a full table reload done in the base class.) These molecule types should remain the same type by replacement standards.
|
||||
molecules.forEach({ molecule in
|
||||
// Replace any top level cell data if required.
|
||||
if let index = moleculesInfo?.firstIndex(where: { $0.molecule.id == molecule.id }) {
|
||||
moleculesInfo?[index].molecule = molecule
|
||||
}
|
||||
newData(for: molecule)
|
||||
})
|
||||
newData(for: molecules)
|
||||
}
|
||||
|
||||
open override func viewDidAppear(_ animated: Bool) {
|
||||
@ -233,18 +237,27 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
}
|
||||
|
||||
open func newData(for molecule: MoleculeModelProtocol) {
|
||||
newData(for: [molecule])
|
||||
}
|
||||
|
||||
/// Refreshes all relevant cells for a given set of molecule models.
|
||||
open func newData(for molecules: [MoleculeModelProtocol]) {
|
||||
|
||||
//Check header and footer if replace happens then return.
|
||||
if updateHeaderFooterView(topView, with: molecule) ||
|
||||
updateHeaderFooterView(bottomView, with: molecule, isHeader: false) {
|
||||
return
|
||||
molecules.forEach {
|
||||
if updateHeaderFooterView(topView, with: $0) ||
|
||||
updateHeaderFooterView(bottomView, with: $0, isHeader: false) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
guard let moleculesInfo = moleculesInfo else { return }
|
||||
|
||||
let indicies = moleculesInfo.indices.filter({ index -> Bool in
|
||||
return moleculesInfo[index].molecule.findFirstMolecule(by: {
|
||||
$0.moleculeName == molecule.moleculeName && equal(moleculeA: molecule, moleculeB: $0)
|
||||
return moleculesInfo[index].molecule.findFirstMolecule(by: { existingMolecule in
|
||||
molecules.contains { newMolecule in
|
||||
existingMolecule.moleculeName == newMolecule.moleculeName && equal(moleculeA: existingMolecule, moleculeB: newMolecule)
|
||||
}
|
||||
}) != nil
|
||||
})
|
||||
|
||||
@ -253,7 +266,14 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
||||
let indexPaths = indicies.map {
|
||||
return IndexPath(row: $0, section: 0)
|
||||
}
|
||||
tableView.reloadRows(at: indexPaths, with: .automatic)
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
// All rows should have been layed out already on the first newDataBuildScreen reload with the getMoleculeInfoList call. Therefore, we can be safe to assume the top level cell configuration will not be modified and only the child content will be updated allowing us to levearage this more efficient method.
|
||||
tableView.reconfigureRows(at: indexPaths)
|
||||
} else {
|
||||
// A full reload can cause a flicker / animation. Better to avoid with above reconfigure method.
|
||||
tableView.reloadRows(at: indexPaths, with: .automatic)
|
||||
}
|
||||
if let selectedIndex = selectedIndex {
|
||||
tableView.selectRow(at: selectedIndex, animated: false, scrollPosition: .none)
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior {
|
||||
}
|
||||
}
|
||||
if moleculeModels.count > 0 {
|
||||
// TODO: Getting dropped into the page update queue. Can we get this replaced without an async dispatch to avoid an animation?
|
||||
delegateObject?.moleculeDelegate?.replaceMoleculeData(moleculeModels, completionHandler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user