Swift使用NWBrowser实现Bonjour服务扫描遇错误求助
解决NWBrowser获取设备列表的两类错误
错误原因与修复方案
错误1:Type 'NWBrowser' has no member 'Service'
NWBrowser类不存在Service嵌套类型,创建Bonjour服务描述符需用Network框架提供的NWBrowser.Descriptor.bonjour(type:domain:name:)方法,这是定义Bonjour浏览目标的标准方式。
错误2:Cannot convert value of type '[Any]' to expected argument type 'NWBrowser.Descriptor'
NWBrowser初始化器init(for:using:)仅接收单个NWBrowser.Descriptor实例,而非数组。原代码将错误创建的service放入数组传入,导致类型不匹配报错。
修正后的完整代码
import Foundation import Network class BonjourService { private let serviceType: String private let domain: String private var browseQuery: NWBrowser? private var services: [NWEndpoint] = [] init(serviceType: String, domain: String) { self.serviceType = serviceType self.domain = domain } func scan(completion: @escaping ([NWEndpoint]) -> Void) { let parameters = NWParameters.tcp // 直接使用预设TCP参数更规范 // 正确创建Bonjour服务描述符 let bonjourDescriptor = NWBrowser.Descriptor.bonjour( type: "_\(serviceType)._tcp", domain: domain, name: nil // 无需过滤特定名称时传nil ) // 传入单个descriptor初始化NWBrowser browseQuery = NWBrowser(for: bonjourDescriptor, using: parameters) browseQuery?.browseResultsChangedHandler = { [weak self] results, changes in self?.services = results.map { $0.endpoint } completion(self?.services ?? []) } browseQuery?.start(queue: DispatchQueue.global(qos: .background)) // 用后台队列处理网络操作,避免阻塞主线程 } func stopScan() { browseQuery?.cancel() browseQuery = nil // 清空引用防止内存泄漏 } }
额外说明
- 提取IP与端口:当
NWEndpoint为.hostPort(host:port:)类型时,可通过模式匹配获取NWHostEndpoint,从中提取IP和端口:
for endpoint in services { if case .hostPort(let hostEndpoint) = endpoint { let ip = hostEndpoint.hostname let port = hostEndpoint.port.rawValue print("IP: \(ip ?? "未知"), 端口: \(port)") } }
- 队列优化:网络操作避开主线程,使用全局后台队列能避免UI卡顿。
内容的提问来源于stack exchange,提问作者Pastor J.G Seigle
相关产品推荐
相关产品推荐

