我无法调用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/
没有NSLog
或colorLabel
的设置。不知道我错过了什么。谢谢!
答案 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
包含自定义对象,而只允许使用属性列表项
奇怪的是,没有错误被抛出。