iOS Widget 04 - Widget Clock Refresh

I did write a clock widget, but I found that there is a problem every time the clock is refreshed. eg. now is 17:42:25, the widget still is 17:41, maybe after 10 seconds, it can be refreshed with 17:42. I want just 17:43:00, it can be refreshed.

Demo-04 Download.zip

Preview

Add Widget Display
img img

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
struct DemoProvider: IntentTimelineProvider {
    func placeholder(in context: Context) -> DemoEntry {
        DemoEntry(date: Date(), configuration: ConfigurationIntent())
    }

    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (DemoEntry) -> ()) {
        let entry = DemoEntry(date: Date(), configuration: configuration)
        completion(entry)
    }

    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<DemoEntry>) -> ()) {
        
        // First refresh time: 2 seconds delay
        let firstDate = DemoProvider.getFirstEntryDate()
        // Second refresh time: When at the first full minute refresh
        let firstMinuteDate = DemoProvider.getFirstMinuteEntryDate()
        
        var entries: [DemoEntry] = []
        entries.append(DemoEntry(date: firstDate, configuration: configuration))
        entries.append(DemoEntry(date: firstMinuteDate, configuration: configuration))
        
        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        for offset in 1 ..< 5 {
            guard let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: firstMinuteDate) else {
                continue
            }
            let entry = DemoEntry(date: entryDate, configuration: configuration)
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
    
    static func getFirstEntryDate() -> Date {
        let offsetSecond: TimeInterval = TimeInterval(2)
        var currentDate = Date()
        currentDate += offsetSecond
        return currentDate
    }
    
    // Get the time point of the first minute time point
    // eg: 14:10:00
    static func getFirstMinuteEntryDate() -> Date {
        var currentDate = Date()
        let passSecond = Calendar.current.component(.second, from: currentDate)
        let offsetSecond: TimeInterval = TimeInterval(60 - passSecond)
        currentDate += offsetSecond
        return currentDate
    }
}

struct CYClockTime {
    var sec: Int
    var min: Int
    var hour: Int
}

struct DemoEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationIntent
    
    func clockTime() -> CYClockTime {
        let date = self.date
        let calendar = Calendar.current
        let hour = calendar.component(.hour, from: date)
        let min = calendar.component(.minute, from: date)
        let sec = calendar.component(.second, from: date)
        print("\(hour) \(min) \(sec) || \(self.date)")
        return CYClockTime(sec: sec, min: min, hour: hour)
    }
    
    func clockHHss() -> String {
        let hour = String(format: "%.2d", clockTime().hour)
        let min = String(format: "%.2d", clockTime().min)
        return hour + " " + min
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Widget View
struct DemoWidgetEntryView : View {
    var entry: DemoProvider.Entry

    let width = (UIScreen.main.bounds.width - 50) / 3
    
    var body: some View {
            Text("\(entry.clockHHss())")
    }
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy