Slather logo

Coverage for "Dismissible.swift" : 80.95%

(17 of 21 relevant lines covered)

RouteComposer/Classes/Extra/Dismissible.swift

1
//
2
// RouteComposer
3
// Dismissible.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
var associatedObjectHandle: UInt8 = 0
17
18
/// `UIViewController` should conform to `Dismissible` protocol to be used with `DismissalMethodProvidingContextTask`.
19
public protocol Dismissible where Self: UIViewController {
20
21
    // MARK: Associated types
22
23
    /// Type of instance that `Dismissible` `UIViewController` will provide on dismissal.
24
    associatedtype DismissalTargetContext
25
26
    // MARK: Properties to implement
27
28
    /// Property to store the dismissal block provided by `DismissalMethodProvidingContextTask`
29
    var dismissalBlock: ((_: DismissalTargetContext, _: Bool, _: ((_: RoutingResult) -> Void)?) -> Void)? { get set }
30
31
}
32
33
// MARK: Helper methods
34
35
public extension Dismissible {
36
37
    /// Dismisses current `UIViewController` using dismissal block provided by `DismissalMethodProvidingContextTask`
38
    ///
39
    /// - Parameters:
40
    ///   - context: `DismissalTargetContext` required to be dismissed.
41
    ///   - animated: Dismissal process should be animated if set to `true`
42
    ///   - completion: The completion block.
43
    func dismissViewController(with context: DismissalTargetContext, animated: Bool, completion: ((_: RoutingResult) -> Void)? = nil) {
5x
44
        guard let dismissalBlock else {
5x
45
            let message = "Dismissal block has not been set."
!
46
            assertionFailure(message)
!
47
            completion?(.failure(RoutingError.compositionFailed(.init(message))))
!
48
            return
!
49
        }
5x
50
        dismissalBlock(context, animated, completion)
5x
51
    }
5x
52
53
}
54
55
// MARK: Helper methods where the DismissalTargetContext is Any?
56
57
public extension Dismissible where DismissalTargetContext == Any? {
58
59
    /// Dismisses current `UIViewController` using dismissal block provided by `DismissalMethodProvidingContextTask`
60
    ///
61
    /// - Parameters:
62
    ///   - animated: Dismissal process should be animated if set to `true`
63
    ///   - completion: The completion block.
64
    func dismissViewController(animated: Bool, completion: ((_: RoutingResult) -> Void)? = nil) {
1x
65
        dismissViewController(with: nil, animated: animated, completion: completion)
1x
66
    }
1x
67
68
}
69
70
// MARK: Helper methods where the DismissalTargetContext is Void
71
72
public extension Dismissible where DismissalTargetContext == Void {
73
74
    /// Dismisses current `UIViewController` using dismissal block provided by `DismissalMethodProvidingContextTask`
75
    ///
76
    /// - Parameters:
77
    ///   - animated: Dismissal process should be animated if set to `true`
78
    ///   - completion: The completion block.
79
    func dismissViewController(animated: Bool, completion: ((_: RoutingResult) -> Void)? = nil) {
4x
80
        dismissViewController(with: (), animated: animated, completion: completion)
4x
81
    }
4x
82
83
}
84
85
/// `DismissibleWithRuntimeStorage` simplifies `Dismissible` protocol conformance implementing required
86
/// `dismissalBlock` using Objective C runtime.
87
public protocol DismissibleWithRuntimeStorage: Dismissible {}
88
89
public extension DismissibleWithRuntimeStorage {
90
91
    var dismissalBlock: ((_: DismissalTargetContext, _: Bool, _: ((_: RoutingResult) -> Void)?) -> Void)? {
92
        get {
5x
93
            objc_getAssociatedObject(self, &associatedObjectHandle) as? ((_: DismissalTargetContext, _: Bool, _: ((_: RoutingResult) -> Void)?) -> Void)
5x
94
        }
5x
95
        set {
11x
96
            objc_setAssociatedObject(self, &associatedObjectHandle, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
11x
97
        }
11x
98
    }
99
100
}