I am trying to implement an extension for Publisher
with a function sinkWithActions(). This function should perform sink with some custom actions inside and returns an AnyCancellable
.
sinkWithActions() expects values of a type that conforms to a custom NavigationRoute
protocol and this values should be Optional
.
I have managed to get this working with non-optional values, but I am having trouble handling optional values as well. How can I achieve this?
Here's what I've tried so far. I expected that I will be able to use sinkWithActions() here.
protocol NavigationRoute: Identifiable, Equatable { }
struct DetailsRoute: NavigationRoute {
var id: Int
}
final class ViewModel: ObservableObject {
@Published var fullscreen: DetailsRoute?
private var cancellables = Set<AnyCancellable>()
init() {
$fullscreen
.sinkWithActions() // here
.store(in: &cancellables)
}
}
extension Publisher where Output: NavigationRoute, Failure == Never {
func sinkWithActions() -> AnyCancellable {
self.sink { _ in
// actions...
}
}
}
Compiler is saying:
Referencing instance method 'sinkWithActions()' on 'Publisher' requires that 'Published<DetailsRoute?>.Publisher.Output' (aka 'Optional<DetailsRoute>') conform to 'NavigationRoute'
You can simply declare another sinkWithActions
overload for optional navigation routes.
extension Publisher where Failure == Never{
func sinkWithActions<T: NavigationRoute>() -> AnyCancellable where Output == T? {
self.sink { _ in
// ...
}
}
}
Alternatively, you can also make Optional
conform to NavigationRoute
if its wrapped value conforms to NavigationRoute
. This is similar to how an optional of some Equatable
thing is also Equatable
.
// the protocol should be public for this to work
public protocol NavigationRoute: Identifiable, Equatable { }
extension Optional: Identifiable where Wrapped: NavigationRoute {
public var id: Wrapped.ID? { self?.id }
}
extension Optional: NavigationRoute where Wrapped: NavigationRoute {
}
Note: depending on what exactly you are in sink
, and how you are using NavigationRoute
elsewhere, this conformance might not make sense.