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

查看:534
本文介绍了如何在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)
    }
    
}

推荐答案

不允许您每秒刷新小部件 .这就是Apple的限制.

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

您能做的就是以 seconds 显示日期 使用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)时,您将设置 最早 的时间设置为刷新.


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天全站免登陆