0

I have an utility class to handle the socket, and in the socket delegate methods i could know the current state of the socket, e.g. didConnected, didReadData and so on. I do not want to write an extra protocol with a delegate to send the socket state indeed.

Actually, there are 2 properties in my utility class, an enum to differentiate the current state of the socket between: didConnected, didReadData, didDisconnected, the other is a Data type value to store the received data from socket. It likes that:

public enum SocketState {
    case unknown, didConnected, didReconnectedFailed, didSentHeartbeatPack, 
         didSentMessage, didReadData, didDisconnected
}
private var currentState: SocketState = .unknown
private var msgData = Data()

After become the delegate of the socket, I have implemented the several methods,

func socket(_ sock: GCDAsyncSocket, didConnectToHost host: String, port: UInt16) {}
func socket(_ sock: GCDAsyncSocket, didWriteDataWithTag tag: Int) {}
func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) {}

What I intend to do is while I change the value of the currentState, or I did set the received data to the msgData, in my controller I could capture the 2 values changed simultaneously.

How to make it by use ReactiveCocoa 5.0?

4

2 に答える 2

0

ReactiveSwift が提供する関数「combineLatest」を使用して、目標を達成しました。

まず、以下のように、2 つの MutableProperty の変数と 1 つの SignalProducer を発表します。

private var rac_state = MutableProperty<SocketState>(.unknown)
private var rac_msg = MutableProperty<Data>(Data())
public var rac_SocketStateChanged: SignalProducer<(SocketState, Data), NoError> {
    return SignalProducer.combineLatest(rac_state.producer, rac_msg.producer)
}

次に、ソケット デリゲート メソッドのrac_state.valueまたはrac_mas.valueを次のように変更します。

func socketDidDisconnect(_ sock: GCDAsyncSocket, withError err: Error?) {
    rac_state.value = .didDisconnected
}

最後に、コントローラーでオブザーバーを作成して、結合された SignalProducerをリッスンします。コードは次のとおりです。

func configTCPListen() {
    tcpManager.rac_SocketStateChanged
        .startWithValues { [weak self = self] (tuple) in
            switch tuple.0 {
            case .didDisconnected:
                print("TCP has disConnected!")
            default: break
            }
    }
}
于 2016-12-13T05:34:30.010 に答える
0

ReactiveSwiftMutablePropertyが提供するがあなたを満足させるかもしれません。あなたの意図は、KVOメカニズムがObjective-Cでできることと非常に似ていますが、Swiftにはありません。ただし、クラスは同じ機能を実装しており、変更が誰かによって観察される可能性があります。 以下のデモで、最も簡単な使用方法とその使用法を理解していただければ幸いです。MutableProperty
MutableProperty

// definition
let currentState: MutableProperty<SocketState> = MutableProperty(.unknown)
let msgData: MutableProperty<Data> = MutableProperty(Data())

// observe changes
currentState.producer.startWithValues { state in
    // process(state)
}
msgData.producer.startWithValues { data in
    // doSomething(withData data)
}

冗長な明示的な型推論を削除すると、上記のコードはクリーンでシンプルになります。

// definition
let currentState = MutableProperty(.unknown)
let msgData = MutableProperty(Data())

// observe changes
currentState.producer.startWithValues {
    // process($0)
}
msgData.producer.startWithValues {
    // doSomething(withData $0)
}
于 2016-12-13T05:13:01.270 に答える