2017-02-16 22 views
13

Birden fazla gözlemlenebilir zincirleme ile aşağıdaki işlevi oluşturdum ancak ne yaparsam yapayım completed? sadece aşağıdaki döndürür:flatMap Dönmeyecek şekilde teslim edildi Tamamlanmış

(facebookSignInAndFetchData()) -> subscribed 
(facebookSignInAndFetchData()) -> Event next(()) 

ben tek tek gözlenebilirleri debug zaman hepsi dönmek rağmen burada

completed benim zincirleme fonksiyonudur

func facebookSignInAndFetchData() { 


    observerFacebook.flatMap { (provider: FacebookProvider) in 
     return provider.login() 
     }.flatMap { token in 
      return self.loginViewModel.rx_authenticate(token: token) 
     }.flatMap { 
      return self.loginViewModel.fetchProfileData() 
     }.debug().subscribe(onError: { error in 

      //Guard unknown ErrorType 
      guard let err = error as? AuthError else { 
       //Unknown error message 
       self.alertHelper.presentAlert(L10n.unknown) 
       return 
      } 

      //error message handling 
      switch err { 
      case .notLoggedIn: 
       print("not logged in") 
       break 
      default: 
       self.alertHelper.presentAlert(err.description) 
      } 

     }, onCompleted: { 
      self.goToInitialController() 
     }).addDisposableTo(self.disposeBag) 

} 

rx_authenticate

func rx_authenticate(token: String) -> Observable<Void> { 


    return Observable.create({ observer in 
     let credentials = SyncCredentials.facebook(token: token) 
     SyncUser.logIn(with: credentials, server: URL(string: Globals.serverURL)!, onCompletion: { user, error in 

      //Error while authenticating 
      guard error == nil else { 
       print("error while authenticating: \(error!)") 
       observer.onError(AuthError.unknown) 
       return 
      } 

      //Error while parsing user 
      guard let responseUser = user else { 
       print("error while authenticating: \(error!)") 
       observer.onError(AuthError.unknown) 
       return 
      } 

      //Authenticated 
      setDefaultRealmConfiguration(with: responseUser) 

      //next 
      observer.onNext() 

      //completed 
      observer.onCompleted() 


     }) 

     return Disposables.create() 
    }) 
} 

fetchProfileData

func fetchProfileData() -> Observable<Void> { 

    return Observable.create({ observer in 

     //Fetch facebookData 
     let params = ["fields" : "name, picture.width(480)"] 
     let graphRequest = GraphRequest(graphPath: "me", parameters: params) 
     graphRequest.start { 
      (urlResponse, requestResult) in 
      switch requestResult { 
      case .failed(_): 
       //Network error 
       observer.onError(AuthError.noConnection) 
       break 
      case .success(let graphResponse): 

       if let responseDictionary = graphResponse.dictionaryValue { 

        guard let identity = SyncUser.current?.identity else { 
         //User not logged in 
         observer.onError(AuthError.noUserIdentity) 
         return 
        } 

        //Name 
        let name = responseDictionary["name"] as! String 

        //Image dictionary 
        let pictureDic = responseDictionary["picture"] as! [String: Any] 
        let dataDic = pictureDic["data"] as! [String: Any] 
        let imageHeight = dataDic["height"] as! Int 
        let imageWidth = dataDic["width"] as! Int 
        let url = dataDic["url"] as! String 

        //Create Person object 
        let loggedUser = Person() 
        loggedUser.id = identity 
        loggedUser.name = name 

        //Create photo object 
        let photo = Photo() 
        photo.height = imageHeight 
        photo.width = imageWidth 
        photo.url = url 

        //Append photo object to person object 
        loggedUser.profileImage = photo 

        //Save userData 
        let realm = try! Realm() 
        try! realm.write { 
         realm.add(loggedUser, update: true) 
        } 

        //next 
        observer.onNext() 

        //completed 
        observer.onCompleted() 

       } else { 
        //Could not retrieve responseData 
        observer.onError(AuthError.noResponse) 
       } 
      } 
     } 



     return Disposables.create() 
    }) 


} 

observerFacebook

//FacebookProvider 
private lazy var observerFacebook: Observable<FacebookProvider>! = { 
    self.facebookButton.rx.tap.map { 

     return FacebookProvider(parentController: self) 
    } 
}() 
+1

iyi görünüyor. Rx_authenticate ve fetchProfileData uygulamalarını ekleyebilir misiniz? – ULazdins

+0

şimdi eklenmiştir. şimdiden teşekkür ederiz –

+1

Ayrıca 'observerFacebook' için tanım ekleyebilir misiniz? – tomahh

cevap

5

her facebookButton dokunulduğunda değerleri yayan olacağı bir gözlenebilir döndüren observerFacebook çağrı ile zincir başlar.

Bu gözlemlenebilir, ancak büyük olasılıkla görüntü denetleyicisi ekrandan kaldırıldığında görüntülenen facebookButton yayınlandığında tamamlanır. Zincirin geri kalanı map ya da flatMap olacaktır, ancak başka bir musluk tüm zinciri tekrar tetikleyeceği için hiçbir zaman zorlamayacaktır.

fonksiyon şöyle tanımlanabilir böylece, facebookButton.rx.tap üzerinde take(1) bir çağrı eklemek olacaktır Bunu çözmenin kolay yol: İlk sonra Şimdi

private lazy var observerFacebook: Observable<FacebookProvider>! = { 
    self.facebookButton.rx.tap 
    .take(1) 
    .map { 
     return FacebookProvider(parentController: self) 
    } 
}() 

, observerFacebookolacak komple dokunun ve onCompleted numaralı aramayı görmelisiniz. Başka bir musluk geldiğinde tekrar gerçekleştirmek istiyorsanız hatalarla ilgili zincire tekrar abone olmak gerekir

Not.

+0

Burada rxjava cevaplarını arayan başka biri varsa, kullandığı deyim 'Observable.create (s -> { s.onNext (new Object()); emitter = s;}). flatMap ($ -> realObservable) 've sonra emitter.onComplete()', 'onComplete() 'ya abone olacak. –