Я вижу проблему. PublishRelay - это просто PublishSubject.
Все, что помещено на него до подписки вашей viewModel, будет потеряно. .Share (replay: 1) помог бы, за исключением того, что что-то должно быть подписано на , что , прежде чем пользователь будет помещен на него, чтобы он «перехватил» событие и кэшировал значение для последующего использования. абонентов.
И даже тогда вам, вероятно, понадобится .share (повтор: 1, область действия: .forever).
Вам нужно помнить, что вы можете настроить все наблюдаемые цепочки, которые вы хотите, но никакие операции в этой цепочке не будут выполняться, пока что-то в конечном итоге не подпишется на эту цепочку.
Измените свое пользовательское состояние на BehaviorSubject (Значение: ноль). Это будет захватывать и удерживать текущего пользователя, если и когда пользователь помещен на него, даже если на него ничего не подписано.
Затем выполните на вашей модели вида что-то вроде следующего.
class ProfileViewModel {
lazy var user = UserState.shared.user.compactMap { $0 }
lazy var name = user.map { $0.username }
lazy var age = user.map { "\($0.age) years old" }
.do(onNext: { print($0) }
// etc
}
class profileViewController {
...
override func viewDidLoad() {
...
profileViewModel.name
.subscribe(onNext: { [weak self] name in
self?.title = name
}
.disposed(by: disposeBag)
}
}
Обратите внимание, что вы хотите этого, если пользователь (и, следовательно, имя пользователя) может динамически меняться в течение периода, когда отображается этот контроллер представления, и вы хотите, чтобы заголовок обновлялся автоматически.
Также обратите внимание, что, как показано, вы НИКОГДА не увидите возраст пользователя, указанный в операторе .do, так как в настоящее время ничто не подписывается и не привязывается к этой наблюдаемой подцепи.