Post

Replies

Boosts

Views

Activity

Reply to Bonjour for discovering a specific device's ip
Hello, I work with @eskimo code and it runs perfect, but I have one problem. In my local network are more devices and I find only one of them. Or do I get all of them and only one device is issued with switch result { case .success(let hostName): print("did resolve, host: \(hostName)") ? how I get the other one too? --> at the end, I would like to add them to a List for using later
Nov ’21
Reply to Bonjour for discovering a specific device's ip
thank you for the fast answer. I think you didn't understand me correctly. :-) i have some devices, but all have the same serviceType and name:  let service = NetService(domain: "local.", type: "_ssh._tcp", name: "mesh")  my problem is that your code find only one device of them. if I switch the founded device off, I can find the next but I need them all I hope my explanation is understandable
Nov ’21
Reply to Bonjour for discovering a specific device's ip
I've try to follow your recommend to use NWBrowser but i got only the results "start function" and "end function" with this code public func findServices() {         print("start function")         let parameter = NWParameters()         parameter.includePeerToPeer = true         let browser = NWBrowser(for: .bonjour(type: "_mesh-http._tcp.", domain: "local."), using: parameter)         browser.stateUpdateHandler = { state in             switch state {             case .ready:                 print("the sericeHandler is ready")             case .failed(let error):                 print("error:", error.localizedDescription)             default:                 break             }         }         browser.browseResultsChangedHandler = { result, changed in             print("in handler")             result.forEach { device in                 device.interfaces.forEach {interface in                     //ADD THE NAME TO A LIST                     print(interface.name)                 }             }             changed.forEach{change in                 switch change                 {                 case .identical:                     print("no change")                     break                 case .added:                     print("A new result was discovered. ")                 case .removed:                     print("A previously discovered result was removed.")                 default:                     break                 }             }         }         print("end function")         browser.start(queue: .main)     } now my Solution. Please leave feedback --> it's a combination of some answers in this forum private func findService(with name:String) {         let service = NetService(domain: "local.", type: "_mesh-http._tcp.", name: name)         print("will resolve, service: \(service)")         BonjourResolver.resolve(service: service) { result in             switch result {             case .success(let hostName):                 print("did resolve, host: \(hostName)")             case .failure(let error):                 print("did not resolve, error: \(error)")             }         }     }     public func findServices()     {         let agent = BrowserAgent()         let browser = NetServiceBrowser()         browser.delegate = agent         browser.searchForServices(ofType: "_mesh-http._tcp.", inDomain: "local.")         browser.schedule(in: RunLoop.main, forMode: .common)         DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { // give the browser time to brows                    print("finish")             for device in agent.getDevices(){                 print(device)                 self.findService(with: device)             }                 }         RunLoop.main.run()     } final class BonjourResolver: NSObject, NetServiceDelegate {     typealias CompletionHandler = (Result<(String, Int), Error>) -> Void     @discardableResult     static func resolve(service: NetService, completionHandler: @escaping CompletionHandler) -> BonjourResolver {         precondition(Thread.isMainThread)         let resolver = BonjourResolver(service: service, completionHandler: completionHandler)         resolver.start()         return resolver     }          private init(service: NetService, completionHandler: @escaping CompletionHandler) {         // We want our own copy of the service because we’re going to set a         // delegate on it but `NetService` does not conform to `NSCopying` so         // instead we create a copy by copying each property.         let copy = NetService(domain: service.domain, type: service.type, name: service.name)         self.service = copy         self.completionHandler = completionHandler     }          deinit {         assert(self.service == nil)         assert(self.completionHandler == nil)         assert(self.selfRetain == nil)     }     private var service: NetService? = nil     private var completionHandler: (CompletionHandler)? = nil     private var selfRetain: BonjourResolver? = nil     private func start() {         precondition(Thread.isMainThread)         guard let service = self.service else { fatalError() }         service.delegate = self         service.resolve(withTimeout: 3.0)         selfRetain = self     }     func stop() {         self.stop(with: .failure(CocoaError(.userCancelled)))     }     private func stop(with result: Result<(String, Int), Error>) {         precondition(Thread.isMainThread)         self.service?.delegate = nil         self.service?.stop()         self.service = nil         let completionHandler = self.completionHandler         self.completionHandler = nil         completionHandler?(result)         selfRetain = nil     }     func netServiceDidResolveAddress(_ sender: NetService) {         let hostName = sender.hostName!         let port = sender.port         if let data = sender.txtRecordData() {             let dict = NetService.dictionary(fromTXTRecord: data)             print(dict.mapValues { String(data: $0, encoding: .utf8) })         }         print("\(hostName)  \(port)")         self.stop(with: .success((hostName, port)))     }     func netService(_ sender: NetService, didNotResolve errorDict: [String: NSNumber]) {         let code = (errorDict[NetService.errorCode]?.intValue)             .flatMap { NetService.ErrorCode.init(rawValue: $0) }             ?? .unknownError         let error = NSError(domain: NetService.errorDomain, code: code.rawValue, userInfo: nil)         self.stop(with: .failure(error))     } } class ServiceAgent : NSObject, NetServiceDelegate {     func netServiceDidResolveAddress(_ sender: NetService) {         if let data = sender.txtRecordData() {             let dict = NetService.dictionary(fromTXTRecord: data)             print("Resolved: \(dict)")             print(dict.mapValues { String(data: $0, encoding: .utf8) })         }     } } class BrowserAgent : NSObject, NetServiceBrowserDelegate {     var currentService:NetService?      let serviceAgent = ServiceAgent()     var devices = [String]()    public func getDevices() -> [String]{         return devices     }     func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {         print("domain found: \(domainString)")     }     func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {         print("service found: \(service.name)")         devices.append(service.name)     } } I make the double search because the result of func netServiceBrowser have no Mac address in the NetService-Object(it's always empty) and I need this. the Solution works but I think it's very awkward
Nov ’21
Reply to Bonjour for discovering a specific device's ip
yes, I need to connect with all devices with this service. I send a httpRequest and get some parameter from all devices. Then I create a dynamic ListView to show DeviceInformations like Devicename, temperature, lightstate... i find out that all devices have hostname like device.local device-1.local device-2.local .... so I have the best results if search with a for_loop private func fillHostName()     {         let number = 30         var counter = 0         self.hostNames.removeAll()         if newHostNames.count == 0 {             while counter < number  {                 if counter == 0                 {                     self.hostNames.append(String("device.local"))                 }                 else                 {                     self.hostNames.append(String("device-\(counter).local"))                 }                 counter += 1             }         }             else             {                 self.hostNames = self.newHostNames             }     } self.hostNames.forEach{ host in                     self.getMeshInfo(from: host)                 usleep(80000) } I know that is "stupid polling" but it works absolut perfekt on very fast. is there a better way?
Dec ’21