如何在 iOS 14 Home Widget 中显示当前时间(实时) [英] How to display Current Time (Realtime) in iOS 14 Home Widget

查看:33
本文介绍了如何在 iOS 14 Home Widget 中显示当前时间(实时)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 ios 14 Home Widget 开发应用程序,但在显示当前时间(数字时钟)时遇到问题,该小部件没有每秒更新一次.众所周知,Apple 不允许每秒触发时间轴,有没有其他方法可以通过实时更新显示当前时间?

I am developing an application for ios 14 Home Widget and I am facing a problem while showing the current time (digital clock) that the widget not getting updated every sec. As we all know, Apple does not allow to trigger timeline every second is there any other way to display the current time with the realtime updates?

我尝试了这些方法,但没有按预期工作

I tried these methods but not works as expected

class NetworkManager: ObservableObject {
    @Published var dateIs = Date()
    
    init() {
        startTimer() // fetch data must be called at least once
    }
    private  func startTimer() { 
        let t = RepeatingTimer(timeInterval: 3)
                t.eventHandler = {
                    DispatchQueue.main.async() {
                        // your UI update code
                        print("Timer Fired")
                     self.dateIs = Date()
                        WidgetCenter.shared.reloadAllTimelines() // reload timelines
                    }
                    if(false){   //I know this makes no sense, but it works. Go figure...
                        t.suspend()
                    }
                }
                t.resume()

    }
}


struct Provider: TimelineProvider {

    init() {
        networkManager = NetworkManager()
    }

    
    @AppStorage("storedData", store: UserDefaults(suiteName: "group.com.name"))
    var data: Data  = Data()
    
    func placeholder(in context: Context) -> WidgetEntry {
        let entry = WidgetEntry(date: Date(), storedData: storedData[0], dateIs: networkManager.dateIs)
        return entry
    }
    
    func getSnapshot(in context: Context, completion: @escaping (WidgetEntry) -> Void) {
        
        guard let storedData: WidgetTemplate = try? JSONDecoder().decode(WidgetTemplate.self, from: data) else { return }
        let entry = WidgetEntry(date: Date(), storedData: storedData, dateIs: networkManager.dateIs)
          
        completion(entry)
    }
    
    func getTimeline(in context: Context, completion: @escaping (Timeline<WidgetEntry>) -> Void) {
    
        guard let storedData: WidgetTemplate = try? JSONDecoder().decode(WidgetTemplate.self, from: data) else { return }
        let entry = WidgetEntry(date: Date(), storedData: storedData, dateIs: networkManager.dateIs)
        
        let currentDate = Date()
        let refreshDate = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)!
        
        let timeline = Timeline(entries: [entry], policy:  .after(refreshDate))
        completion(timeline)
    }
    
}

推荐答案

您不能每秒刷新 Widget.这就是 Apple 的限制.

You’re not allowed to refresh the Widget every second. That’s the limitation from Apple.

你能做的最好的就是用显示一个日期使用 timer 日期样式:

Best you can do is display a date with seconds using the timer date style:

/// A style displaying a date as timer counting from now.
///
///     Text(event.startDate, style: .timer)
///
/// Example output:
///    2:32
///    36:59:01
public static let timer: Text.DateStyle


  1. 您需要一个带有 Date 属性的简单 Entry:
  1. You need a simple Entry with a Date property:

struct SimpleEntry: TimelineEntry {
    let date: Date
}

  1. Entry中传递给定日期的午夜日期,并在下一个午夜之后刷新时间线:
  1. Pass the midnight date for a given day in the Entry and refresh the timeline after the next midnight:

struct SimpleProvider: TimelineProvider {
    ...

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let midnight = Calendar.current.startOfDay(for: Date())
        let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!
        let entries = [SimpleEntry(date: midnight)]
        let timeline = Timeline(entries: entries, policy: .after(nextMidnight))
        completion(timeline)
    }
}

  1. 使用 timer 样式显示日期:
  1. Display the date using the timer style:

struct SimpleWidgetEntryView: View {
    var entry: SimpleProvider.Entry

    var body: some View {
        Text(entry.date, style: .timer)
    }
}


请注意,当您刷新时间线时(通过指定 TimelineReloadPolicy 或通过调用 WidgetCenter),您将设置 earliest Widget 刷新的时间.


Note that when you refresh the timeline (either by specifying the TimelineReloadPolicy or by calling the WidgetCenter) you set the earliest time when the Widget will be refreshed.

不保证在特定时间刷新.

It is not guaranteed to be refreshed at that specific time.

这篇关于如何在 iOS 14 Home Widget 中显示当前时间(实时)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