2017-10-27 4 views
1

Ich bin wirklich neu in Rx und RxSwift und ich versuche zu lernen, indem ich gleichzeitig lese und tue, also bringt dich diese Frage vielleicht zum Lachen. Bitte, entschuldige mich im Voraus: PForward transformed Event von Observable direkt zu BehaviourSubject

Ich habe diese Architektur:

MatchView -> MatchViewModel -> P2PSession -> MCSession+Rx 

ich eine Reactive Erweiterung von MCSession gemacht haben Sitzungszustand zu machen, ändert sich eine beobachtbare:

var didChangeState: Observable<(MCPeerID, MCSessionState)> { 
    return RxMCSessionDelegateProxy.proxy(for: base).didChangeStateSubject.asObservable() 
} 

Dann Ich habe ein anderes Objekt, P2PSession, das beobachtbar abonniert, um das empfangene Ereignis zu transformieren, um es an eine BehaviorSubject<MCPeerID?> zu emittieren, die von meiner MatchViewModel beobachtet wird, die es transformieren wird, um zu einerzu emittierenin einem Etikett angezeigt werden.

Vielleicht Verkettungs völlig lächerlich ist, aber hier ist die komplette (aber vereinfacht) Sache:

P2PSession

var connectedPeer: BehaviorSubject<MCPeerID?> = BehaviorSubject(value: nil) 

mcSession.rx.didChangeState 
    .subscribe(onNext: { self.connectedPeer.onNext($0.0) }) 
    .disposed(by: disposeBag) 

MatchViewModel

var peerName = Variable("") 

p2pSession.connectedPeer.asObservable() 
    .map({ $0?.displayName ?? "None" }) 
    .subscribe(onNext: { self.peerName.value = $0 }) 
    .disposed(by: disposeBag) 

MatchView

viewModel.peerName.asDriver() 
    .drive(peerLabel.rx.text) 
    .disposed(by: disposeBag) 

Es funktioniert, als Peer verbindet, wird ein Delegatmethode im RxMCSessionDelegateProxy und Daten bewegt sich durch die Kette genannt, bis es in dem Etikett dargestellt ist.

Aber ich denke, dass könnte viel eleganter gemacht werden. Ist es möglich, ein transformiertes Ereignis von einem Observablen auf ein Subjekt zu übertragen, ohne die Subskription für das erste Observable zu transformieren und den Wert auf das Subjekt/die Variable zu übertragen? (wie mache ich in P2PSession). Ich weiß nicht, ob ich mich richtig erklärt habe, aber ich denke, das ist möglich mit flatMap, aber ich bekomme es nicht richtig, vielleicht brauche ich sowieso die subscribe und ich versuche, dumme Dinge zu tun.

Vielen Dank, ich brauche deine Hilfe!

+0

Benötigen Sie wirklich ein Thema? Weil dies leicht durch Verketten von Observablen mit map durchgeführt werden kann. Subjekte (Variablen sind Subjekte) addieren den Status und Sie ordnen nur von einem Typ zum anderen zu. –

+0

@FelipeCypriano Vielleicht kann ich mein 'BehaviorSubject' mit' Variable' ändern, aber ich habe das gleiche Problem, oder? Würden Sie mir bitte den Code mit Ihrer Lösung zeigen? Vielen Dank. – emenegro

+1

Wenn Sie die richtige Antwort bemerken, ist nicht auf Themen angewiesen. Sie könnten den Lesezugriff auf Ihre Klassen-Interna offen legen, ohne dass Sie diese benötigen oder benötigen. –

Antwort

2

Expose den angeschlossenen Peer über eine Observable, und die Peer-Namen durch einen Driver:

let connectedPeer: Observable<MCPeerID?> 
connectedPeer = mcSession.rx.didChangeState.map { $0.0 } 

let peerName: Driver<String> 
peerName = p2pSession.connectedPeer.map { $0.displayName ?? "None" }.asDriver(onErrorJustReturn: "None") 

viewModel.peerName.drive(peerLabel.rx.text).disposed(by: disposeBag) 
+0

Danke, es funktioniert mit dem 'connectedPeer', aber mit' peerName' es Fehler: 'Kann Call Ergebnis Typ 'Observable <_>' in den erwarteten Typ 'SharedSequence !'' Konvertieren. Ich kann keine Lösung finden T_T – emenegro

+0

Nun, mit 'peerName = p2pSession.connectedPeer.map {$ 0.displayName}.asDriver (onErrorJustReturn: "None") 'es funktioniert, aber ich weiß nicht, ob es korrekt ist. – emenegro

+0

Sorry, ich hätte die Konvertierung hinzufügen sollen. –

Verwandte Themen