Skip to content

Instantly share code, notes, and snippets.

@narciszait
Forked from fdstevex/allbonjour.swift
Created October 7, 2022 07:24
Show Gist options
  • Save narciszait/3f3b0ec16204b7feacd95944c61d340d to your computer and use it in GitHub Desktop.
Save narciszait/3f3b0ec16204b7feacd95944c61d340d to your computer and use it in GitHub Desktop.
Swift command-line script to find Bonjour services on your local network.
#!/usr/bin/swift
// Swift script to search for Bonjour services on the local network.
// Found services are printed to the console.
import Foundation
import CoreFoundation
// Inner search, finds services of a particular type
class ServicesDiscoverer : NSObject, NSNetServiceBrowserDelegate {
let browser = NSNetServiceBrowser()
let service: NSNetService
let allServicesDiscoverer: AllServicesDiscoverer
// Save the list of services until we have them all before printing
var serviceNames = Array<String>()
init(service: NSNetService, allServicesDiscoverer: AllServicesDiscoverer) {
self.service = service
self.allServicesDiscoverer = allServicesDiscoverer
super.init()
browser.delegate = self
}
func start() {
let parts = service.type.componentsSeparatedByString(".")
let type = "\(service.name).\(parts[0])."
browser.searchForServicesOfType(type, inDomain: "local.")
}
func netServiceBrowser(browser: NSNetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
self.allServicesDiscoverer.removeDiscoverer(self);
}
func netServiceBrowserDidStopSearch(browser: NSNetServiceBrowser) {
self.allServicesDiscoverer.removeDiscoverer(self);
}
func netServiceBrowser(browser: NSNetServiceBrowser, didFindService service: NSNetService, moreComing: Bool) {
serviceNames.append(service.name)
if (!moreComing) {
NSOperationQueue.mainQueue().addOperationWithBlock {
for name in self.serviceNames {
print("\(self.service.name) \(self.service.type) \"\(name)\"")
}
print("")
self.allServicesDiscoverer.removeDiscoverer(self);
}
}
}
}
// Outer search, searches for all the types of services available, and uses
// ServicesDiscoverer to search for instances of those services.
class AllServicesDiscoverer : NSObject, NSNetServiceBrowserDelegate, NSNetServiceDelegate {
let browser = NSNetServiceBrowser()
var serviceDiscoverers = Set<ServicesDiscoverer>()
var searchComplete = false
func start() {
browser.delegate = self
browser.searchForServicesOfType("_services._dns-sd._udp.", inDomain: "local.")
}
func removeDiscoverer(discoverer: ServicesDiscoverer) {
serviceDiscoverers.remove(discoverer)
if (searchComplete && serviceDiscoverers.isEmpty) {
exit(0)
}
}
func netServiceBrowser(browser: NSNetServiceBrowser, didFindService service: NSNetService, moreComing: Bool) {
let serviceDiscoverer = ServicesDiscoverer(service:service, allServicesDiscoverer: self)
serviceDiscoverers.insert(serviceDiscoverer)
serviceDiscoverer.start()
if (!moreComing) {
searchComplete = true
}
}
}
// Start the search
let serviceDiscoverer = AllServicesDiscoverer()
serviceDiscoverer.start()
// The search is asynchronous, so run the run loop and let the end of the search exit the process.
NSRunLoop.currentRunLoop().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment