ผู้ให้บริการไทม์ไลน์และสแนปชอต
จัดเตรียมเนื้อหาวิดเจ็ตตามช่วงเวลา
ผู้ให้บริการไทม์ไลน์และสแนปชอต เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
หน้าที่ของผู้ให้บริการ
วิดเจ็ตจะไม่อัปเดตตัวเองอย่างต่อเนื่อง แต่ TimelineProvider จะส่งกำหนดการของรายการที่แสดงผลไว้ล่วงหน้าให้ WidgetKit จากนั้นระบบจะแสดงแต่ละรายการตามเวลาที่กำหนด ผู้ให้บริการจะตอบคำถามสามข้อ ได้แก่ placeholder ภาพตัวอย่าง และไทม์ไลน์
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
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 เป็นจริง ให้ใช้ข้อมูลตัวอย่างแทนการดึงข้อมูลที่ใช้เวลานาน เพื่อให้แกลเลอรีแสดงผลได้ทันที
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 ระบบจะแสดงผลแต่ละรายการตามวันที่ของรายการนั้น จากนั้นจะขอไทม์ไลน์ใหม่ตามนโยบาย
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การประกอบผู้ให้บริการ
ผู้ให้บริการที่สมบูรณ์ควรมี placeholder ที่คืนค่าได้ทันที ภาพตัวอย่างที่รวดเร็วและรองรับโหมดแสดงตัวอย่าง และไทม์ไลน์ของรายการที่เตรียมไว้ล่วงหน้าพร้อมนโยบายการโหลดซ้ำที่เหมาะสม เพื่อให้วิดเจ็ตยังคงเป็นปัจจุบันภายใต้งบประมาณของระบบ
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
สรุปทบทวน
คุณได้เรียนรู้เรื่องผู้ให้บริการไทม์ไลน์แล้ว:
placeholderคืนค่าข้อมูลจำลองได้ทันทีgetSnapshotคืนค่ารายการเดียว โดยใช้ข้อมูลตัวอย่างเมื่อisPreviewเป็นจริง และgetTimelineคืนค่ารายการในอนาคตพร้อมนโยบาย- นโยบายการโหลดซ้ำได้แก่
.atEnd,.after(date)หรือ.neverส่วน OS จะจัดสรรงบประมาณสำหรับการรีเฟรชจริง - เตรียมรายการหลายรายการไว้ล่วงหน้า และดำเนินการดึงข้อมูลแบบอะซิงโครนัสก่อนทำงานให้เสร็จสิ้น
- วิดเจ็ตที่ปรับแต่งได้ใช้
AppIntentTimelineProvider
คำถามที่พบบ่อย
บทเรียน “ผู้ให้บริการไทม์ไลน์และสแนปชอต” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ผู้ให้บริการไทม์ไลน์และสแนปชอต” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ผู้ให้บริการไทม์ไลน์และสแนปชอต”
จัดเตรียมเนื้อหาวิดเจ็ตตามช่วงเวลา คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ผู้ให้บริการไทม์ไลน์และสแนปชอต” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้างวิดเจ็ตด้วย WidgetKit
- ผู้ให้บริการไทม์ไลน์และสแนปชอต
- ภาพรวมส่วนขยายแอป
- App Intents และทางลัด