ios - Watchkit - didReceiveApplicationContext 仅在第一次工作

标签 ios swift3 watchconnectivity wcsession

当我在 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/

相关文章:

ios - 如何将数据从 ViewModel 层传递到 View 层

ios - 简单地推送 SWRevealViewController 来实现单单元格快速?

ios - ReactiveSwift 不适用于 Xcode 8.1。转换为 Swift 3 会导致 >50 个错误。修复?

ios - 当 WatchKit 应用程序未运行时,从 iOS 应用程序为 WatchKit 应用程序设置一个值

ios - WatchConnectivity:尽管更新了上下文,但 didReceiveApplicationContext 永远不会被调用

ios - dequeueReusableCell 打破 cliptobounds

ios - Venmo支付SDK链系统

ios - 在 swift 3 中子类化的 UITableViewCell 始终具有 320 点的 contentView

ios - 如何在 Collection View 的底部/页脚中添加 uiactivity 指示器?

ios - "Message reply took too long."- Watch OS 3 的 watch 连接问题