You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:16:03