【问题标题】:WatchKit complication not updatingWatchKit 并发症未更新
【发布时间】:2022-11-14 11:19:48
【问题描述】:

我想做一些看似简单的事情——我在 iPhone 上有一个应用程序可以让你更改日期。在手表上,我有一个并发症,其中显示了直到那个日期的日子。很明显,当您更改 iPhone 应用程序上的日期时,我希望手表上的日期发生变化,并且该状态一直持续到或者如果您再次更改 iPhone 上的日期。

我所做的是创建了一个包含在并发症和手表应用程序中的状态对象,并且在两者中我只是这样做以显示值

    @ObservedObject state = OneDayState.shared

    ...
    Text( state.daysUntilValue )

怎么了当我更改 iPhone 上的日期时:

  • 如果手表应用程序处于活动状态并正在运行
    • 应用程序上显示的日期会发生应有的变化
    • 如果我回到主屏幕,并发症有旧的坏值
    • 如果我重置手表 - 复杂功能现在具有正确的值
  • 如果手表应用程序未激活且未运行
    • 无论是复杂功能还是手表都没有获得新的价值

我什么即将发生

  • 当我更改 iphone 上的值时,应用程序即使没有运行也能获取新值
  • 当我在 iPhone 上更改值时立即更改的并发症

这是我的状态对象的代码 - 我做错了什么? (谢谢)

class OneDayState : NSObject, ObservableObject, WCSessionDelegate
{
    
    static let shared = OneDayState()
    
    //
    // connection to the settings
    //
    let session = WCSession.default

    //
    // connection to the user defaults
    //
    let settings =  UserDefaults(suiteName: "[removed]")!;

    //
    // what is watched by the UI
    //
    var daysUntilValue : String {
        return  String( Calendar.current.dateComponents( [.day], from: .now, to: theDate).day!)
    }
    
    //
    // the target date
    //
    @Published var theDate : Date = Date.now

    //
    // setup this
    //
    override init()
    {
        super.init()
        session.delegate = self
        session.activate()
        theDate = settings.object(forKey: "target" ) as? Date ?? Date.now;
    }

    //
    // you seem to have to override this
    //
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        print("sesison activated")
    }

    //
    // when the application context changes, we just store the new date
    //
    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any])
    {
        let newDate = applicationContext["target"] as? Date ?? Date.now;
        DispatchQueue.main.async
        {
            self.settings.set( newDate, forKey: "target")
            self.theDate = newDate;
        }
    }
        
}

【问题讨论】:

  • 日期更改时如何重新加载并发症时间表?
  • 我不 - 我认为这是观察对象的重点?但是我尝试将“用于 CLKComplicationServer.sharedInstance.activeComplications 中的复杂化??[] {CLKComplicationServer.sharedInstance.reloadTimeline(for:complication)}”放入我设置日期的位置,它没有任何区别
  • 但我已经在并发症中设置了断点 - 没有事件触发,即使我正在发送输液器信息、trasnfercurrentcomplicationuserinfo 和 updateapplicationContext
  • 更改为 WidgetCenter.shared.reloadAllTimelines()。也无所作为

标签: ios swiftui watchkit watchconnectivity apple-watch-complication


【解决方案1】:

在 SwiftUI 之前,我有一个依赖的 Watch 应用程序,它需要一个 iOS 配套应用程序(我当前的 Watch 应用程序是独立的)。因此,我只能说我当时做了什么让它发挥作用。
我有一个WatchSessionManager,在func transferCurrentComplicationUserInfoIfPossible(userInfo: [String: AnyObject])发送的func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any])并发症数据中收到。
那么问题是如何将接收到的复杂数据传输到ComplicationController: NSObject, CLKComplicationDataSource。然后我使用NotificationCenter 发布带有数据的userInfoComplicationController 收到帖子并重新加载活动并发症的时间线。这样,即使 Watch 扩展程序未激活,复杂功能也会始终更新。
为了更新 Watch 应用程序本身,即使它未处于活动状态,我也使用 func transferUserInfo(_ userInfo: [String: Any]) -> WCSessionUserInfoTransfer? 传输数据。如果 Watch 扩展未激活,则只要 Watch 扩展激活,就会收到 userInfo。在任何情况下,Watch 扩展都可以根据需要使用数据来更新其状态。
我不确定如何将其转换为 SwiftUI。我现在使用的是新的 WatchOS 9 小部件,但它们的工作方式不同。

【讨论】:

    【解决方案2】:

    当您的手表应用在后台运行时,您应该使用WKWatchConnectivityRefreshBackgroundTask 从 iPhone 获取数据。

    WKWatchConnectivityRefreshBackgroundTask

    目前WKWatchConnectivityRefreshBackgroundTask,所以你看不会得到数据,直到它进入前台。

    然后您需要自己手动更新您的并发症。

    【讨论】:

      【解决方案3】:

      您的可观察对象看起来不错。我需要查看更多复杂的代码才能确定,但​​根据您的代码 sn-p ,观察 OneDayState 对象似乎出了点问题。

      @ObservedObject var state = OneDayState.shared
      

      像这样在其类型声明中实例化对象不是可行的方法,因为每当重新计算复杂性或视图时都会重新创建对象。您应该使用@StateObject(即使在复杂化无效后仍保留变量),或者使用.environmentObject(_:) 将对象注入环境中。我也会避免使用单例类作为可观察对象(使用.shared)。只需在需要的复杂功能中创建它。

      @StateObject var state = OneDayState()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-08
        • 2018-09-12
        • 1970-01-01
        • 2013-07-05
        相关资源
        最近更新 更多