I am trying to implement the Bonjour NetServiceBrowser in Swift3 in order to discover hosts on my network.
When I manually search in the terminal using the following command I will find the hosts.
dns-sd -B
However, when I try to use the NetServiceBrowser in Swift (see code below), it will only print "starting search..". I implemented this class by following the Bonjour documentation.
I do not understand what is going wrong. Does Bonjour work different for Swift? I could not find a working example online. I have tried several variants on the domain
("local", "local.", "") or several variants for name
.
class ZeroConf: NSObject, NetServiceBrowserDelegate, NetServiceDelegate{
var browser: NetServiceBrowser!
var services = [NetService]()
let domain = "local"
let name = "_http._tcp"
func startSearch(){
self.services.removeAll()
self.browser = NetServiceBrowser()
self.browser.delegate = self
self.browser.searchForServices(ofType: name, inDomain: domain)
}
func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]) {
debugPrint(errorDict)
}
func netServiceBrowserWillSearch(_ browser: NetServiceBrowser) {
print("starting search..")
}
func netServiceBrowserDidStopSearch(_ browser: NetServiceBrowser) {
print("Stoped search")
}
func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
print("error in search")
debugPrint(errorDict)
}
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
print("found service")
services.append(service)
debugPrint(service)
}
func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool) {
if let ix = self.services.index(of:service) {
self.services.remove(at:ix)
print("removing a service")
}
}
func netServiceDidResolveAddress(_ sender: NetService) {
print("did resolve address")
}
}
I found out why it wasn't working for me. I tried to execute the code from the main loop while it apparently should be called from a different thread. Hence, I changed my code in startSearch
to
DispatchQueue.main.async {
self.browser.schedule(in: RunLoop.current, forMode: .defaultRunLoopMode)
self.browser.searchForServices(ofType: self.name, inDomain: self.domain)
RunLoop.current.run()
}