首页 > 解决方案 > 有时无法访问配对手表模拟器上的 WatchConnectivity 会话

问题描述

我有一个 iOS 应用程序,它使用 WatchConnectivity 与配对的手表进行通信。在大多数情况下,它在模拟器和设备上都可以正常工作。

问题:

在模拟器上进行开发期间,当我尝试使用以下命令从 iOS 向 watchOS 发送直接消息时,不时出现以下通信错误WCSession.default.sendMessage(_:replyHandler:errorHandler:)

Error Domain=WCErrorDomain Code=7007  
"WatchConnectivity session on paired device is not reachable."

我已经阅读了这篇相关文章,但它不适用于我的情况,因为我的应用程序确实可以正常工作。

我的问题:

当应用程序在 iOS 模拟器上运行时,手表模拟器怎么会变得不可访问?一段时间后
重试有意义吗? 有什么解决方法吗?sendMessage

标签: iosreachabilitysendmessagewatchoswatchconnectivity

解决方案


作为一种解决方法,我修改了该sendMessage函数,以便在出现此错误时重试传输多次。从那时起,所有sendMessage传输都成功执行。

func sendMessage(_ message: [String: AnyObject],
                                 replyHandler: (([String: Any]) -> Void)?,
                                 errorHandler: ((Error) -> Void)?) {
    guard let communicationReadySession = communicationReadySession else {
        // watchOS: A session is always valid, so it will never come here.
        print("Cannot send direct message: No reachable session")
        let error = NSError.init(domain: kErrorDomainWatch, 
                                 code: kErrorCodeNoValidAndReachableSession, 
                                 userInfo: nil)
        errorHandler?(error)
        return
    }

    /* The following trySendingMessageToWatch sometimews fails with
    Error Domain=WCErrorDomain Code=7007 "WatchConnectivity session on paired device is not reachable."
    In this case, the transfer is retried a number of times.
    */
    let maxNrRetries = 5
    var availableRetries = maxNrRetries

    func trySendingMessageToWatch(_ message: [String: AnyObject]) {
        communicationReadySession.sendMessage(message, 
                                              replyHandler: replyHandler, 
                                              errorHandler: { error in
                                                              print("sending message to watch failed: error: \(error)")
                                                              let nsError = error as NSError
                                                              if nsError.domain == "WCErrorDomain" && nsError.code == 7007 && availableRetries > 0 {
                                                                 availableRetries = availableRetries - 1
                                                                 let randomDelay = Double.random(min: 0.3, max: 1.0)
                                                                 DispatchQueue.main.asyncAfter(deadline: .now() + randomDelay, execute: {
                                                                    trySendingMessageToWatch(message)
                                                                 })
                                                               } else {
                                                                 errorHandler?(error)
                                                               }
        })
    } // trySendingMessageToWatch

    trySendingMessageToWatch(message)
} // sendMessage

推荐阅读