Чтобы остановить подписку, наблюдателю необходимо выполнить одно из следующих действий:
Отправить сообщение об ошибке
Отправить завершенное сообщение
Удалить подписку (уничтожить disposeBag)
В вашем случае ни rx.viewWillAppear
ни shoppingCart
не отправляют сообщения об ошибках или завершенные сообщения, так как они являются драйверами
Один из способов правильного прекращения подписки - уничтожить старый пакет disposeBag.
bag = DisposeBag()
Но не забудьте восстановить подписку на viewWillAppear
Другой вариант будет иметь какой-то флаг в VC, например
var hasAppeared: Bool
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
...
hasAppeared = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisppear(animated)
...
hasAppeared = false
}
и просто добавить фильтрацию
output?.shoppingCart
.filter({ [weak self] _ in self?.hasAppeared ?? false })
.map {
print("Mapping")
return $0.lines.count == 0
}
.asObservable()
.bind(to: goToCartButton.rx.isHidden)
.disposed(by: bag)
Третий способ - остановить отправку изнутри viewModel
let initTrigger = rx.viewWillAppear
.mapToVoid()
.asDriverOnErrorJustComplete()
let stopTrigger = rx.viewWillDisappear
.mapToVoid()
.asDriverOnErrorJustComplete()
let shoppingCart: Driver<ShoppingCart>
let shoppingCart = Observable.merge(input.initTrigger.map({ true }),
input.stopTrigger.map({ false }))
.flatMapLatest { isRunning in
guard isRunning else {
return .just(ShoppingCart())
}
return self.getShoppingCartUseCase
.execute()
.asDriver(onErrorJustReturn: ShoppingCart())
}