2017-02-16 3 views
13

아래의 함수를 여러 관찰 가능 체이닝과 함께 만들었지 만 무엇을해도 호출하지 않는 것 같습니다 completed? 그것은 단지 다음을 반환 :flatMap oncompleted를 반환하지 않습니다

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

I 개별적으로 관찰 가능한을 debug 때 그들은 모두 반환하더라도 여기

completed 내 체인 기능입니다

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

좋아요. rx_authenticate 및 fetchProfileData 구현을 추가 할 수 있습니까? – ULazdins

+0

지금 추가됩니다. 미리 감사드립니다 –

+1

'observerFacebook'에 대한 정의를 추가 할 수 있습니까? – tomahh

답변

5

마다 facebookButton 두드린 값 발광 것이라는 관찰을 반환하는 observerFacebook 전화와 체인 시작.

이 관찰 가능은 facebookButton이 해제 될 때만 완료되며, 대부분보기 컨트롤러를 들고있는보기 컨트롤러가 화면에서 제거 될 때만 완료됩니다.

체인의 나머지 부분은 map 또는 flatMap입니다. 그러나 다른 탭이 전체 체인을 다시 트리거하므로 강제 종료하지 마십시오.

함수가과 같이 정의 될 수 있도록 facebookButton.rx.taptake(1)에 호출을 추가하는 것이 문제를 해결하는 쉽게 방법 : 첫 번째 이후 지금

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

, observerFacebook것이다 완료 탭을 누르면 onCompleted으로 전화가 표시됩니다.

다른 탭이 들어올 때 다시 수행하려면 오류시 체인에 다시 가입해야합니다.

+0

다른 사람이 rxjava 응답을 찾는 경우, 제가 사용하는 관용구는'Observable.create (s -> { 'emitter.onComplete()'는 구독자에게'onComplete()'를 전달할 것이다. –