2017-01-24 4 views
0

私は​​のマネージャーを持っていて、すべてCLLocationManagerを処理する必要があります。これは、RxSwift(およびその拡張機能とDelegateProxies)を通じて観測可能なプロパティを提供することによって実現します。 LocationRepositoryは次のようになります。RxSwiftドライバーを初めて2回呼び出す

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() 
    } 
} 

プレゼンターはリポジトリのプロパティの変更をリッスンします。それは作業を行い

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を取得していますので、アクセス要求ビューは二回提示します:LocatorPresenterはこのようになります。私はここで何が欠けていますか?

よろしくお願いいたします。

答えて

1

startWithドキュメントから:StartWith

ます場合、私はおそらくそれを試してみましたが、していない観察可能

ソースからアイテムを放出するために開始する前に、アイテムの指定されたシーケンスを発しますstartWith(status)を削除すると、ステータスは2回表示されません。

あなたが観測から次のシーケンスを受けているようだ:

------------------------------ ---不正----許可----->

ので、ラインで:

------- unauthorized-:

startWith(status) // status is unauthorized 

あなたは最終的にこの1つは取得します--------無許可----承認済み----->

+0

ありがとう、それでした。 Observableに初めて加入するたびに、私は現在のステータスを2回与えていました。取外し開始しました。 – edulpn

+0

これはうまくいきますが、 '.distinctUntilChanged()' ater mapをブール値にすることができます。ブール値は、状態が異なる場合にのみ呼び出され、呼び出しを複製しません。 –

関連する問題