Section 6/141 menit

6. Timeline Provider Lanjutan

6. Timeline Provider Lanjutan

Async TimelineProvider

Untuk network request, gunakan AppIntentTimelineProvider (iOS 17+) atau TimelineProvider dengan completion-based async:

swift
struct NewsProvider: TimelineProvider {
    func getTimeline(in context: Context, completion: @escaping (Timeline<NewsEntry>) -> Void) {
        Task {
            do {
                let articles = try await NewsAPI.fetchLatest()
                var entries: [NewsEntry] = []
                let now = Date()

                // Buat satu entry per jam untuk 6 jam ke depan
                for hourOffset in 0..<6 {
                    let entryDate = Calendar.current.date(
                        byAdding: .hour,
                        value: hourOffset,
                        to: now
                    ) ?? now
                    // Tampilkan artikel berbeda di tiap jam
                    let article = articles[hourOffset % articles.count]
                    entries.append(NewsEntry(date: entryDate, article: article))
                }

                let timeline = Timeline(entries: entries, policy: .atEnd)
                completion(timeline)
            } catch {
                // Fallback jika network error
                let fallback = NewsEntry(date: Date(), article: .placeholder)
                let timeline = Timeline(entries: [fallback], policy: .after(Date().addingTimeInterval(3600)))
                completion(timeline)
            }
        }
    }
}

Refresh Manual dari App

swift
// Di app utama — panggil setelah data berubah
import WidgetKit

func userCompletedHabit() {
    saveHabitDataToSharedDefaults()

    // Reload hanya widget tertentu
    WidgetCenter.shared.reloadTimelines(ofKind: "HabitWidget")

    // Atau reload semua widget
    WidgetCenter.shared.reloadAllTimelines()
}

Relevant dan Kontekstual (iOS 16+)

swift
// Beri tahu sistem kapan widget paling relevan untuk ditampilkan di Smart Stack
struct SmartHabitProvider: TimelineProvider {
    func getTimeline(in context: Context, completion: @escaping (Timeline<HabitEntry>) -> Void) {
        var entries: [HabitEntry] = []

        // Entry pagi — widget paling relevan saat pengguna biasanya olahraga
        let morningDate = Calendar.current.date(
            bySettingHour: 7, minute: 0, second: 0, of: Date()
        ) ?? Date()

        let morningEntry = HabitEntry(date: morningDate, habitName: "Olahraga", isCompleted: false, streak: 5)
        entries.append(morningEntry)

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}