当我在Xcode中使用iOS和watchOS模拟器运行Watch Connectivity应用程序时,WCSession委托方法 didReceiveApplicationContext 只能首次使用,但是不会被调用,并且Interface控制器中没有任何更改。谁能解释为什么会这样吗?
下面是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)
}
}
答案 0 :(得分:2)
其原因是因为updateApplicationContext
仅在应用程序上下文字典的内容更改时触发。 apple documentation将其描述为(强调是我的):
使用updateApplicationContext(_ :)方法将最新状态信息传达给对方。当对方唤醒时,它可以使用此信息来更新其自身的状态。例如,支持后台应用刷新的iOS应用可以使用其后台执行时间的一部分来更新相应的Watch应用。 此方法会覆盖以前的数据字典,因此当您的应用仅需要最新的数据值时使用此方法。
因此,可以将其视为属性设置器方法,该方法仅在值实际更改时才触发KVO。这里,接收方委托方法仅在字典的内容更改时才触发,因此在上面的示例中,如果您更改此行:
let message = ["quote": "Hello"]
要这样:
let message = ["quote": "Hello", "date": NSDate()]
您会看到接收方委托每次都会得到一个回调。