I changed my PeerConnection class to follow the code the way that you did but it's not working correctly. There are 3 issues
1st issue, the echoData is always sent, however inside the PeerConnection class, connection.receive(minimumIncompleteLength.., inside if let data = data, !data.isEmpty { } I call receivedIncoming() again but the returned echoData is nil.
2nd issue, the only way I can get it to keep listening is if I move receivedIncoming() at the very top of the completionHandler like below but the echoData that comes back is is still nil
connection.receive(minimumIncompleteLength.. { ...
self?.receivedIncoming()
if let err = error { ... }
if let data = data, !data.isEmpty {
// ...
} else {
print("=-=-=-=-= Receive data is nil -=-=-=-=-=") // returned echoData is always nil
}
}
3rd issue, inside the same connection.receive(minimumIncompleteLength.., if there are any problems I remove any connections via delegate?.removeIncomingConnection(connection), the ViewController class that conforms to it will remove the connection thus removing the encodedData (a cell shows the data). This is a separate issue relating more so to my other question. But the fact that the returned echoData is nil is causing collateral damage
Coded like your example:
protocol PeerConnectionDelegate: class {
func sendOutgoing(_ connection: NWConnection)
func removeIncomingConnection(_ connection: NWConnection)
func readDataFromIncomingConnection(_ data: Data, _ connection: NWConnection)
}
final class PeerConnection: Hashable {
// outgoing init is the same
// incoming init is the same
func startIncomingConnection() {
connection.stateUpdateHandler = { [weak self](nwConnectionState) in
case .ready:
self?.receivedIncoming()
}
func receivedIncoming() {
guard let connection = connection else { return }
connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { [weak self](data, context, isComplete, error) in
if let err = error {
print("received error: (err.localizedDescription)")
self?.delegate?.removeIncomingConnection(connection)
return
}
if let data = data, !data.isEmpty {
let echoString = String(decoding: data, as : UTF8.self)
if echoString == "12345" {
print("echo received, stop listening")
return
}
self?.delegate?.readDataFromIncomingConnection(data, connection) // vc conforms to this
self?.receivedIncoming()
} else {
print("=-=-=-=-= Receive data is nil -=-=-=-=-=") // returned echoData gets hit here
self?.delegate?.removeIncomingConnection(connection)
}
}
}
}
extension ViewController: PeerConnectionDelegate {
// ... other peerConnection Delegate methods
func readDataFromIncomingConnection(_ data: Data, _ connection: NWConnection) {
guard let decodedData = NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) ... else { return }
// display decodedData inside a cell
// first make sure connection isn't already in the array, the arrOfConnections is an ivar
arrOfConnections.append(connection)
let echoData = "12345".data(using: String.Encoding.utf8)
let message = NWProtocolWebSocket.Metadata(opcode: .text)
let context = NWConnection.ContentContext(identifier: "send", metadata: [message])
connection.send(content: echoData, contentContext: context, isComplete: true, completion: .contentProcessed({
(error) in
if let error = error { return }
print("echoData successfully sent") // this always prints
guard let echoData = echoData else { return }
let echoString = String(decoding: echoData, as : UTF8.self)
if echoString == "12345" {
print("here is the echoData that was sent: \(backToString)") // always prints
}
}))
}