RxSwift Driver第一次调用两次

时间:2017-01-24 21:35:43

标签: swift core-location rx-swift

我有一个CoreLocation管理器,它应该通过RxSwift(及其Extensions和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 $0 {
            case .authorizedAlways:
                return true
            default:
                return false
            }
        }

        location = locationManager.rx.didUpdateLocations.asDriver(onErrorJustReturn: []).flatMap {
            return $0.last.map(Driver.just) ?? Driver.empty()
        }
        .map { $0.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两次,因此访问请求视图会显示两次。我在这里缺少什么?

问候!

1 个答案:

答案 0 :(得分:1)

来自startWith文档:

  

StartWith   在开始从源Observable

中发出项目之前,发出指定的项目序列

我还没有尝试过,但可能如果您删除了startWith(status),您将无法获得两次状态。

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

---------------------------------未经授权的授权---- -----&GT; < / p>

所以行:

startWith(status) // status is unauthorized

你终于得到了这个:

-------未授权---------未经授权的授权---- -----&GT;