RxSwift Driver 第一次调用两次

RxSwift Driver calling twice on first time

我有一个 CoreLocation 管理器,它应该通过 RxSwift(及其扩展和 DelegateProxies)提供可观察的属性来处理所有 CLLocationManagerLocationRepository 看起来像这样:

class LocationRepository {
    static let sharedInstance = LocationRepository()
    var locationManager: CLLocationManager = CLLocationManager()
    private (set) var supportsRequiredLocationServices: Driver<Bool>
    private (set) var location: Driver<CLLocationCoordinate2D>
    private (set) var authorized: Driver<Bool>

    private init() {
        locationManager.distanceFilter = kCLDistanceFilterNone
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation

        supportsRequiredLocationServices = Observable.deferred {
            let support = CLLocationManager.locationServicesEnabled() && CLLocationManager.significantLocationChangeMonitoringAvailable() && CLLocationManager.isMonitoringAvailable(for:CLCircularRegion.self)
            return Observable.just(support)
        }
        .asDriver(onErrorJustReturn: false)

        authorized = Observable.deferred { [weak locationManager] in
            let status = CLLocationManager.authorizationStatus()
            guard let locationManager = locationManager else {
                return Observable.just(status)
            }
            return locationManager.rx.didChangeAuthorizationStatus.startWith(status)
        }
        .asDriver(onErrorJustReturn: CLAuthorizationStatus.notDetermined)
        .map {
            switch [=10=] {
            case .authorizedAlways:
                return true
            default:
                return false
            }
        }

        location = locationManager.rx.didUpdateLocations.asDriver(onErrorJustReturn: []).flatMap {
            return [=10=].last.map(Driver.just) ?? Driver.empty()
        }
        .map { [=10=].coordinate }
    }

    func requestLocationPermission() {
        locationManager.requestAlwaysAuthorization()
    }
}

然后我的演示者会收听存储库属性的更改。 LocatorPresenter 看起来像这样:

class LocatorPresenter: LocatorPresenterProtocol {
    weak var view: LocatorViewProtocol?
    var repository: LocationRepository?
    let disposeBag = DisposeBag()

    func handleLocationAccessPermission() {
        guard repository != nil, view != nil else {
            return
        }

        repository?.authorized.drive(onNext: {[weak self] (authorized) in
            if !authorized {
                print("not authorized")
                if let sourceView = self?.view! as? UIViewController, let authorizationView = R.storyboard.locator.locationAccessRequestView() {
                    sourceView.navigationController?.present(authorizationView, animated: true)
                }
            } else {
                print("authorized")
            }
        }).addDisposableTo(disposeBag)
    }
}

它确实有效,但我第一次尝试获取授权状态时收到 Driver 调用两次,因此访问请求视图显示了两次。我在这里错过了什么?

此致!

来自 startWith 文档:

StartWith emit a specified sequence of items before beginning to emit the items from the source Observable

我没有尝试过,但如果您删除 startWith(status),您可能不会收到两次状态。

您似乎正在接收来自 observable 的下一个序列:

--------------------------------未授权----已授权------>

所以这行:

startWith(status) // status is unauthorized

你终于得到了这个:

--------未授权--------未授权----已授权----->