Currently I'm using NetServiceBrowser to find Bonjour services and to resolve corresponding addresses and port.
Looking to de-complicate my code I stumbled upon NWBrowser which seems to provide a very simple interface to deal with the Bonjour discovering.
However, the browseResultsChangedHandler sends back results and changes which contain an endpoint of enum case service. I'm trying to get address and port information from the results, but is seems the NWEndpoint would have to be of enum type .hostPort.
Ideally I would use the endpoint to connect to servers using NWConnection, however, I'm using another library which doesn't handle the NWEndpoint directly.
Are there (simple) ways of getting addresses and port information from an NWEndpoint.service result?
import Foundation
import Network
let browser = NWBrowser(for: .bonjour(type: "_http._tcp", domain: ""), using: NWParameters())
browser.browseResultsChangedHandler = { (results, changes) in
print("Results:")
for result in results
{
if case .service(let service) = result.endpoint
{
debugPrint(service)
}
else
{
assert(false, "This nevers gets executed")
}
}
print("Changes:")
for change in changes
{
if case .added(let added) = change
{
if case .service(let service) = added.endpoint
{
debugPrint(service)
}
else
{
assert(false, "This nevers gets executed")
}
}
}
}
browser.start(queue: DispatchQueue.main)
sleep(3)
This is possible.
First, you should not attempt to get a service's host and port until the user has actually chosen to connect to it - in most of your application, you should only store a reference to the service object, since Bonjour allows the service's host and port to change. From Bonjour Concepts:
This reduces DNS noise within your network and is core to the design of Bonjour. This means all my next suggestions should not happen in your
browseResultsChangedHandler.The officially recommended way to use
NWBrowserappears to be to open aNWConnectionto the service and use that instead of extracting the address and port and connecting manually. You can open the connection and the Network framework will handle resolving the actual host/port and connecting to the service.If you can't use this Network framework connection, I'd guess you could then close the connection (maybe need to wait for TCP to stop using the port) and use it for your own purposes.
You can also use the deprecated
NetServiceapi to resolve a service (although I haven't personally gotten this to work with a manually constructed instance) orDNSServiceResolve.There's a lot more context from an official Apple representative in this Apple Developer Forum thread.