代码之家  ›  专栏  ›  技术社区  ›  chriscrutt

watchSession.sendMessage在模拟器上工作正常,超时IRL

  •  2
  • chriscrutt  · 技术社区  · 7 年前

    我写了两个应用程序,首先使用 transferUserInfo ,这导致了太多的延迟(我相信是因为它在后台发送东西)。我换成了 sendMessage 对结果非常满意(响应时间更快)。当我试图在我真正的iPhone和applewatch上运行这个应用程序时,我收到了 Transfer timed out. 以下是其中一个调试的完整代码和示例:

    //  ViewController.swift
    
    import UIKit
    import Foundation
    import WatchConnectivity
    
    class WatchManager: UIViewController, WCSessionDelegate {
    
        var counter = 0
    
        var watchSession: WCSession? {
            didSet {
                if let session = watchSession {
                    session.delegate = self
                    session.activate()
                }
            }
        }
    
        override func viewDidLoad(){
            super.viewDidLoad()
    
            watchSession = WCSession.default
    
        }
    
    
        private func sendDict(_ dict: [String: Any]) {
            self.watchSession?.sendMessage(dict, replyHandler: nil, errorHandler: {error in print(error.localizedDescription)})
        }
    
        @IBOutlet weak var transferButton: UIButton!
        @IBOutlet weak var label: UILabel!
    
        @IBAction func dataTransfer(_ sender: Any) {
            sendDict(["DataKey": counter])
            counter+=1
            print("sent")
        }
    
        func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
            print("Session activation did complete")
        }
    
        public func sessionDidBecomeInactive(_ session: WCSession) {
            print("session did become inactive")
        }
    
        public func sessionDidDeactivate(_ session: WCSession) {
            print("session did deactivate")
        }
    
        func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
            print("phone received app context: ", message)
            if let temperature = message["DataKey"] as? String {
                DispatchQueue.main.async {
                    self.transferButton.setTitle(temperature, for: .normal)
                    self.label.text=temperature
                }
            }
    
        }
    
    }
    

    苹果手表:

    //  InterfaceController.swift
    
    import WatchKit
    import Foundation
    import WatchConnectivity
    
    
    class InterfaceController: WKInterfaceController {
    
        var watchSession: WCSession? {
            didSet {
                if let session = watchSession {
                    session.delegate = self
                    session.activate()
                }
            }
        }
    
    
        @IBOutlet weak var temperatureLabel: WKInterfaceButton!
    
        private func sendDict(_ dict: [String: Any]) {
            self.watchSession?.sendMessage(dict, replyHandler: nil, errorHandler: {error in print(error.localizedDescription)})
        }
    
        @IBAction func button() {
            let urg = ["DataKey":UUID().uuidString]
            sendDict(urg)
            print("watch sent app context \(urg)")
        }
    
    }
    
    extension InterfaceController: WCSessionDelegate {
    
        #if os(iOS)
        public func sessionDidBecomeInactive(_ session: WCSession) { }
        public func sessionDidDeactivate(_ session: WCSession) {
            session.activate()
        }
        #endif
    
        func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
            print("Session activation did complete")
        }
    
        func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
            print("watch received app context: ", message)
            if let temperature = message["DataKey"] as? Int {
                self.temperatureLabel.setTitle(String(temperature))
            }
    
        }
    
        override func willActivate() {
            // This method is called when watch view controller is about to be visible to user
            super.willActivate()
    
            watchSession = WCSession.default
    
        }
    
        override func didDeactivate() {
            // This method is called when watch view controller is no longer visible
            super.didDeactivate()
        }
    
    }
    

    调试示例:

    Session activation did complete
    watch sent app context ["DataKey": "AF793FC6-7A16-4D7D-9A3B-D3BB960EC9D9"]
    2019-01-13 21:07:43.524717-0800 testApp WatchKit Extension[1240:1178401] [WC] -[WCSession onqueue_handleMessageCompletionWithError:withMessageID:] C385FF5F-5EA1-478B-A930-54066C2F0B0F due to WCErrorCodeTransferTimedOut -> IDSErrorTypeTimedOut -> IDSResponseTimedOut
    2019-01-13 21:07:43.525001-0800 testApp WatchKit Extension[1240:1178401] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] C385FF5F-5EA1-478B-A930-54066C2F0B0F errorHandler: YES with WCErrorCodeTransferTimedOut -> IDSErrorTypeTimedOut -> IDSResponseTimedOut
    Transfer timed out.
    
    0 回复  |  直到 7 年前
    推荐文章