我在让我的小部件按照时间线安排更新时遇到问题。我的手表处于开发人员模式,因此正常预算不应与附加到调试器的应用程序一起应用。我有以下代码,需要输入日期,例如现在 + 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)
}
}
我在 watchOS 上的 WidgetKit 中遇到了类似的问题。即使手表处于开发人员模式并且应用程序连接到调试器,时间线更新也可能不一致。根据您的代码,以下是一些观察和建议:
.atEnd
时间线策略可能不适合您的用例。entries.sort { $0.date < $1.date }
.never
作为重新加载策略并添加一个远期条目entries.append(SimpleEntry(date: Date().addingTimeInterval(86400), timerEnd: widgetData.endDate))
let timeline = Timeline(entries: entries, policy: .never)
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)
}
body
确保您始终使用当前日期,而不是输入日期:
if let timerSeconds = Calendar.current.dateComponents([.second], from: Date(), to: entry.timerEnd).second {
// Your existing code
}
请记住,WidgetKit 的行为可能因 watchOS 版本而异,因此请确保您在目标操作系统版本上进行测试。