I have a scanner class to scan list of all bonjour services available with an option for the user to search for all the devices in a certain bonjour service name.
Everything works great! except when I remove my iphone from the cable then I can't see all the bonjour services.
Any ideas y?
Note: My iphone any my laptop connected via wifi at the same network. But it seems that the iphone detects the bonjour services through my laptop.
here is my Class though I am sure its not about my class implementation.
class ScannerViewController: UIViewController {
@IBOutlet weak var serviceTextField: UITextField!
@IBOutlet weak var transportLayerTextField: UITextField!
@IBOutlet weak var domainTextField: UITextField!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var allBonjourBtn: UIButton!
@IBOutlet weak var searchBtn: UIButton!
let searchForAllString = "_services._dns-sd._udp."
var services = [NetService](){
didSet{
self.tableView.reloadData()
}
}
private lazy var serviceBrowser = NetServiceBrowser()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 150
self.tableView.rowHeight = UITableViewAutomaticDimension
self.serviceBrowser.delegate = self
self.searchBtn.makeCircularEdges()
self.allBonjourBtn.makeCircularEdges()
}
@IBAction func allBonjourPressed(_ sender: UIButton) {
self.startBrowsing(all: true)
}
@IBAction func searchPressed(_ sender: UIButton) {
self.startBrowsing(all: false)
}
func setBrowserObj() -> (serviceName: String, transportLayer: String, domain: String){
let sName = (self.serviceTextField?.text ?? "").trim
let tl = (self.transportLayerTextField?.text ?? "").trim
let text = (self.domainTextField?.text ?? "").trim
let domain = (text == "" ? text: "\(text).")
print("\(sName).\(tl).", domain)
return (serviceName: "_\(sName)", transportLayer: "_\(tl)", domain: "\(domain)")
}
func startBrowsing(all: Bool){
self.hideKeyboard()
self.serviceBrowser.stop()
self.services = []
let result = self.setBrowserObj()
self.serviceBrowser.delegate = self
if all {
self.serviceBrowser.searchForServices(ofType: searchForAllString, inDomain: "\(result.domain)")
}else{
self.serviceBrowser.searchForServices(ofType: "\(result.serviceName).\(result.transportLayer).", inDomain: "\(result.domain)")
}
}
}
extension ScannerViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.services.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else{
return UITableViewCell()
}
guard self.services.count > 0 else{
return cell
}
let service = self.services[indexPath.row]
cell.textLabel?.text = "Name: \(service.name)\nDomain: \(service.domain)\nPort: \(service.port)"
return cell
}
}
extension ScannerViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let nextTag = textField.tag + 1
if let nextTextField = textField.superview?.viewWithTag(nextTag) {
nextTextField.becomeFirstResponder()
}else{
self.hideKeyboard()
}
return false
}
func hideKeyboard() {
self.serviceTextField?.resignFirstResponder()
self.transportLayerTextField?.resignFirstResponder()
self.domainTextField?.resignFirstResponder()
}
}
extension ScannerViewController: NetServiceBrowserDelegate, NetServiceDelegate {
func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
print("Error serching for service")
print("Errors: \(errorDict.keys)\n")
}
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
service.delegate = self
self.services.append(service)
}
func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool) {
service.delegate = nil
self.removeServiceFromList(serviceObj: service)
}
///Removes the service from the current list.
func removeServiceFromList(serviceObj: NetService){
for (index, sev) in self.services.enumerated() {
if sev == serviceObj {
self.services.remove(at: index)
}
}
}
}
Update:
I am using the command line to check the available bonjour services and I have noticed:
Running
dns-sd -B _services._dns-sd._udp local.
will list couple of services that I believe is brodcasted from my machine only.Running
dns-sd -B _ipp._tcp local.
ordns-sd -B _http._tcp local.
will list all things uses theipp
/http
services.
The real question why the ipp
or http
service types did not appear when I used the command dns-sd -B _services._dns-sd._udp local.
??? based on all my readings online everybody saying that this command should list all bonjour services availble and active on the network! But thats not what is happening with me.
Note: I am connected to the network via wifi and I can't use a cable since I do not have an adapter.
Attached a snapshot of the result.
Update 2
Finally I figured it out. I guess the issue was with the wifi network at work that was blocking the list of services. because when I tried it home I was able to see all the bonjour services with no issues.