Slather logo

Coverage for "StackIteratingFinder.swift" : 100.00%

(10 of 10 relevant lines covered)

RouteComposer/Classes/Finders/StackIteratingFinder.swift

1
//
2
// RouteComposer
3
// StackIteratingFinder.swift
4
// https://github.com/ekazaev/route-composer
5
//
6
// Created by Eugene Kazaev in 2018-2022.
7
// Distributed under the MIT license.
8
//
9
// Become a sponsor:
10
// https://github.com/sponsors/ekazaev
11
//
12
13
import Foundation
14
import UIKit
15
16
/// `StackIteratingFinder` iterates through the view controllers stack
17
/// following the search options provided. It simplifies the creation of the finders for a hosting app.
18
public protocol StackIteratingFinder: Finder {
19
20
    // MARK: Associated types
21
22
    /// Type of `UIViewController` that `StackIteratingFinder` can find
23
    associatedtype ViewController
24
25
    /// Type of `Context` object that `StackIteratingFinder` can deal with
26
    associatedtype Context
27
28
    // MARK: Properties to implement
29
30
    /// `StackIterator` to be used by `StackIteratingFinder`
31
    var iterator: StackIterator { get }
32
33
    // MARK: Methods to implement
34
35
    /// The method to be implemented by the `StackIteratingFinder` instance
36
    ///
37
    /// - Parameters:
38
    ///   - viewController: A view controller in the current view controller stack
39
    ///   - context: The `Context` instance provided to the `Router`.
40
    /// - Returns: true if this view controller is the one that `Finder` is looking for, false otherwise.
41
    func isTarget(_ viewController: ViewController,
42
                  with context: Context) -> Bool
43
44
}
45
46
public extension StackIteratingFinder {
47
48
    func findViewController(with context: Context) throws -> ViewController? {
193x
49
        let predicate: (UIViewController) -> Bool = {
709x
50
            guard let viewController = $0 as? ViewController else {
709x
51
                return false
600x
52
            }
600x
53
            return self.isTarget(viewController, with: context)
109x
54
        }
709x
55
193x
56
        return try iterator.firstViewController(where: predicate) as? ViewController
193x
57
    }
193x
58
59
}