我正在尝试使用一个简单的应用程序学习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
任何帮助将不胜感激
[编辑]当我使用调试器监视电话应用程序时,我看到发送消息失败:
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收到的错误。第一条消息中watchKitExtension没有错误。
以下解决方案适用于通过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)")
}
}
InterfaceController.swift(Watch Extension)
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如下,
我的问题是sendMessage实现了replyHandler:{replyMessage in 打印(replyMessage) 我收到邮件时没有回复。我从来没有真正弄清楚如何发送回复,最后放弃了sendMessage,转而使用更准确地满足我要求的updateApplicationContext。
我有同样的问题:
在我的应用程序中,我将图像从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)
}
更新:上述答案对于处理回复处理程序仍然有效。只需快速说明:在模拟器中运行应用程序时,我注意到用户必须等待很长时间才能从手表到达回复。这不是真正的最佳用户体验(特别是如果你需要即时更新UI)所以我选择了一个更简单的选项,通过调用wcSession.isReachable
来检查手表是否可以访问,如果为true则显示警报。所以值得注意的是,只有当你真正需要手表发回的消息时才应该使用回复处理程序。