Поставщики временных шкал и снимки
Обеспечьте обновление содержимого виджета со временем.
«Поставщики временных шкал и снимки» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Задача поставщика
Виджет не обновляется непрерывно самостоятельно. Вместо этого TimelineProvider передаёт WidgetKit расписание заранее отрисованных записей, а система показывает каждую из них в нужный момент. Поставщик отвечает на три вопроса: placeholder, снимок и timeline.
import WidgetKit
// TimelineProvider supplies:
// placeholder(in:) -> instant skeleton
// getSnapshot(in:) -> one entry for previews
// getTimeline(in:) -> future entries + refresh policyСоответствие TimelineProvider
Поставщик соответствует TimelineProvider и имеет связанный тип Entry. Вам нужно реализовать три метода; каждый из них передаёт Context, описывающий семейство и указывающий, является ли это предварительным просмотром.
import WidgetKit
struct WeatherProvider: TimelineProvider {
typealias Entry = WeatherEntry
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(),
temperature: 20, condition: "Sunny")
}
// getSnapshot and getTimeline follow
}Заполнитель
placeholder(in:) должен мгновенно возвращать демонстрационные данные, близкие к реальным. Система показывает их в виде замаскированного макета, пока загружается настоящий виджет, а также в галерее виджетов. Не выполняйте здесь сетевые операции или операции с диском.
import WidgetKit
func placeholder(in context: Context) -> WeatherEntry {
// Synchronous, fake data, no I/O
WeatherEntry(date: Date(),
temperature: 0, condition: "--")
}Снимок
getSnapshot предоставляет одну запись для временных ситуаций, например для предварительного просмотра в галерее виджетов. Метод должен возвращать результат быстро. Когда context.isPreview имеет значение true, используйте демонстрационные данные вместо медленной загрузки, чтобы галерея открывалась мгновенно.
import WidgetKit
func getSnapshot(
in context: Context,
completion: @escaping (WeatherEntry) -> Void) {
if context.isPreview {
completion(WeatherEntry(date: Date(),
temperature: 22, condition: "Clear"))
} else {
completion(currentEntry())
}
}Временная шкала
getTimeline — центральный метод: Вы создаёте массив будущих записей и объединяете его с политикой обновления в объекте Timeline. Система отображает каждую запись в момент, указанный в её поле date, а затем запрашивает новую временную шкалу в соответствии с политикой.
import WidgetKit
func getTimeline(
in context: Context,
completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let entries = buildEntries()
let timeline = Timeline(
entries: entries, policy: .atEnd)
completion(timeline)
}Политики обновления
Политика обновления определяет, когда WidgetKit запрашивает следующую временную шкалу: .atEnd — после даты последней записи, .after(date) — в указанное время или .never — пока Вы не выполните обновление вручную. Система учитывает доступные ресурсы, поэтому не следует ожидать обновлений каждую секунду.
import WidgetKit
// .atEnd -> reload after final entry
// .after(someDate) -> reload at a chosen time
// .never -> only on manual reloadTimelines
let policy = TimelineReloadPolicy.atEnd
_ = policyСоздание будущих записей
Обычно заранее вычисляют записи на несколько следующих часов, чтобы виджет обновлялся без запуска Вашего кода каждый раз. Создавайте записи через определённые интервалы, начиная с текущего момента и на будущее, помещая в каждую данные для соответствующего момента.
import WidgetKit
import Foundation
func hourlyEntries() -> [WeatherEntry] {
var entries: [WeatherEntry] = []
let now = Date()
for hour in 0..<6 {
let date = Calendar.current.date(
byAdding: .hour, value: hour, to: now)!
entries.append(WeatherEntry(date: date,
temperature: 18 + hour, condition: "Sunny"))
}
return entries
}Асинхронные данные во временной шкале
Если необходимо получить данные из сети, сделайте это до вызова обработчика завершения. Оберните асинхронную работу в Task и завершайте операцию только после получения данных. Работайте быстро: у поставщиков очень ограничен доступный интервал времени.
import WidgetKit
func getTimeline(
in context: Context,
completion: @escaping (Timeline<WeatherEntry>) -> Void) {
Task {
let entry = await fetchForecast()
let timeline = Timeline(
entries: [entry], policy: .after(
Date().addingTimeInterval(3600)))
completion(timeline)
}
}
func fetchForecast() async -> WeatherEntry {
WeatherEntry(date: Date(),
temperature: 21, condition: "Cloudy")
}Актуальность и доступные ресурсы
WidgetKit ограничивает количество обновлений в день, чтобы экономить заряд аккумулятора. Нельзя принудительно выполнять частые обновления. Добавляйте несколько записей в каждую временную шкалу и выбирайте разумное время обновления; вызывайте reloadTimelines из приложения только при значительных изменениях данных.
import WidgetKit
// The system, not you, decides exact refresh timing.
// Strategy: pre-bake multiple entries + a sensible policy
// + app-driven reloads on real changes.
let budget = "refreshes are budgeted by the OS"
_ = budgetПоставщик настраиваемых виджетов
Для виджета с конфигурацией AppIntentConfiguration используйте вместо него AppIntentTimelineProvider. Его методы получают настроенное пользователем действие, поэтому Вы можете загружать данные для выбранного варианта — выбранного города, учётной записи и т. д.
import WidgetKit
// AppIntentTimelineProvider adds the configuration:
// func timeline(for configuration: MyIntent,
// in context: Context)
// async -> Timeline<Entry>
let configurable = "intent-aware provider"
_ = configurableСборка поставщика
Полный поставщик мгновенно возвращает заполнитель, быстро формирует снимок с учётом предварительного просмотра и предоставляет временную шкалу заранее подготовленных записей с подходящей политикой обновления. Благодаря этому виджет остаётся актуальным в пределах доступных системе ресурсов.
import WidgetKit
// 1. placeholder -> instant dummy
// 2. getSnapshot -> sample when isPreview, else current
// 3. getTimeline -> [entries] + .atEnd or .after
let summary = "three methods, one current widget"
_ = summaryБыстрая проверка
Вспомните ограничение, которому должен соответствовать метод заполнителя.
Повторение
Вы изучили поставщиков временных шкал:
placeholderмгновенно возвращает демонстрационные данные;getSnapshotвозвращает одну запись, используя демонстрационные данные при значенииisPreview;getTimelineвозвращает будущие записи и политику.- Политики обновления —
.atEnd,.after(date)или.never; OS ограничивает фактическую частоту обновлений. - Заранее создавайте несколько записей; выполняйте асинхронную загрузку до завершения операции.
- Для настраиваемых виджетов используйте
AppIntentTimelineProvider.
Часто задаваемые вопросы
Урок «Поставщики временных шкал и снимки» бесплатный?
Да — полный текст урока «Поставщики временных шкал и снимки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Поставщики временных шкал и снимки»?
Обеспечьте обновление содержимого виджета со временем. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Поставщики временных шкал и снимки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Создание виджета WidgetKit
- Поставщики временных шкал и снимки
- Обзор расширений приложений
- App Intents и быстрые команды