ONEAPP-5208: Review feedback

This commit is contained in:
Scott Pfeil 2023-08-28 11:13:39 -04:00
parent fe5dc7c6b7
commit 034133e4a5
5 changed files with 74 additions and 85 deletions

View File

@ -96,7 +96,6 @@
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F1289212CA00919EEB /* MVMError.swift */; };
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F3289212EB00919EEB /* MVMCoreError.swift */; };
AF686FDA2A8A876A008F666A /* NavigationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF686FD92A8A876A008F666A /* NavigationOperation.swift */; };
AF686FDC2A8A87EA008F666A /* KVOPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF686FDB2A8A87EA008F666A /* KVOPublisher.swift */; };
AF686FDE2A8D29CD008F666A /* MVMCoreLoadRequestOperation+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF686FDD2A8D29CD008F666A /* MVMCoreLoadRequestOperation+Extension.swift */; };
AF69D4E9286E54D500BC6862 /* ActionCallHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */; };
AF69D4EB286E586200BC6862 /* ActionRestartHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */; };
@ -252,7 +251,6 @@
AF60A7F1289212CA00919EEB /* MVMError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMError.swift; sourceTree = "<group>"; };
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreError.swift; sourceTree = "<group>"; };
AF686FD92A8A876A008F666A /* NavigationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationOperation.swift; sourceTree = "<group>"; };
AF686FDB2A8A87EA008F666A /* KVOPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KVOPublisher.swift; sourceTree = "<group>"; };
AF686FDD2A8D29CD008F666A /* MVMCoreLoadRequestOperation+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreLoadRequestOperation+Extension.swift"; sourceTree = "<group>"; };
AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCallHandler.swift; sourceTree = "<group>"; };
AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionRestartHandler.swift; sourceTree = "<group>"; };
@ -595,7 +593,6 @@
AF43A5851FBB67D6008E9347 /* MVMCoreActionUtility.h */,
AF43A5861FBB67D6008E9347 /* MVMCoreActionUtility.m */,
AFA4931D29E5C988001A9663 /* MVMCoreActionUtility+Extension.swift */,
AF686FDB2A8A87EA008F666A /* KVOPublisher.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -940,7 +937,6 @@
D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */,
AF686FDE2A8D29CD008F666A /* MVMCoreLoadRequestOperation+Extension.swift in Sources */,
60CBD0542A02397A00056CB0 /* MVMCoreSessionTimeHandler.swift in Sources */,
AF686FDC2A8A87EA008F666A /* KVOPublisher.swift in Sources */,
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */,
D268D82C26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m in Sources */,
0AEBB84625FA75C000EA80EE /* ActionOpenSMSModel.swift in Sources */,

View File

