I did ask same question on Apple dev portal and there is other people with the same problem.
I have created simple reproducible project on GitHub: (follow steps in README) https://github.com/ChoadPet/NWListenerTest.git
I have screen and on present ConnectionListener is initialized and on dismiss it deinitialized (called stopListening()).
First time when open the screen everything is ok:
Listener stateUpdateHandler: waiting(POSIXErrorCode: Network is down)
Listener stateUpdateHandler: ready
" New connection: 10.0.1.2:50655 establish"
"Connection stateUpdateHandler: preparing"
"Connection stateUpdateHandler: ready"
but for next n-tries only this messages:
[] nw_path_evaluator_evaluate NECP_CLIENT_ACTION_ADD error [48: Address already in use]
[] nw_path_create_evaluator_for_listener nw_path_evaluator_evaluate failed
[] nw_listener_start_locked [L3] nw_path_create_evaluator_for_listener failed
Listener stateUpdateHandler: waiting(POSIXErrorCode: Network is down)
Listener stateUpdateHandler: failed(POSIXErrorCode: Address already in use)
It happens on iPhone 6 iOS 12.4.1, iPhone Xs Max iOS 13.3, iPhone 11 Pro iOS 13.5.1(also iOS 13.6)
but NOT on iPhone 7 Plus iOS 12.1.4, iPhone 11 iOS 13.5.1.
Here is my code for listening inbound connection:
final class ConnectionListener {
var dataReceivedHandler: ((Data) -> Void)?
private let port: UInt16
private let maxLength: Int
private var listener: NWListener!
private var connection: NWConnection!
init(port: UInt16, maxLength: Int) {
self.port = port
self.maxLength = maxLength
}
deinit {
print("❌ Deinitialize \(self)")
}
// MARK: Public API
func startListening() {
let parameters = NWParameters.tcp
parameters.allowLocalEndpointReuse = true
self.listener = try! NWListener(using: parameters, on: NWEndpoint.Port(integerLiteral: port))
self.listener.stateUpdateHandler = { state in print("Listener stateUpdateHandler: \(state)") }
self.listener.newConnectionHandler = { [weak self] in self?.establishNewConnection($0) }
self.listener.start(queue: .main)
}
func stopListening() {
listener.cancel()
connection?.cancel()
}
// MARK: Private API
private func establishNewConnection(_ newConnection: NWConnection) {
connection = newConnection
debugPrint(" New connection: \(String(describing: connection.endpoint)) establish")
connection.stateUpdateHandler = { [weak self] state in
guard let self = self else { return }
debugPrint("Connection stateUpdateHandler: \(state)")
switch state {
case .ready:
debugPrint("Connection: start receiving ✅")
self.receive(on: self.connection)
default: break
}
}
self.connection.start(queue: .main)
}
private func receive(on connection: NWConnection) {
connection.receive(minimumIncompleteLength: 1, maximumLength: maxLength, completion: { [weak self] content, context, isCompleted, error in
guard let self = self else { return }
if let frame = content {
self.dataReceivedHandler?(frame)
}
self.receive(on: connection)
})
}
}
If there is more information, which you need, let me know.
Thanks!