WatchConnectivity:尽管更新了上下文,但从未调用 didReceiveApplicationContext
WatchConnectivity: didReceiveApplicationContext never gets called although context is updated
我遇到了以下问题:我可以在 iPhone 和 Watch(模拟器和真实设备)上启动 WCSessions,并且可以很好地使用 sendMessage 方法。我知道 updateApplicationContext 需要发送更新的字典,所以我添加了一个 uuid 用于调试目的:
context = ["user":id,"messageId": UUID().uuidString]
调用该方法时没有抛出任何错误,但在观察端 didReceiveApplicationContext 永远不会被调用并且 receivedApplicationContext dict 始终保持为空。在阅读了很多类似的代码示例和文档后,我看不出我哪里错了。
我正在构建 XCode 12.5 和 iOS 14.5 以及 watchOS 7.4
这是处理 WCSession 的 iOS 代码,上下文是在另一个方法中设置的,并且使用 sendMessage
成功传输 但没有使用 updateApplicationContext
:
import WatchConnectivity
public class CDVSettings : CDVPlugin, WCSessionDelegate {
var wcSession : WCSession! = nil
var didSendMessage:Bool = false
var context: [String : Any] = [:] {
didSet {
debugPrint("context didSet:", self.context)
debugPrint("WCSession.isPaired: \(wcSession.isPaired), WCSession.isWatchAppInstalled: \(wcSession.isWatchAppInstalled)")
if wcSession.activationState == WCSessionActivationState.activated {
do {
debugPrint("updateApplicationContext is called")
self.didSendMessage=true
try wcSession.updateApplicationContext(self.context)
}
catch let error as NSError {
debugPrint(error.localizedDescription)
}
catch {}
wcSession.sendMessage(self.context, replyHandler: { reply in
print("Got reply: \(reply)")
}, errorHandler: { error in
print("error: \(error)")
})
} else {
print("activationState is not activated")
wcSession.activate()
}
}
}
public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
}
public func sessionDidBecomeInactive(_ session: WCSession) {
}
public func sessionDidDeactivate(_ session: WCSession) {
}
@objc(pluginInitialize)
public override func pluginInitialize() {
wcSession = WCSession.default
wcSession.delegate = self
wcSession.activate()
}
[...]
}
这是手表部分:
import WatchConnectivity
class ConnectivityRequestHandler: NSObject, ObservableObject, WCSessionDelegate {
var session = WCSession.default
override init() {
super.init()
session.delegate = self
session.activate()
debugPrint("ConnectivityRequestHandler started with session", session)
}
// MARK: WCSession Methods
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
debugPrint(error)
debugPrint("session is reachable:",session.isReachable)
debugPrint("last received application context:",session.receivedApplicationContext)
}
func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) {
debugPrint("didReceiveMessage: \(message)")
replyHandler(["message received": Date()])
}
func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void) {
debugPrint("didReceiveMessageData: \(messageData)")
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
debugPrint("did receive application context")
debugPrint(applicationContext)
if let id = applicationContext["user"] as? [String]{
debugPrint("\(id)")
UserDefaults.standard.set(id, forKey: "user")
}
}
}
iOS
上对应的日志
"context didSet:" ["user": "0e4a28b5-f8a0-40a5-942d-5f13b610a93a",
"messageId": "8A78246C-91E6-48DC-B55D-4F4EBC761211"]
"WCSession.isPaired: true, WCSession.isWatchAppInstalled: true"
"updateApplicationContext is called" Got reply: ["message received":
2021-09-03 08:31:54 +0000]
在 watchOS 上
"ConnectivityRequestHandler started with session" <WCSession:
0x600003be0b40, hasDelegate: YES, activationState: 0> nil "session is
reachable:" true "last received application context:" [:]
"didReceiveMessage: ["user": 0e4a28b5-f8a0-40a5-942d-5f13b610a93a,
"messageId": 8A78246C-91E6-48DC-B55D-4F4EBC761211]"
我做错了什么?非常感谢您的帮助。
对于那些在研究过程中被我的问题绊倒的人来说,这不是真正的解决方案,而是我(现在)与他人分享的一个观察(见上面的评论):使用 真实设备 它按预期工作,但在此过程中您可能需要重新启动它们。在模拟器中,似乎不同的方法可能有效,而其他方法则无效,甚至因开发人员而异。
我遇到了以下问题:我可以在 iPhone 和 Watch(模拟器和真实设备)上启动 WCSessions,并且可以很好地使用 sendMessage 方法。我知道 updateApplicationContext 需要发送更新的字典,所以我添加了一个 uuid 用于调试目的:
context = ["user":id,"messageId": UUID().uuidString]
调用该方法时没有抛出任何错误,但在观察端 didReceiveApplicationContext 永远不会被调用并且 receivedApplicationContext dict 始终保持为空。在阅读了很多类似的代码示例和文档后,我看不出我哪里错了。
我正在构建 XCode 12.5 和 iOS 14.5 以及 watchOS 7.4
这是处理 WCSession 的 iOS 代码,上下文是在另一个方法中设置的,并且使用 sendMessage
成功传输 但没有使用 updateApplicationContext
:
import WatchConnectivity
public class CDVSettings : CDVPlugin, WCSessionDelegate {
var wcSession : WCSession! = nil
var didSendMessage:Bool = false
var context: [String : Any] = [:] {
didSet {
debugPrint("context didSet:", self.context)
debugPrint("WCSession.isPaired: \(wcSession.isPaired), WCSession.isWatchAppInstalled: \(wcSession.isWatchAppInstalled)")
if wcSession.activationState == WCSessionActivationState.activated {
do {
debugPrint("updateApplicationContext is called")
self.didSendMessage=true
try wcSession.updateApplicationContext(self.context)
}
catch let error as NSError {
debugPrint(error.localizedDescription)
}
catch {}
wcSession.sendMessage(self.context, replyHandler: { reply in
print("Got reply: \(reply)")
}, errorHandler: { error in
print("error: \(error)")
})
} else {
print("activationState is not activated")
wcSession.activate()
}
}
}
public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
}
public func sessionDidBecomeInactive(_ session: WCSession) {
}
public func sessionDidDeactivate(_ session: WCSession) {
}
@objc(pluginInitialize)
public override func pluginInitialize() {
wcSession = WCSession.default
wcSession.delegate = self
wcSession.activate()
}
[...]
}
这是手表部分:
import WatchConnectivity
class ConnectivityRequestHandler: NSObject, ObservableObject, WCSessionDelegate {
var session = WCSession.default
override init() {
super.init()
session.delegate = self
session.activate()
debugPrint("ConnectivityRequestHandler started with session", session)
}
// MARK: WCSession Methods
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
debugPrint(error)
debugPrint("session is reachable:",session.isReachable)
debugPrint("last received application context:",session.receivedApplicationContext)
}
func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) {
debugPrint("didReceiveMessage: \(message)")
replyHandler(["message received": Date()])
}
func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void) {
debugPrint("didReceiveMessageData: \(messageData)")
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
debugPrint("did receive application context")
debugPrint(applicationContext)
if let id = applicationContext["user"] as? [String]{
debugPrint("\(id)")
UserDefaults.standard.set(id, forKey: "user")
}
}
}
iOS
上对应的日志"context didSet:" ["user": "0e4a28b5-f8a0-40a5-942d-5f13b610a93a", "messageId": "8A78246C-91E6-48DC-B55D-4F4EBC761211"] "WCSession.isPaired: true, WCSession.isWatchAppInstalled: true" "updateApplicationContext is called" Got reply: ["message received": 2021-09-03 08:31:54 +0000]
在 watchOS 上
"ConnectivityRequestHandler started with session" <WCSession: 0x600003be0b40, hasDelegate: YES, activationState: 0> nil "session is reachable:" true "last received application context:" [:] "didReceiveMessage: ["user": 0e4a28b5-f8a0-40a5-942d-5f13b610a93a, "messageId": 8A78246C-91E6-48DC-B55D-4F4EBC761211]"
我做错了什么?非常感谢您的帮助。
对于那些在研究过程中被我的问题绊倒的人来说,这不是真正的解决方案,而是我(现在)与他人分享的一个观察(见上面的评论):使用 真实设备 它按预期工作,但在此过程中您可能需要重新启动它们。在模拟器中,似乎不同的方法可能有效,而其他方法则无效,甚至因开发人员而异。