RxSwift中withLatestFrom不兼容BehaviorRelay的问题排查
手机号注册检查ViewModel中withLatestFrom报错问题排查
问题描述
编写用于用户注册前检查手机号状态的ViewModel时,遇到如下错误:
Instance method 'withLatestFrom' requires that 'BehaviorRelay' conform to 'SharedSequenceConvertibleType'
相关代码如下:
import Foundation import RxSwift import RxCocoa protocol RegisterViewModelling { var openRegistrationData: Signal<String> { get } var showErrorMessage: Signal<String> { get } var sendButtonActive: Driver<Bool> { get } var phoneNumberText: BehaviorRelay<String> { get } var tapSendButton: PublishRelay<Void> { get } } final class RegisterViewModel: RegisterViewModelling { var openRegistrationData: Signal<String> let showErrorMessage: Signal<String> let sendButtonActive: Driver<Bool> let phoneNumberText: BehaviorRelay<String> = BehaviorRelay<String>(value: "") let tapSendButton: PublishRelay<Void> = PublishRelay<Void>() init(getPhoneNumberStatus: GetPhoneNumberStatusUseCase) { sendButtonActive = phoneNumberText .asDriver(onErrorDriveWith: .empty()) .map(shouldButtonActive(number:)) let isRegistered = tapSendButton .withLatestFrom(phoneNumberText) .flatMap(getPhoneNumberStatus.get(number:)) .share() showErrorMessage = isRegistered .asSignal(onErrorSignalWith: .just(true)) .filter { $0 == true } .map { _ in () } .map(getErrorMessage) openRegistrationData = isRegistered .asSignal(onErrorSignalWith: .just(true)) .filter { $0 == false } .withLatestFrom(phoneNumberText) // ERROR: Instance method 'withLatestFrom' requires that 'BehaviorRelay<String>' conform to 'SharedSequenceConvertibleType' } } private func shouldButtonActive(number: String) -> Bool { return !number.isEmpty && number.count <= 15 } private func getErrorMessage() -> String { return "Phone number has been registered." } protocol GetPhoneNumberStatusUseCase { func get(number: String) -> Observable<Bool> }
问题原因
- 序列体系不兼容:报错行中调用
withLatestFrom的是Signal类型序列,Signal属于RxSwift的SharedSequence体系,它的withLatestFrom方法要求传入的参数必须符合SharedSequenceConvertibleType协议(比如Driver、Signal这类),而BehaviorRelay本质是Observable的子类,并不直接符合该协议。 - 前序代码正常的原因:之前
tapSendButton是PublishRelay(属于Observable体系),它的withLatestFrom方法接受ObservableConvertibleType类型参数,BehaviorRelay刚好符合这个协议,因此可以直接传入使用。
解决方法
将BehaviorRelay转换为Signal(或Driver)类型,使其符合SharedSequenceConvertibleType要求,修改报错行代码如下:
.withLatestFrom(phoneNumberText.asSignal(onErrorSignalWith: .empty()))
或者转换为Driver(与上下文Signal兼容):
.withLatestFrom(phoneNumberText.asDriver(onErrorDriveWith: .empty()))
内容的提问来源于stack exchange,提问作者Bawenang Rukmoko Pardian Putra
相关产品推荐
相关产品推荐

