我正在尝试使用一个简单的应用程序学习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中的第一条消息没有错误。
答案 0 :(得分:5)
以下解决方案适用于通过WCSession
,
<强> 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)")
}
}
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)
}
OutPut将如下所示
答案 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)来检查手表是否可以到达。因此,值得注意的是,仅当您确实需要手表发回的消息时才应使用回复处理程序。