NWConnection cancel

Hi, i work on some application which should send data between devices, I implement that in Network Framwork instead of socket.

Everything works like it should, except one situation which i do not understand correctly.


When i open NWConnection to some endpoint, i can observe states - all works fine from setting uoo to ready.

I can send data between, without problems.

Now i want to solve in nice way situation when one side of connection is closed - manually or by an issue.


I do close connection by cancelCurrentEndpoint - there are no other endpoints on that connection - so as i expect State should change to cancelled, but it goes to failed on the device i close it with information that network is down.

I don't undersand why nothing happens on the endpoint this connection - no StateUpdate


When i use cancel() method, it works like expected - on my side of connection statusChange to cancelled.

I can make some code to send to all devices information about closing connection, but it is not solution i want.


Have someone got that issue and explain how those cancel - cancelEndPoint method works, on Apple Documentation there is nothing to read.

Post not yet marked as solved Up vote post of HPmax Down vote post of HPmax
1.5k views

Replies

What transport protocol are you using (TCP or UDP)?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
@HPmax, I know it's a "bit" late, but this should work if you are using plain TCP (no TLS). You must send() with data=nil and a context that has .isFinal=true (such as .finalMessage).

as an addition to @jakajancar's answer let me introduce an example code ;

Send a message to the connection you want to cancel; set contentContext: parameter to NWConnection.ContentContext.finalMessage, then cancel the connection:

connectionYouWantToCancel.send(content: nil, contentContext: .finalMessage, isComplete: true, completion: .idempotent)
connectionYouWantToCancel.cancel()

And read the message on the other device; check if the context is final

connectionOnTheOtherDevice.receiveMessage { (content, context, isComplete, error) in
    if let context = context, context.isFinal {
        connectionOnTheOtherDevice.cancel()
        // any other logic if needed.
        return
    }
        
    // other logic
}

At least I'm handling the problem this way without any delay or any unexpected behaviour.