Apple Watch并发症无法可靠更新

时间:2019-02-18 15:06:17

标签: watchkit apple-watch watchconnectivity apple-watch-complication clockkit

我有一个iPhone应用程序,可将数据从iPhone应用程序直接发送到表盘以显示为复杂情况。

我使用WatchConnectivity框架创建一个WCSession,以将数据从手机发送到手表。

我的数据存储在字典中,并使用WCSession的{​​{1}}方法发送到手表。 (这种方法每天可以使用约50次,而我知道这一点-这不是问题。)

transferCurrentComplicationUserInfo方法似乎在我第一次尝试发送数据时起作用。

我的问题是我的iPhone应用程序打算在一次会话中多次调用此函数,并且只能在第一次可靠地运行。

当我发送第二组数据时,第一组保留在并发症上。通常,当我发送第三组时,会出现第二组。有时第二组永久显示,有时在显示第三组之前仅出现一秒钟。

这是不一致的,这就是我遇到的问题。

我设置不正确吗?

代码:

transferCurrentComplicationUserInfo

//更新//

进一步检查后,我发现步骤正在按顺序进行。

这是事件的顺序:

    从iPhone应用程序调用
  1. //iPhone code to send data to Apple Watch: func sendComplication(complication: Complication) { guard let session = session else { delegate?.failedToSendComplication(reason: "Could not connect to your Apple Watch.") return } guard let context = convertComplicationToDictionary(complication: complication) else { delegate?.failedToSendComplication(reason: "Couldn't cast complication to a dictionary.") return } if session.remainingComplicationUserInfoTransfers > 0 { session.transferCurrentComplicationUserInfo(context) delegate?.didSendComplication() } else { delegate?.failedToSendComplication(reason: "Due to hardware limitations, you can only send a certain amount of complications in a day. You have exceeded that limit for today. You can still set complications from the Apple Watch app.") } } // WatchKit Extension Delegate to receive and handle data sent from iPhone app import WatchKit import WatchConnectivity class ExtensionDelegate: NSObject, WKExtensionDelegate { var session: WCSession? override init() { super.init() self.session = newWatchConnectivitySession() } func newWatchConnectivitySession() -> WCSession? { if WCSession.isSupported() { let session = WCSession.default session.delegate = self session.activate() return session } return nil } func reloadComplicationTimeline() { let server = CLKComplicationServer.sharedInstance() guard let activeComplicationFamilies = server.activeComplications else { return } for comp in activeComplicationFamilies { server.reloadTimeline(for: comp) } } } extension ExtensionDelegate: WCSessionDelegate { func sessionReachabilityDidChange(_ session: WCSession) { if session.activationState != .activated { self.session = newWatchConnectivitySession() } } // Receive info from iPhone app func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) { // Parse dictionary and update data source reloadComplicationTimeline() } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { guard let error = error else { return } print(error.localizedDescription) } }
  2. sendComplication在Watch应用上初始化,设置了ExtensionDelegate
  3. 更新并发症(为时过早-这是WCSession收到新数据之前的时间)
  4. 调用WCSession委托方法,解析数据,并更新数据源(为时已晚)
  5. 告诉并发症要重新加载,但是什么也没发生(可能是预算问题?)

3 个答案:

答案 0 :(得分:0)

正如您在更新中描述的那样,您的iPhone应用程序会在手表设置session.transferCurrentComplicationUserInfo(context)之前调用WCSession。但是文档说:

  

[transferCurrentComplicationUserInfo(_ :)]仅在   会话处于活动状态-也就是说,activationState属性设置为   WCSessionActivationState.activated。调用此方法   无效或无效的会话是程序员错误。

因此,我建议您实现WCSessionDelegate函数session(_:activationDidCompleteWith:error:)(如果尚未这样做)(请参见here),并仅在会话完成后才传输并发症数据已激活。

答案 1 :(得分:0)

尝试以下操作:

func reloadComplicationTimeline() {
    #if os(watchOS)
    let server = CLKComplicationServer.sharedInstance()
    if let activeComplicationFamilies = server.activeComplications {
    for comp in activeComplicationFamilies {
        server.reloadTimeline(for: comp)
    }
   #endif
}



func sendComplication(complication: Complication) {
        guard WCSession.default.activationState == .activated else {
            delegate?.failedToSendComplication(reason: "Could not connect to your Apple Watch.")
            return
        }
        guard let context = convertComplicationToDictionary(complication: complication) else {
            delegate?.failedToSendComplication(reason: "Couldn't cast complication to a dictionary.")
            return
        }
        #if os(iOS)
        if WCSession.default.isComplicationEnabled {
            let userInfoTranser = WCSession.default.transferCurrentComplicationUserInfo(context)
            delegate?.didSendComplication()
        } else {
            delegate?.failedToSendComplication(reason: "Due to hardware limitations, you can only send a certain amount of complications in a day. You have exceeded that limit for today. You can still set complications from the Apple Watch app.")
        }
        #endif
    }

这是苹果公司的一个很好的例子,可以为您提供更多帮助:source

答案 2 :(得分:0)

重置iPhone,Apple Watch和Mac可以解决此问题。