Expo原生模块开发:NativeScannerModule未遵循AnyModule协议报错求助
Expo原生模块开发:NativeScannerModule未遵循AnyModule协议报错求助
嘿,看起来你在开发Expo原生扫描AirPrint打印机的模块时踩坑了,我来帮你梳理下问题和解决办法:
首先看你贴的代码片段,有几个明显的问题会触发协议遵循报错:
- 代码没写完,
Funct是Function的拼写错误,而且没有完成方法的完整定义 - 没有满足Expo Modules Core中
Module协议的全部要求,尤其是初始化方法和事件发送的核心逻辑,这大概率就是“未遵循AnyModule协议”报错的核心原因
我给你整理了修正后的完整代码示例,你可以参考调整:
import ExpoModulesCore import Foundation import Network public class NativeScannerModule: NSObject, Module, NetServiceBrowserDelegate, NetServiceDelegate { private var serviceBrowser: NetServiceBrowser? private var discoveredServices: [NetService] = [] // 用于给JS端发送事件的关键对象 private let eventEmitter: EventEmitter // 必须实现接收AppContext的初始化方法,这是Expo模块的强制要求 public required init(appContext: AppContext) { self.eventEmitter = appContext.eventEmitter super.init() setupServiceBrowser() } public func definition() -> ModuleDefinition { // 定义模块名称,JS端会通过这个名称调用模块方法 Name("NativeScanner") // 注册要发送到JS端的事件 Events("onPrinterFound") // 定义JS可调用的"开始扫描"方法 Function("startScanning") { [weak self] in // AirPrint服务的标准类型是_ipp._tcp.,扫描本地局域网域 self?.serviceBrowser?.searchForServices(ofType: "_ipp._tcp.", inDomain: "local.") } // 定义停止扫描的方法 Function("stopScanning") { [weak self] in self?.serviceBrowser?.stop() self?.discoveredServices.removeAll() } } private func setupServiceBrowser() { serviceBrowser = NetServiceBrowser() serviceBrowser?.delegate = self } // 实现NetServiceBrowserDelegate方法,发现服务时触发 public func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) { discoveredServices.append(service) // 触发服务地址解析 service.delegate = self service.resolve(withTimeout: 5.0) } // 服务地址解析完成后,把打印机信息发送到JS端 public func netServiceDidResolveAddress(_ sender: NetService) { guard let addressData = sender.addresses?.first else { return } var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(addressData.bytes, socklen_t(addressData.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) let ipAddress = String(cString: hostname) // 组装JS端易处理的打印机信息字典 let printerInfo = [ "name": sender.name, "ipAddress": ipAddress, "port": sender.port ] as [String: Any] // 发送事件到JS端 eventEmitter.sendEvent("onPrinterFound", body: printerInfo) } // 必须实现错误处理的代理方法,避免协议未完全遵循的报错 public func netServiceBrowser(_ browser: NetServiceBrowser, didNotSearch errorDict: [String: NSNumber]) { print("扫描打印机出错: \(errorDict)") } public func netService(_ sender: NetService, didNotResolve errorDict: [String: NSNumber]) { print("解析打印机服务出错: \(errorDict)") } }
另外再给你几个额外的排查方向:
- 如果你仍遇到“未遵循AnyModule协议”的报错,大概率是Expo Modules Core版本和项目的Expo SDK版本不匹配,建议检查依赖版本并保持一致
- Swift对协议遵循的检查非常严格,必须完整实现所有你声明遵循的协议方法,缺一个都会触发报错
- 可以尝试清理Xcode缓存(Product -> Clean Build Folder)后重新构建项目,有时候缓存会导致奇怪的协议校验问题
备注:内容来源于stack exchange,提问作者Dev07




