No it doesn’t. The Bonjour service name and the local DNS name do not need to be related and, even when they are, it’s common for them to be significantly different. For some fun examples of this, see this post.Just adding .local to the host name solved the problem.
The only way to get the DNS name of a service is to resolve it.
Hmmm, I can’t spot the error. Rather than spend time debugging that I created a small test program that illustrates one way to do this. If you paste the code below into a new command-line tool project, it should be able to resolve any service you give it.But it still freezing my app just after service found
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Code Block import Foundation 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 { // If these fire the last reference to us was released while the resolve // was still in flight. That should never happen because we retain // ourselves on `start`. 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: 5.0) // Form a temporary retain loop to prevent us from being deinitialised // while the resolve is in flight. We break this loop in `stop(with:)`. 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 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)) } } func main() { let service = NetService(domain: "local.", type: "_ssh._tcp", name: "Fluffy") print("will resolve, service: \(service)") BonjourResolver.resolve(service: service) { result in switch result { case .success(let hostName): print("did resolve, host: \(hostName)") exit(EXIT_SUCCESS) case .failure(let error): print("did not resolve, error: \(error)") exit(EXIT_FAILURE) } } RunLoop.current.run() } main()