WatchKit_Extension.InterfaceController没有实现委托方法

时间:2018-01-06 21:07:35

标签: swift watchkit apple-watch watchconnectivity

我正在尝试使用一个简单的应用程序学习watchkit连接,并花了两天徒劳地研究这个错误:

{app name} _WatchKit_Extension.InterfaceController没有实现委托方法。

我已经盲目地复制了" SimpleWatchConnectivity" https://developer.apple.com/library/content/samplecode/SimpleWatchConnectivity/Listings/SimpleWatchConnectivity_WatchKit_Extension_InterfaceController_swift.html演示代码。并且没有成功地搜索论坛。

我的代码构建并运行正常,但我在手表上收到以下错误

2018-01-06 10:39:20.522995+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke delegate messageDemo_WatchKit_Extension.InterfaceController does not implement delegate method
2018-01-06 10:39:20.524378+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession _onqueue_sendResponseError:identifier:dictionaryMessage:] identifier: A150D814-453C-44B7-B970-913697526D6A with WCErrorCodeDeliveryFailed

执行时:

if (WCSession.isSupported())  
    {  
        WCSession.default.delegate = self;  
        WCSession.default.activate()  

        if let messageText =  textField.text{  
             WCSession.default.sendMessage(["message": messageText]  
                ,replyHandler: {replyMessage in  
                    print(replyMessage)  
             }  

               , errorHandler: {error in  
                print( error.localizedDescription)}  )  
        }  
    }  
来自iOS ViewController的

我的界面控制器如下:

 import WatchKit  
import Foundation  
import WatchConnectivity  
class InterfaceController: WKInterfaceController  
    , WCSessionDelegate  
    {  
    func session(_ session: WCSession  
        , activationDidCompleteWith activationState: WCSessionActivationState  
        , error: Error?) {  
        print("activationDidCompleteWith:\(activationState )") /  
    }  
    func sessionReachabilityDidChange(_ session: WCSession) {  
      /  
      /  
        print("sessionReachabilityDidChange")  
    }  

    @IBOutlet var messageLabel: WKInterfaceLabel!  
    override func awake(withContext context: Any?) {  
        super.awake(withContext: context)  

        /  
    }  

    override func willActivate() {  
        /  
        super.willActivate()  
        if (WCSession.isSupported())  
        {  
            WCSession.default.delegate = self;  
            WCSession.default.activate()  

        }  

    }  

    override func didDeactivate() {  

        super.didDeactivate()  

    }  

    private func session(session: WCSession, didReceiveMessage message: [String : Any]  
        , replyHandler: @escaping ([String : Any]) -> Void) {  
        self.messageLabel.setText(message["message"]! as? String)  
    }  
       func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {  
        self.messageLabel.setText(message["message"]! as? String)  
    }  
    func session(_ session: WCSession, didReceiveMessageData messageData: Data) {  
        print("HERE01")  
    }  

    func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void) {  
        self.session(session, didReceiveMessageData: messageData)  

         print("HERE02")  
    }  
    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {  

         print("HERE03")  
    }  

    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {  
         print("HERE04")  

    }  
    func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) {  
        print("HERE05")  
    }  

    func session(_ session: WCSession, didReceive file: WCSessionFile) {  
        print("HERE06")  
        }  

    func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) {  
        print("HERE07")  
    }  
}  

(抱歉格式化,我试了10分钟才能把它弄好,但遗憾地失败了)

我添加了一堆印刷品以确保涵盖所有案例。

完整的错误是:

2018-01-06 10:39:20.522995+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke delegate messageDemo_WatchKit_Extension.InterfaceController does not implement delegate method
2018-01-06 10:39:20.524378+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession _onqueue_sendResponseError:identifier:dictionaryMessage:] identifier: A150D814-453C-44B7-B970-913697526D6A with WCErrorCodeDeliveryFailed

非常感谢任何帮助

[编辑] 当我使用调试器监视Phone应用程序时,我看到发送消息失败,并显示:

