ONEAPP-5208: Review feedback
This commit is contained in:
parent
fe5dc7c6b7
commit
034133e4a5
@ -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 */,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user