WidgetKit 手表复杂功能未按时间轴日期更新

问题描述 投票:0回答:1

我在让我的小部件按照时间线安排更新时遇到问题。我的手表处于开发人员模式,因此正常预算不应与附加到调试器的应用程序一起应用。我有以下代码,需要输入日期,例如现在 + 2 小时。然后,根据该日期,我想在特定时间触发小部件的重新加载,以便以不同的方式格式化它。

我遇到的问题是,它似乎忽略了除第一个和最后一个条目之外的所有其他条目。

func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    var entries: [SimpleEntry] = []
    
    if let widgetData = UserDefaults.getEncodedDefault(type: WidgetData.self, key: "widgetData") {
        entries.append(SimpleEntry(date: widgetData.startDate, timerEnd: widgetData.endDate)) // Update on timer start
        entries.append(SimpleEntry(date: Calendar.current.startOfDay(for: widgetData.startDate), timerEnd: widgetData.endDate)) // Update at midnight day of
        entries.append(SimpleEntry(date: Calendar.current.date(byAdding: .hour, value: -1, to: widgetData.endDate)!, timerEnd: widgetData.endDate)) // Update at last hour
        entries.append(SimpleEntry(date: widgetData.endDate, timerEnd: widgetData.startDate)) // Update on timer end to clear
    }

    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
}
func formatDateAsDayHourMinuteSecond(_ date: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMM d h:mma" // Format for Month, Day, and Time (12-hour format)
            formatter.amSymbol = "am" // Optional: Set AM symbol
            formatter.pmSymbol = "pm" // Optional: Set PM symbol
            return formatter.string(from: date)
}

var body: some View {
    ZStack {
        if entry.timerEnd > Date.now {
            if let timerSeconds = Calendar.current.dateComponents([.second], from: .now, to: entry.timerEnd).second {
                Text("\(timerSeconds)") // I would expect this to change on update, but it never does indicating the timeline is being ignored.
                if isLuminanceReduced {
                    Text(formatDateAsDayHourMinuteSecond(entry.timerEnd)).multilineTextAlignment(.center)
                } else {
                    // Greater than one day
                    if timerSeconds > 86400 {
                        Text(formatDateAsDayHourMinuteSecond(entry.timerEnd)).multilineTextAlignment(.center)
                    }
                    
                    // Greater than 1 hour and less than 1 day
                    if timerSeconds > 3600 && timerSeconds < 86400 {
                        // less than one day
                        Text(entry.timerEnd, style: .relative).multilineTextAlignment(.center)
                    }
                    
                    // Less than one hour
                    if timerSeconds <= 3600 {
                        Text(entry.timerEnd, style: .timer)
                            .multilineTextAlignment(.center)
                    }
                }
            }
        }
        
        Image("ComplicationIcon").opacity(entry.timerEnd < Date.now ? 1 : 0.33)
    }
}
swift swiftui watchos widgetkit
1个回答
0
投票

我在 watchOS 上的 WidgetKit 中遇到了类似的问题。即使手表处于开发人员模式并且应用程序连接到调试器,时间线更新也可能不一致。根据您的代码,以下是一些观察和建议:

潜在问题

  1. watchOS 上的 WidgetKit 的更新时间可能无法预测,即使在开发者模式下也是如此。
  2. .atEnd
    时间线策略可能不适合您的用例。
  3. 您的时间线条目可能不按时间顺序排列。

建议的解决方案

1.按时间顺序对条目进行排序

entries.sort { $0.date < $1.date }

2.使用
.never
作为重新加载策略并添加一个远期条目

entries.append(SimpleEntry(date: Date().addingTimeInterval(86400), timerEnd: widgetData.endDate))
let timeline = Timeline(entries: entries, policy: .never)

3.实施
recommendations(for:)
方法

这可以建议更频繁的更新时间:

func recommendations(for configuration: ConfigurationIntent, completionHandler: @escaping (TimelineProviderRecommendations<SimpleEntry>) -> Void) {
    // Your existing code to create entries
    let recommendations = TimelineProviderRecommendations(entries: entries, refreshAfter: Date().addingTimeInterval(300))
    completionHandler(recommendations)
}

4.在您的
body

中使用当前日期

确保您始终使用当前日期,而不是输入日期:

if let timerSeconds = Calendar.current.dateComponents([.second], from: Date(), to: entry.timerEnd).second {
    // Your existing code
}

额外提示

  • 在实际的手表设备上进行测试,而不仅仅是模拟器。
  • 如果这些解决方案不起作用,请考虑使用后台刷新或推送通知来强制更新小部件。

请记住,WidgetKit 的行为可能因 watchOS 版本而异,因此请确保您在目标操作系统版本上进行测试。

© www.soinside.com 2019 - 2024. All rights reserved.