Reputation: 2001
In order to update a view, I want to forward the view from my ViewController to the ViewModel by forwarding it.
Something like the following:
viewModel.labelViewModel.subscribe(forward: labelView) { labelView, model in labelView.update(with: model) }
but using Combine.
So how can I return the observer with the observable?
In the ViewController I'm trying:
viewModel.$labelModel.sink { lab in
print("Value: \(lab?.1.text)")
}.store(in: &subscriptions)
with the label in the ViewModel:
@Published private(set) var labelModel: (Label, Label.Model)?
but what I want to do is actually return the same label in the sink as is subscribing from the ViewController.
Is this possible?
Upvotes: 1
Views: 181
Reputation: 33978
You could do it with something like this:
extension Publisher {
func withUnretained<Object: AnyObject>(_ obj: Object) -> AnyPublisher<(Object, Output), Error> {
return tryMap { [weak obj] element -> (Object, Output) in
guard let obj = obj else { throw UnretainedError.failedRetaining }
return (obj, element)
}
.eraseToAnyPublisher()
}
}
enum UnretainedError: Swift.Error {
case failedRetaining
}
Which would allow you to do:
$labelModel
.withUnretained(label)
.sink { (completion) in
if case .failure = completion {
print("oops!")
}
} receiveValue: { (label, text) in
label.text = text
}
.store(in: &subscriptions)
But why do all that when you could just do this?
$labelModel
.sink { [label] text in
label?.text = text
}
.store(in: &subscriptions)
Upvotes: 1