@ -70,13 +70,15 @@ public extension MVMCoreLoadRequestOperation {
func navigate(with navigationOperation: NavigationOperation, loadObject: MVMCoreLoadObject?) async {
// stop any loading animation we may have started if we are about to display
cancellable = NavigationHandler.shared().onNavigationWillBegin.sink(receiveValue: { operation in
cancellable = NavigationHandler.shared().onNavigation
.filter { $0.0 == .willNavigate }
.sink { (event, operation) in
if navigationOperation == operation,
!self.backgroundLoad,
!(loadObject?.requestParameters?.noloadingOverlay ?? false) {
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.stopLoading(false)
}
})
}
await NavigationHandler.shared().navigate(with: navigationOperation)
cancellable = nil
}

View File

@ -42,6 +42,11 @@ public class NavigationHandler {
}
}
}
public enum NavigationEvent {
case willNavigate
case didNavigate
}
private static let handler = NavigationHandler()
public static func shared() -> NavigationHandler {
@ -65,15 +70,11 @@ public class NavigationHandler {
// MARK: - Publishers
/** Publishes when the navigation will begin
- Parameter NavigationType: The type of navigation being performed.
/** Publishes navigation events
- Parameter NavigationEvent: The navigation event that is happening.
- Parameter NavigationOperation: The operation performing the navigation.
*/
public let onNavigationWillBegin = PassthroughSubject<(NavigationOperation), Never>()
/** Publishes when the navigation did finish
- Parameter NavigationType: The type of navigation being performed.
*/
public let onNavigationDidFinish = PassthroughSubject<(NavigationOperation), Never>()
public let onNavigation = PassthroughSubject<(NavigationEvent, NavigationOperation), Never>()
// MARK: - Getters

View File

@ -116,7 +116,7 @@ open class NavigationOperation: MVMCoreOperation, UINavigationControllerDelegate
}
navigationController.delegate = self
toNavigationControllerViewControllers = viewControllers
NavigationHandler.shared().onNavigationWillBegin.send(self)
NavigationHandler.shared().onNavigation.send((.willNavigate, self))
guard !checkAndHandleForCancellation() else { return }
navigationController.setViewControllers(viewControllers, animated: animated)
}
@ -175,11 +175,11 @@ open class NavigationOperation: MVMCoreOperation, UINavigationControllerDelegate
*/
@MainActor
open func present(viewController: UIViewController, onController: UIViewController, animated: Bool = true) {
NavigationHandler.shared().onNavigationWillBegin.send(self)
NavigationHandler.shared().onNavigation.send((.willNavigate, self))
guard !checkAndHandleForCancellation() else { return }
viewController.modalPresentationStyle = .fullScreen
onController.getViewControllerToPresentOn().present(viewController, animated: animated) { [self] in
NavigationHandler.shared().onNavigationDidFinish.send(self)
NavigationHandler.shared().onNavigation.send((.didNavigate, self))
markAsFinished()
}
}
@ -190,10 +190,10 @@ open class NavigationOperation: MVMCoreOperation, UINavigationControllerDelegate
*/
@MainActor
open func dismiss(viewController: UIViewController, animated: Bool = true) {
NavigationHandler.shared().onNavigationWillBegin.send(self)
NavigationHandler.shared().onNavigation.send((.willNavigate, self))
guard !checkAndHandleForCancellation() else { return }
viewController.dismiss(animated: animated) { [self] in
NavigationHandler.shared().onNavigationDidFinish.send(self)
NavigationHandler.shared().onNavigation.send((.didNavigate, self))
markAsFinished()
}
}
@ -202,7 +202,7 @@ open class NavigationOperation: MVMCoreOperation, UINavigationControllerDelegate
open func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
delegate?.navigationController?(navigationController, didShow: viewController, animated: animated)
NavigationHandler.shared().onNavigationDidFinish.send(self)
NavigationHandler.shared().onNavigation.send((.didNavigate, self))
markAsFinished()
}
@ -231,3 +231,58 @@ open class NavigationOperation: MVMCoreOperation, UINavigationControllerDelegate
return animatedTransitioning
}
}
fileprivate struct KVOPublisher<ObjectType: NSObject, ValueType>: Publisher {
public typealias Output = ValueType
public typealias Failure = Never
private let object: ObjectType
private let keyPath: String
private let options: NSKeyValueObservingOptions
public init(object: ObjectType, keyPath: String, options: NSKeyValueObservingOptions = [.new]) {
self.object = object
self.keyPath = keyPath
self.options = options
}
public func receive<S: Subscriber>(subscriber: S) where ValueType == S.Input, Never == S.Failure {
let subscription = KVOSubscription(subscriber: subscriber, object: object, keyPath: keyPath, options: options)
subscriber.receive(subscription: subscription)
}
private final class KVOSubscription<S: Subscriber, ObjectType: NSObject, ValueType>:NSObject, Subscription where S.Input == ValueType {
private let subscriber: S
private var object: ObjectType
private var keyPath: String
private var options: NSKeyValueObservingOptions
init(subscriber: S, object: ObjectType, keyPath: String, options: NSKeyValueObservingOptions = [.new]) {
self.object = object
self.keyPath = keyPath
self.options = options
self.subscriber = subscriber
super.init()
self.object.addObserver(self, forKeyPath: self.keyPath, options: options, context: nil)
}
func request(_ demand: Subscribers.Demand) {}
func cancel() {}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == self.keyPath, let change = change, let newValue = change[.newKey] as? ValueType {
_ = subscriber.receive(newValue)
}
}
deinit {
self.object.removeObserver(self, forKeyPath: keyPath)
}
}
}
extension NSObject {
fileprivate func kvoPublisher<Value>(for keyPath: String, type: Value.Type, options: NSKeyValueObservingOptions = [.new]) -> AnyPublisher<Value, Never> {
return KVOPublisher(object: self, keyPath: keyPath, options: options).eraseToAnyPublisher()
}
}

View File

@ -1,65 +0,0 @@
//
// KVOPublisher.swift
// MVMCore
//
// Created by Scott Pfeil on 8/14/23.
// Copyright © 2023 myverizon. All rights reserved.
//
import Foundation
import Combine
public struct KVOPublisher<ObjectType: NSObject, ValueType>: Publisher {
public typealias Output = ValueType
public typealias Failure = Never
private let object: ObjectType
private let keyPath: String
private let options: NSKeyValueObservingOptions
public init(object: ObjectType, keyPath: String, options: NSKeyValueObservingOptions = [.new]) {
self.object = object
self.keyPath = keyPath
self.options = options
}
public func receive<S: Subscriber>(subscriber: S) where ValueType == S.Input, Never == S.Failure {
let subscription = KVOSubscription(subscriber: subscriber, object: object, keyPath: keyPath, options: options)
subscriber.receive(subscription: subscription)
}
private final class KVOSubscription<S: Subscriber, ObjectType: NSObject, ValueType>:NSObject, Subscription where S.Input == ValueType {
private let subscriber: S
private var object: ObjectType
private var keyPath: String
private var options: NSKeyValueObservingOptions
init(subscriber: S, object: ObjectType, keyPath: String, options: NSKeyValueObservingOptions = [.new]) {
self.object = object
self.keyPath = keyPath
self.options = options
self.subscriber = subscriber
super.init()
self.object.addObserver(self, forKeyPath: self.keyPath, options: options, context: nil)
}
func request(_ demand: Subscribers.Demand) {}
func cancel() {}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == self.keyPath, let change = change, let newValue = change[.newKey] as? ValueType {
_ = subscriber.receive(newValue)
}
}
deinit {
self.object.removeObserver(self, forKeyPath: keyPath)
}
}
}
extension NSObject {
public func kvoPublisher<Value>(for keyPath: String, type: Value.Type, options: NSKeyValueObservingOptions = [.new]) -> AnyPublisher<Value, Never> {
return KVOPublisher(object: self, keyPath: keyPath, options: options).eraseToAnyPublisher()
}
}