2018-01-07 09:47:23.319221+1100 messageDemo[6628:1549809] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorCodeSessionNotActivated
2018-01-07 09:47:23.321103+1100 messageDemo[6628:1549978] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:]_block_invoke dropping as pairingIDs no longer match. pairingID (null), client pairingID: (null)
WatchConnectivity session has not been activated.

当我尝试发送第二条消息时,会生成我在帖子顶部引用的watchKitExtension收到的错误。 watchGitExtension中的第一条消息没有错误。

3 个答案:

答案 0 :(得分:5)

以下解决方案适用于通过WCSession

在iPhone和iWatch之间共享数据

<强> ViewController.swift

import UIKit
import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {

    @IBOutlet weak var textFieldMessage : UITextField!
    @IBOutlet weak var buttonSend : UIButton!
    var wcSession : WCSession!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        wcSession = WCSession.default
        wcSession.delegate = self
        wcSession.activate()
    }

    //MARK: - Button Actions

    @IBAction func clickSendMessage(_ sender : UIButton) {

        let message = ["message" : textFieldMessage.text!]
        do {
            try wcSession.updateApplicationContext(message)
        } catch {
            print("Something went wrong")
        }
    }

    // MARK: - WCSessionDelegate

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        NSLog("%@", "activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
    }

    func sessionDidBecomeInactive(_ session: WCSession) {
        print("%@", "sessionDidBecomeInactive: \(session)")
    }

    func sessionDidDeactivate(_ session: WCSession) {
        print("%@", "sessionDidDeactivate: \(session)")
    }

    func sessionWatchStateDidChange(_ session: WCSession) {
        print("%@", "sessionWatchStateDidChange: \(session)")
    }
}

enter image description here

InterfaceController.swift (观看分机)

import WatchKit
import Foundation
import WatchConnectivity

class InterfaceController: WKInterfaceController, WCSessionDelegate {

    var session : WCSession?
    @IBOutlet weak var sessionLabel : WKInterfaceLabel!

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()

        session = WCSession.default
        session?.delegate = self
        session?.activate()
    }

    // MARK: - WCSessionDelegate

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        NSLog("%@", "activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
    }

    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
        NSLog("didReceiveApplicationContext : %@", applicationContext)
        sessionLabel.setText(applicationContext["message"] as? String)
    }

enter image description here

OutPut将如下所示

enter image description here

答案 1 :(得分:1)

我的问题是sendMessage已实现 replyHandler:{replyMessage in
                    打印(replyMessage)
收到邮件后我没有回复。 我从来没有真正弄清楚如何发送回复,最后放弃了sendMessage,转而使用更准确地满足我要求的updateApplicationContext。

答案 2 :(得分:0)

我遇到了同样的问题:

在我的应用中,我将图像从iPhone发送到iWatch,并且在图像发送后,我正在iPhone上显示通知。如果发生错误,我会显示一条错误消息。由于这些原因,我需要将回复发送回应用程序。

我这样解决了:

在Watch Extension中,我实现了以下方法:

    func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void) {
    print("recieved data message to watch")

    //I have a method here which saves the image to watch storage...

   //I'm setting the reply data like this:
    let replyData = "Image recieved".data(using: .utf8)

    replyHandler(replyData!)
}

然后回到iOS应用中,我正在像这样处理响应:

 wcSession.sendMessageData(data, replyHandler: { (replyData) in

                let replyString = String(data: replyData, encoding: String.Encoding.utf8)

                if replyString != nil {
                 //Do something with the replyString...
                }

             }) { (error) in
                //Display error notification to user...
                print("error", error.localizedDescription)
            }

更新: 上面的答案对于处理回复处理程序仍然有效。简要说明一下: 在模拟器中运行该应用程序后,我注意到用户必须等待很长时间才能从手表收到答复。这并不是最佳的UX(尤其是如果您需要即时更新UI),因此我选择了一个更简单的选项,方法是通过调用wcSession.isReachable并查看警报(如果为true)来检查手表是否可以到达。因此,值得注意的是,仅当您确实需要手表发回的消息时才应使用回复处理程序。