当我在 Xcode 中运行带有 iOS 和 watchOS 模拟器的 watch 连接应用程序时,WCSession 委托(delegate)方法 didReceiveApplicationContext 仅在第一次工作,但随后它没有被调用并且接口(interface) Controller 中没有任何变化。任何人都可以解释发生这种情况的原因吗?
下面是UIViewController的WCSessionVC类
import Foundation
import UIKit
import WatchConnectivity
class WCSessionVC: UIViewController, WCSessionDelegate {
let session = WCSession.default
override func viewDidLoad() {
super.viewDidLoad()
session.delegate = self
session.activate()
}
func updateApplicationContext(applicationContext: [String : Any]) throws {
if WCSession.default.isPaired {
do {
try WCSession.default.updateApplicationContext(applicationContext)
} catch let error {
throw error
}
}
}
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
print("Session activated")
let message = ["quote": "Hello"]
do {
try self.updateApplicationContext(applicationContext: message as [String : Any])
}
catch {
print(error)
}
}
}
下面是WKInterfaceController的InterfaceController类
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController, WCSessionDelegate {
@IBOutlet var lblUserId: WKInterfaceLabel!
var watchSession: WCSession? {
didSet {
if let session = watchSession {
session.delegate = self
session.activate()
}
}
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
if let session = watchSession {
session.delegate = self
session.activate()
}
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
//loadDataFromDatastore()
watchSession = WCSession.default
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
//MARK: Delegate Methods
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
watchSession?.activate()
print("Session activation did complete")
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
DispatchQueue.main.async {
print("watch received app context: ", applicationContext)
if let data = applicationContext["quote"] as? String {
self.lblUserId.setText(data)
}
}
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
print(message)
}
}
最佳答案
之所以这样,是因为updateApplicationContext
只有在应用程序上下文字典的内容发生变化时才会触发。 apple documentation将其描述为(重点是我的):
Use the updateApplicationContext(_:) method to communicate recent state information to the counterpart. When the counterpart wakes, it can use this information to update its own state. For example, an iOS app that supports Background App Refresh can use part of its background execution time to update the corresponding Watch app. This method overwrites the previous data dictionary, so use this method when your app needs only the most recent data values.
因此可以将其视为一种属性设置方法,仅在值实际发生变化时才触发 KVO。这里接收方委托(delegate)方法仅在字典内容更改时触发,因此在上面的示例中,如果更改此行:
let message = ["quote": "Hello"]
是这样的:
let message = ["quote": "Hello", "date": NSDate()]
您会看到接收方委托(delegate)每次都会收到回调。
关于ios - Watchkit - didReceiveApplicationContext 仅在第一次工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51044213/