我有一个CoreLocation
管理器,它应该通过RxSwift(及其Extensions和DelegateProxies)提供可观察的属性来处理所有CLLocationManager
。 LocationRepository
看起来像这样:
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
两次,因此访问请求视图会显示两次。我在这里缺少什么?
问候!
答案 0 :(得分:1)
来自startWith
文档:
StartWith 在开始从源Observable
中发出项目之前,发出指定的项目序列
我还没有尝试过,但可能如果您删除了startWith(status)
,您将无法获得两次状态。
您似乎正在接收来自observable的下一个序列:
---------------------------------未经授权的授权---- -----&GT; < / p>
所以行:
startWith(status) // status is unauthorized
你终于得到了这个:
-------未授权---------未经授权的授权---- -----&GT;