Rufus_12 Rufus_12 - 15 days ago 5
Swift Question

Bonjour Service Browser with Swift does not fetch serviceinfo

The service I want to connect to is published via Bonjour.

I can find all the info with the Bonjour Browser, however if I try to gather the data programmatically, the only value I get, is the name of the service.

The NetService delegate is set and the function netServiceWillPublish is called.
The functions DidNotPublish or DidPublish are not executed.

The function netServiceBrowser gets all published netServices, but all properties are set to the default value of the datatype.

import UIKit

class BMNSDelegate : NSObject, NetServiceDelegate {
func netServiceWillPublish(_ sender: NetService) {
print("netServiceWillPublish:\(sender)"); //This method is called
}


func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]){
print("didNotPublish:\(sender)");
}

func netServiceDidPublish(_ sender: NetService) {
print("netServiceDidPublish:\(sender)");
}
func netServiceWillResolve(_ sender: NetService) {
print("netServiceWillResolve:\(sender)");
}

func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
print("netServiceDidNotResolve:\(sender)");
}

func netServiceDidResolveAddress(_ sender: NetService) {
print("netServiceDidResolve:\(sender)");
}

func netService(_ sender: NetService, didUpdateTXTRecord data: Data) {
print("netServiceDidUpdateTXTRecordData:\(sender)");
}

func netServiceDidStop(_ sender: NetService) {
print("netServiceDidStopService:\(sender)");
}

func netService(_ sender: NetService,
didAcceptConnectionWith inputStream: InputStream,
outputStream stream: OutputStream) {
print("netServiceDidAcceptConnection:\(sender)");
}
}

class BMBrowserDelegate : NSObject, NetServiceBrowserDelegate, NetServiceDelegate {

func netServiceBrowser(_ netServiceBrowser: NetServiceBrowser,
didFind netService: NetService,
moreComing moreServicesComing: Bool) {
let nsnsdel = BMNSDelegate()
netService.delegate = nsnsdel
netService.resolve(withTimeout: 1)
print(netService.domain) // local.
print(netService.name) // This property is correct
print(netService.type) // _http._tcp.
print(netService.addresses) // Optional([])
print(netService.hostName) // nil
print(netService.port) // -1
print(moreServicesComing) //false
}

}


let SERVICE_TYPE = "_http._tcp."
let BM_DOMAIN = "local."
let browser = NetServiceBrowser()
let nsbdel = BMBrowserDelegate()
browser.delegate = nsbdel
browser.searchForServices(ofType: SERVICE_TYPE, inDomain: BM_DOMAIN)
RunLoop.current.run()

Answer

The error is that the services which are found in the ServiceBrowserDelegate function are not saved anywhere and therefore are discarded at the end of the function.

I found a working example here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/61f0c753a080040e4a74b912e6c18dd97fe8bcaa/bk2ch24p853bonjour/ch37p1101bonjour/ViewController.swift

class ViewController: UIViewController, NetServiceBrowserDelegate, NetServiceDelegate {
var nsb : NetServiceBrowser!
var services = [NetService]()

@IBAction func doButton (_ sender: Any!) {
    print("listening for services...")
    self.services.removeAll()
    self.nsb = NetServiceBrowser()
    self.nsb.delegate = self
    self.nsb.searchForServices(ofType:"_daap._tcp", inDomain: "")
}

func updateInterface () {
    for service in self.services {
        if service.port == -1 {
            print("service \(service.name) of type \(service.type)" +
                " not yet resolved")
            service.delegate = self
            service.resolve(withTimeout:10)
        } else {
            print("service \(service.name) of type \(service.type)," +
                "port \(service.port), addresses \(service.addresses)")
        }
    }
}

func netServiceDidResolveAddress(_ sender: NetService) {
    self.updateInterface()
}

func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didFind aNetService: NetService, moreComing: Bool) {
    print("adding a service")
    self.services.append(aNetService)
    if !moreComing {
        self.updateInterface()
    }
}

func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didRemove aNetService: NetService, moreComing: Bool) {
    if let ix = self.services.index(of:aNetService) {
        self.services.remove(at:ix)
        print("removing a service")
        if !moreComing {
            self.updateInterface()
        }
    }
  }
}