WatchOS配套App编译正常但归档时触发WCSessionDelegate协议错误
问题:WatchOS应用Release归档时出现WCSessionDelegate协议不兼容错误
我在WatchOS配套App中实现了如下ViewModel代码:
import Foundation import WatchConnectivity class WatchViewModel: NSObject, ObservableObject { var session: WCSession @Published var counter = 0 // Add more cases if you have more receive method enum WatchReceiveMethod: String { case sendCounterToNative } // Add more cases if you have more sending method enum WatchSendMethod: String { case sendCounterToFlutter } init(session: WCSession = .default) { self.session = session super.init() self.session.delegate = self session.activate() } func sendDataMessage(for method: WatchSendMethod, data: [String: Any] = [:]) { sendMessage(for: method.rawValue, data: data) } } extension WatchViewModel: WCSessionDelegate { public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { } // Receive message From AppDelegate.swift that send from iOS devices func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { DispatchQueue.main.async { guard let method = message["method"] as? String, let enumMethod = WatchReceiveMethod(rawValue: method) else { return } switch enumMethod { case .sendCounterToNative: self.counter = (message["data"] as? Int) ?? 0 } } } func sendMessage(for method: String, data: [String: Any] = [:]) { guard session.isReachable else { return } let messageData: [String: Any] = ["method": method, "data": data] session.sendMessage(messageData, replyHandler: nil, errorHandler: nil) } }
这段代码能在模拟器正常编译运行,但尝试归档App时收到错误提示:Type 'WatchViewModel' does not conform to protocol 'WCSessionDelegate'。我知道这是缺少协议必需方法,但找不到具体缺失项。另外把归档scheme改成Debug而非Release时,归档能成功完成。想知道为什么这个错误只在Release模式归档时出现,Debug模式没问题,求排查方向。
排查方案
1. 统一协议方法的访问级别
你当前仅给session(_:activationDidCompleteWith:error:)加了public修饰,其他协议方法没有。Release模式下Swift优化器会严格校验协议方法的访问权限,可能因为权限不一致导致协议一致性判断失败。尝试给所有WCSessionDelegate的实现方法加上public修饰:
extension WatchViewModel: WCSessionDelegate { public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {} public func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { DispatchQueue.main.async { guard let method = message["method"] as? String, let enumMethod = WatchReceiveMethod(rawValue: method) else { return } switch enumMethod { case .sendCounterToNative: self.counter = (message["data"] as? Int) ?? 0 } } } }
2. 补充WCSessionDelegate的必需方法
在WatchOS的WCSessionDelegate协议中,除了激活完成的方法,还有两个容易被忽略的必需方法:sessionDidBecomeInactive(_:)和sessionDidDeactivate(_:)。Debug模式下编译器可能宽松处理,但Release模式会严格校验协议完整性。补充这两个方法:
extension WatchViewModel: WCSessionDelegate { public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {} public func sessionDidBecomeInactive(_ session: WCSession) {} public func sessionDidDeactivate(_ session: WCSession) { session.activate() // 通常需要重新激活会话以接收后续消息 } public func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { // 原有逻辑 } }
3. 检查Release模式的编译优化设置
- 打开项目的WatchOS Target设置,进入Build Settings,找到Swift Compiler - Code Generation下的Optimization Level。Release模式默认是
Fast, Whole Module Optimization,这种全模块优化可能导致协议检查严格甚至误判。临时将其改为None,再尝试归档,确认是否是优化导致的问题。 - 同时检查Enable Strict Checking of Objective-C Runtime Calls选项,Release模式下可能开启了该选项,导致对Objective-C协议(WCSessionDelegate属于此类)的校验更严格。
4. 清理缓存后重试
Release模式下Xcode的缓存可能引发异常编译错误,执行以下操作:
- 删除Derived Data:通过
Xcode -> Settings -> Locations -> Derived Data打开文件夹,删除对应项目的缓存目录 - 清理项目:使用快捷键
Command + Shift + K - 重启Xcode后重新尝试归档
内容的提问来源于stack exchange,提问作者circlek
相关产品推荐
相关产品推荐

