Как получить IP и PORT сервиса, опубликованного AVAHI в iOS swift?

Я использую NSNetServiceBrowser и могу найти список сервисов, опубликованный AVAHI в "didFindService", который выглядит так: Сервис появился: локальный. _https._tcp. TEMP-Mobileyes5-1C497B9ED382 -1 Сервис появился: локальный. _https._tcp. TEMP-Mobileyes5-1C497B8E3916 -1 Сервис появился: локальный. _https._tcp. ТЕМП-Mobileyes5-1C497B9ED380 -1

Но не удалось найти IP-адрес и номер порта той же службы. Я обнаружил, что код не достигает "netServiceDidResolveAddress" Мой код:

class ServiceDiscovery : NSObject, NSNetServiceBrowserDelegate,NSNetServiceDelegate {

    var _browser:NSNetServiceBrowser!
    var _service: NSNetService!
    var services = [NSNetService]()
    override init() {
        _browser = NSNetServiceBrowser()
        super.init()
        _browser.delegate = self
        _browser.includesPeerToPeer = true
        _browser.searchForServicesOfType("_https._tcp.", inDomain: "local.")
        _browser.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)

    }


    func netServiceBrowser(browser: NSNetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
        print(domainString)
    }

    func netServiceBrowser(aNetServiceBrowser: NSNetServiceBrowser, didFindService aNetService: NSNetService, moreComing: Bool) {
       print("Service appeared: \(aNetService)")
        services.append(aNetService)
        aNetService.delegate = self
        aNetService.resolveWithTimeout(5.0)
    }


    func netServiceBrowser(browser: NSNetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
        print(errorDict)
    }

    func netServiceBrowser(browser: NSNetServiceBrowser, didRemoveService service: NSNetService, moreComing: Bool) {
        print("Service removed: \(service)")

    }

    func netService(sender: NSNetService, didNotResolve errorDict: [String : NSNumber]) {
        print(errorDict)
    }

    func netServiceDidResolveAddress(sender: NSNetService) {
        print(sender.addresses![0])
    }


}

2 ответа

Возможной причиной вашей проблемы может быть то, что вы звоните

aNetService.resolveWithTimeout(5.0)

внутри другой функции, так как только

didFindService

По окончании локальная переменная aNetService уничтожается (так как это локальная переменная для функции didFindService)

РЕШЕНИЕ

Я вижу, что вы уже определили переменную вверху с областью действия класса "_service". Следовательно, используйте это, используя

_service = aNetService
_service.resolveWithTimeout(5.0)

внутри вашего didFindService это должно решить вашу проблему. И, netServiceDidResolveAddress должен быть вызван сейчас.

import Foundation
class ServiceDiscovery : NSObject, NetServiceBrowserDelegate,NetServiceDelegate {

    var _browser:NetServiceBrowser!
    var _service: NetService!
    var services = [NetService]()


    func searchServices(){
        self.services.removeAll()
        _browser = NetServiceBrowser()
        _browser.delegate = self
        _browser.includesPeerToPeer = true
        _browser.searchForServices(ofType: "_https._tcp.", inDomain: "local.")
        _browser.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
    }


    func updateInterface () {
        for service in self.services {
            if service.port == -1 {
                print("service \(service.name) of type \(service.type)" +
                    " not yet resolved")
                service.delegate = self
                service.resolve(withTimeout: 0.0)
            } else {

                let deviceLanController = DeviceLanController()
                let dict = NetService.dictionary(fromTXTRecord: service.txtRecordData()!)
                let id = self.copyStringFromTXTDict(dict as [AnyHashable: Any]?, which: "id")
                var ipAdd = ""
                if let address = service.addresses{
                if let addressOfFirstDevice = address.first{
                    let theAddress = addressOfFirstDevice as Data
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    if getnameinfo((theAddress as NSData).bytes.bindMemory(to: sockaddr.self, capacity: theAddress.count), socklen_t(theAddress.count),
                                   &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
                        if let numAddress = String(validatingUTF8: hostname) {
                            ipAdd = numAddress
                        }
                    }

                    if let serviceId = id{
                        deviceLanController.setDeviceAvailable(serviceId, host: ipAdd, port: "\(service.port)")
                    }
                }
                }
            }
        }
    }


    fileprivate func copyStringFromTXTDict(_ dict: [AnyHashable: Any]?, which: String) -> String? {
        // Helper for getting information from the TXT data
        var resultString: String? = nil
        if let data = dict?[which as NSObject] as! Data? {
            resultString = String(data: data, encoding: String.Encoding.utf8)!

        }
        return resultString
    }



    func netServiceBrowser(_ browser: NetServiceBrowser, didFindDomain domainString: String, moreComing: Bool) {
        print("didFindDomain")
        print(domainString)
    }

    func netServiceBrowser(_ aNetServiceBrowser: NetServiceBrowser, didFind aNetService: NetService, moreComing: Bool) {
        print("didFindService")
        self.services.append(aNetService)
        if !moreComing {
            aNetService.stop()
            self.updateInterface()
        }
    }

    func netServiceBrowser(_ browser: NetServiceBrowser, didRemove service: NetService, moreComing: Bool){
        print("didRemoveService")
        if let ix = self.services.index(of: service) {
            self.services.remove(at: ix)
            print("removing a service")
            if !moreComing {
                self.updateInterface()
            }
        }
    }

    func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String : NSNumber]) {
        print("didNotSearch")
        print(errorDict)
    }



    func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
        print("didNotResolve",sender)
        print(errorDict)

    }

    func netServiceWillResolve(_ sender: NetService) {
        print("netServiceWillResolve",sender)
    }
    func netServiceDidResolveAddress(_ sender: NetService) {
        print("netServiceDidResolveAddress",sender)
       self.updateInterface()
    }

}

Этот ответ решил мою проблему. Я разрешаю и сохраняю каждый адрес в моей coredata, чтобы я мог использовать этот адрес для подключения локальных сервисов.

Другие вопросы по тегам