Hmmm, I tested this stuff while working on TN3179 and I got pretty reasonable results, so I’m surprised you’re having problems. Just to be sure, I tested it again today.
Using Xcode 16.2 on macOS 14.7.1, I created a small test project that runs a browser and logs the result. The core code is at the end of this post. The startStop()
method is wired up to a Start/Stop button.
I copied this to a ‘clean’ macOS 15.1 VM, one that’s never seen this app before.
In the VM, I moved the app to Applications folder.
In Console, I started monitoring the com.example.apple-samplecode.Test770563
subsystem.
I ran the app and clicked the Start/Stop button, resulting in two things:
-
In the UI, I saw the Local Network alert.
-
In Console, I saw these log entries:
browser will start
browser did change state, new: ready
This is a bit weird, but it’s reasonable enough. It’s in the .ready
state, but the system hasn’t delivered any results because the user hasn’t made a choice yet.
In the alert, I clicked Deny, resulting in:
browser did change state, new: waiting(-65570: PolicyDenied)
That’s definitely what I was expecting.
In the app I clicked the Start/Stop button again, resulting in:
browser will stop
Then I clicked it again, resulting in:
browser will start
browser did change state, new: ready
browser did change state, new: waiting(-65570: PolicyDenied)
This time it went to the .waiting(…)
state promptly.
Please try this sequence in your environment and let me know what you get.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
let log = Logger(subsystem: "com.example.apple-samplecode.Test770563", category: "browser")
var browserQ: NWBrowser? = nil
func start() -> NWBrowser {
log.log("browser will start")
let browser = NWBrowser(for: .bonjour(type: "_ssh._tcp", domain: "local"), using: .tcp)
browser.stateUpdateHandler = { newState in
self.log.log("browser did change state, new: \("\(newState)", privacy: .public)")
}
browser.browseResultsChangedHandler = { newResults, change in
self.log.log("browser did receive results, count: \(newResults.count)")
}
browser.start(queue: .main)
return browser
}
func stop(browser: NWBrowser) {
log.log("browser will stop")
browser.stateUpdateHandler = nil
browser.cancel()
}
func startStop() {
if let browser = self.browserQ {
self.browserQ = nil
self.stop(browser: browser)
} else {
self.browserQ = self.start()
}
}