J'ai un gestionnaire CoreLocation
qui devrait gérer tous les CLLocationManager
en offrant des propriétés observables via RxSwift (et ses extensions et DelegateProxies). LocationRepository
ressemble à ceci:RxSwift Pilote appelant deux fois la première fois
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()
}
}
Mon présentateur écoute alors des changements sur les propriétés du référentiel. LocatorPresenter
ressemble à ceci:
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)
}
}
Il fonctionne, mais je reçois le Driver
deux fois pour appeler la première fois que j'essaie d'obtenir le statut d'autorisation, de sorte que la vue sur la demande d'accès obtient présenté deux fois. Qu'est-ce que j'oublie ici?
Cordialement!
Merci, c'était ça. Il me donnait deux fois le statut actuel chaque fois que je m'abonnais à l'Observable pour la première fois. enlever startWith travaillé. – edulpn
Cela fonctionnera, mais vous pouvez utiliser '.distinctUntilChanged()' ater map to boolean, qui se déclenchera à nouveau si le statut est différent, et non pas en double. –