NWBrowser browseResultsChangedHandler can't get a TXT record

In TicTacToe example two modifications were added:
  1. txtRecordObject was added to the listener:

           
Code Block swift
listener.service?.txtRecordObject = NWTXTRecord(["key1": "value1"])


2. browser.browseResultsChangedHandler was updated with code to get the txt record:

Code Block swift
browser.browseResultsChangedHandler = { results, changes in
            results.forEach { device in
                switch device.metadata {
                case .bonjour(let record):
                    print(record)
                case .none:
                    print("none")
                default:
                    break
                }
            }
self.delegate?.refreshResults(results: results)
}


With the help of Discovery.app I can see that tictactoe service with the txt record ("key1=value1") was successfully published, but NWBrowser returns .none for metadata instead of the TXT record object.

How can I get the TXT record from the published Bonjour service?

Accepted Reply

Try using the following to see if this improves your situation:

Code Block
/* Listener Side */
let txtData = NWTXTRecord(["0x09": "key=value", "0x08":"paper=A4", "0x07":"passreq"])
listener.service = NWListener.Service(name: self.name, type: "_tictactoe._tcp", domain: "local", txtRecord: txtData )
/* Browser Side */
let browser = NWBrowser(for: .bonjourWithTXTRecord(type: "_tictactoe._tcp", domain: nil), using: parameters)
browser.browseResultsChangedHandler = { results, changes in
results.forEach{ device in
print("Device metadata: \(device.metadata)")
switch device.metadata {
case .bonjour(let record):
print("Record: \(record.dictionary)")
case .none:
print("Record: none")
@unknown default:
print("Record: default")
}
}
}



Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Replies

Interesting. Are you able to see these values in iOS 13 using something like?

Code Block swift
listener.service = NWListener.Service(name: NetworkConstants.serviceName,
type: NetworkConstants.serviceType,
domain: "local",
txtRecord: NWTXTRecord(["key":"value"]))


And then something like:
Code Block swift
browser?.browseResultsChangedHandler = { [weak self] results, changes in
results.forEach { device in
print("Endpoint: \(device.endpoint) and record: \(device.metadata)")
}
}


Because I see <none> here as well on iOS 13. Note that I am not testing this in the TicTacToe sample, but just another local test bed project I have.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
The same <none> result with "local" added to both NWBrowser and NWListener. Tested on iOS 13 and 14.
FB8291155
Thank you for opening a bug report on this. I see it internally and have requested to be copied on updates for it.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Matt, thank you for your help and your attention to this problem!
Try using the following to see if this improves your situation:

Code Block
/* Listener Side */
let txtData = NWTXTRecord(["0x09": "key=value", "0x08":"paper=A4", "0x07":"passreq"])
listener.service = NWListener.Service(name: self.name, type: "_tictactoe._tcp", domain: "local", txtRecord: txtData )
/* Browser Side */
let browser = NWBrowser(for: .bonjourWithTXTRecord(type: "_tictactoe._tcp", domain: nil), using: parameters)
browser.browseResultsChangedHandler = { results, changes in
results.forEach{ device in
print("Device metadata: \(device.metadata)")
switch device.metadata {
case .bonjour(let record):
print("Record: \(record.dictionary)")
case .none:
print("Record: none")
@unknown default:
print("Record: default")
}
}
}



Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Matt, thank you! It works now! For some reasons I didn’t find .bonjourWithTXTRecord before and was using just .bonjour descriptor…