Swift Network.framework Study 20191209「Handling Path Updates」

# Study

Network.framework
Study：「Handling Path Updates」
下記メソッドを実装
内容はパラメータを表示

- pathUpdateHandler<br />
ネットワークインタフェース(NWPath)変更時にコールされる<br />
最初は、コネクション生成時にコールされる様です
- viabilityUpdateHandler<br />
送受信可能になるとコールされる<br />
NWState「ready」後にコールされる様です
- betterPathUpdateHandler<br />
優先される代替えネットワークインタフェース(NWPath)時にコールされる<br />
試せていないです

## 環境

Client：Swift、Xcode
Server：Java、NetBeans 12/8と一緒のため割愛

# Client Source Swift

## main.swift

```swift
import Foundation
import Network

var sendAndReceive = SendAndReceive(host: "localhost", port: 7777, nWParameters: .tcp)

sendAndReceive.startConnection()

while sendAndReceive.running {
    sleep(1)
}
```

## SendAndReceive.swift

```swift
import Foundation
import Network

class SendAndReceive {
    public var running = true
    private var host:NWEndpoint.Host
    private var port:NWEndpoint.Port
    private var nWParameters: NWParameters
    
    init(host:NWEndpoint.Host, port:NWEndpoint.Port, nWParameters: NWParameters) {
        self.host = host
        self.port = port
        self.nWParameters = nWParameters
    }

    func startConnection() {
        let myQueue = DispatchQueue(label: "ExampleNetwork")
        let connection = NWConnection(host: host, port: port, using: nWParameters)
        connection.pathUpdateHandler = { (nWPath) in
            print("pathUpdateHandler:\(nWPath)")
        }
        connection.viabilityUpdateHandler = { (viability) in
            print("viabilityUpdateHandler:\(viability)")
        }
        connection.betterPathUpdateHandler = {(better) in
            print("betterPathUpdateHandler:\(better)")
        }
        connection.stateUpdateHandler = { (newState) in
            switch(newState) {
            case .setup:
                print("setup")
            case .waiting(let error):
                print("waiting")
                print(error)
            case .preparing:
                print("preparing")
            case .ready:
                print("ready")
                self.sendMessage(connection)
            case .failed(let error):
                print("failed")
                print(error)
            case .cancelled:
                print("cancelled")
            @unknown default:
                print("defaults")
                break
            }
        }
        connection.start(queue: myQueue)
        self.receive(nWConnection: connection)
    }

    func sendMessage(_ connection: NWConnection) {
        let data = "Example Send Data".data(using: .utf8)
        let completion = NWConnection.SendCompletion.contentProcessed { (error: NWError?) in
            print("送信完了")
        }
        connection.send(content: data, completion: completion)
    }

    func receive(nWConnection:NWConnection) {
        nWConnection.receive(minimumIncompleteLength: 1, maximumLength: 5, completion: { (data, context, flag, error) in
            print("receiveMessage")
            if let data = data {
                let receiveData = [UInt8](data)
                print(receiveData)
                print(flag)
                if(flag == false) {
                    self.receive(nWConnection: nWConnection)
                }
            }
            else {
                print("receiveMessage data nil")
            }
        })
    }

}
```

# Output(送信完了まで)

```tex
pathUpdateHandler:satisfied (Path is satisfied), interface: lo0
preparing
ready
viabilityUpdateHandler:true
送信完了
```