0Pricing
Swift Academy · Урок

Поставщики временных шкал и снимки

Обеспечьте обновление содержимого виджета со временем.

«Поставщики временных шкал и снимки» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Создание виджета WidgetKit
  2. Поставщики временных шкал и снимки
  3. Обзор расширений приложений
  4. App Intents и быстрые команды
← Назад к Swift Academy