WatchKit didReceiveApplicationContext未被调用

时间:2015-09-26 23:03:02

标签: swift watchkit xcode7 watch-os-2

无法调用didReceiveApplicationContext 。有什么想法吗?

InterfaceController

import WatchKit
import Foundation
import WatchConnectivity

class InterfaceController: WKInterfaceController, WCSessionDelegate {

    @IBOutlet var colorLabel: WKInterfaceLabel!

    private let session: WCSession? = WCSession.isSupported() ? WCSession.defaultSession() : nil

    override init() {
        super.init()
        session?.delegate = self
        session?.activateSession()
    }

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
    }

    func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]){
        let colors : String = applicationContext["color"] as! String
        colorLabel.setText(colors)
        NSLog("session did receive application context")
    }

}

我一直在关注本教程:http://www.kristinathai.com/watchos-2-how-to-communicate-between-devices-using-watch-connectivity/

没有NSLogcolorLabel的设置。不知道我错过了什么。谢谢!

6 个答案:

答案 0 :(得分:5)

这似乎是一个典型的发展阶段'问题!

iOS 设备 WCSession.defaultSession.applicationContext 缓冲,因此仅转移到观看强>(扩展)一旦它没有改变。

这导致了一个奇怪的发现,即观看扩展' didReveiveApplicationContext:'当再次在iOS应用程序中调用 WCSession.defaultSession.updateApplicationContext 时,似乎不会被调用。 (尝试在扩展名中调用 WSSession.defaultSession.receivedApplicationContext 来查找,事实上早先传输的上下文是可用的)!

测试环境中,添加' 转换器'非常有用。对象到上下文字典(比如UUID对象,或者 - 甚至更好 - 一个NSDate.date)。这将确保上下文已更改(与缓冲的上下文相比)并再次传输(导致调用didReceiveApplicationContext): - )

NSError*    error = nil;
[WCSession.defaultSession updateApplicationContext:@{ @"yourKey"       : @"your content",
                                                      @"forceTransfer" : NSDate.date }
                                             error:&error];

并且:不要忘记在您的应用的生产版本中删除它,因为 - 当然 - 这会导致您的应用和手表扩展程序之间不必要的数据传输!

PS:选中的答案通过创建新应用来解决此问题。并以这种方式刷新所有缓冲区......

答案 1 :(得分:2)

检查会话以确保其isPaired和watchAppInstalled属性都为YES。似乎更新共享上下文而这些是NO将不起作用。

我遇到了这个问题。当条件为NO时,对而不是更新上下文进行了更改。添加了sessionWatchStateDidChange:的实现,如果两个条件都为YES,则更新上下文。它奏效了。

我怀疑这与另一个问题相结合,如果数据不同,手机将不会发送上下文导致“永不更新”问题。传递“uuid”的解决方法确实有帮助,但我怀疑上面是一个更好的解决方案。

答案 2 :(得分:1)

我将上面的代码复制到一个新的手表应用程序中,它运行正常。错误必须放在发送方。您确定要调用iOS应用程序中的代码吗?我假设您正在使用Xcode和两个模拟器,一个用于iOS应用程序,另一个用于WatchApp。

除非您在手机模拟器上打开应用程序,否则iOS侧的代码无法运行。在iOS端的哪个位置以及如何发出updateAppContext调用?

在我的测试中,这就是我在iOS端添加到我的ViewController.swift的所有内容(在我的iPhone上启动iOS应用程序之前,此代码不会被触发。)

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let session = WCSession.defaultSession()
    session.delegate = self
    session.activateSession()
    do {
        try session.updateApplicationContext( ["color" : "Red" ])
    } catch _ {

    }
}

答案 3 :(得分:1)

我遇到了同样的问题。在我的例子中,它有助于关闭两个模拟器,然后运行Watch方案。这会在连接状态下再次打开两个模拟器。

希望它有所帮助!

答案 4 :(得分:1)

对我来说,在进行一些测试/调试时,我试图在updateApplicationContext中触发AppDelegate。这导致didReceiveApplicationContext未被调用。

将此逻辑移至稍后的位置,就像在UIViewController中一样,至少使它对我有用。

答案 5 :(得分:1)

就我而言,我使用以下代码发送我的应用程序上下文:

    do {
        try session.updateApplicationContext(applicationContext)
    } catch let error {
        throw error
    }  

既没有调用didReceiveApplicationContext,也没有抛出错误

我的问题是applicationContext包含自定义对象,而只允许使用属性列表项 奇怪的是,没有错误被抛出。