WidgetKit là một framework của Apple được giới thiệu trong iOS 14, cho phép các nhà phát triển đặt widget động trên màn hình chính của iPhone và iPad, màn hình nền Mac và mặt đồng hồ Apple Watch. Widget hiển thị thông tin chính mà không cần mở ứng dụng — dự báo thời tiết, tỷ giá hối đoái, lịch, số bước. Theo Apple Developer Documentation, 2026, WidgetKit xử lý tới 2 tỷ lượt cập nhật widget mỗi ngày trong hệ sinh thái Apple, khiến nó trở thành một trong những framework được sử dụng nhiều nhất để hiển thị thông tin trên màn hình hệ thống.
Những điểm chính
WidgetKit là framework của Apple để tạo widget hiển thị nội dung trên màn hình hệ thống của thiết bị Apple. Widget là một biểu diễn thu nhỏ của ứng dụng mà người dùng đặt trên màn hình chính ở chế độ jiggle. Không giống như các complication watchOS tồn tại trước WidgetKit, framework mới đã thống nhất việc tạo widget cho tất cả nền tảng Apple thông qua một API SwiftUI duy nhất.
Nguyên lý hoạt động của WidgetKit dựa trên TimelineProvider — một đối tượng tạo mảng có thứ tự các TimelineEntry, trong đó mỗi mục chứa Snapshot (trạng thái cụ thể của widget tại một thời điểm nhất định). Hệ thống hiển thị các mục tuần tự, cập nhật widget khi chuyển sang mục tiếp theo trên dòng thời gian. Giữa các mục, WidgetKit không gọi mã ứng dụng — thời gian CPU chỉ được tiêu tốn khi tạo Timeline mới.
Theo phiên WWDC 2024 “WidgetKit: What’s new”, người dùng iOS trung bình có 8–12 widget trên màn hình chính, với các danh mục phổ biến nhất là thời tiết, thời gian, lịch, thể dục và tài chính. WidgetKit tiêu thụ ít hơn 1% pin mỗi ngày khi sử dụng thông thường nhờ các bản cập nhật theo lịch trình thay vì thời gian thực.
Trước iOS 14, widget chỉ tồn tại dưới dạng Today View — một bảng có thể truy cập bằng cách vuốt sang trái từ màn hình đầu tiên. Today Extensions có những hạn chế nghiêm trọng: chỉ khả dụng trên màn hình “Hôm nay”, yêu cầu mở ứng dụng để cập nhật nội dung và hỗ trợ kích thước hạn chế. WidgetKit đã thay thế hoàn toàn Today Extensions, cung cấp widget trên màn hình chính, màn hình khóa (iOS 16+) và màn hình nền Mac.
Kiến trúc WidgetKit được xây dựng trên ba giao thức chính: TimelineProvider, TimelineEntry và Widget. TimelineEntry là mô hình dữ liệu đại diện cho trạng thái widget tại một thời điểm cụ thể. TimelineProvider tạo một mảng các mục như vậy (Timeline), chỉ định ngày kích hoạt cho mỗi mục. Widget là điểm vào kết nối nhà cung cấp với view SwiftUI.
Phương thức Timeline getTimeline được hệ thống gọi khi widget được thêm lần đầu và sau đó định kỳ — thường là mỗi 1–6 giờ tùy thuộc vào loại nhà cung cấp. Timeline có thể chứa các mục cho nhiều giờ hoặc nhiều ngày tới, cho phép widget hoạt động mà không cần gọi mã ứng dụng giữa các lần cập nhật. Nếu cần cập nhật widget khẩn cấp (ví dụ: tỷ giá hối đoái thay đổi), ứng dụng có thể gọi WidgetCenter.shared.reloadAllTimelines() một cách bắt buộc.
struct SimpleEntry: TimelineEntry {
let date: Date
let value: Double
}
struct Provider: TimelineProvider {
typealias Entry = SimpleEntry
func placeholder(in context: Context) -> Entry {
Entry(date: Date(), value: 0)
}
func getSnapshot(
in context: Context,
completion: @escaping (Entry) -> Void
) {
Entry(date: Date(), value: 42.5)
}
func getTimeline(
in context: Context,
completion: @escaping (Timeline<Entry>, Error?) -> Void
) {
let entry = Entry(date: Date(), value: fetchLatestValue())
let nextUpdate = Calendar.current
.date(byAdding: .hour, value: 1, to: Date())!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline, nil)
}
}
WidgetKit hỗ trợ ba kích thước widget, mỗi kích thước có tỷ lệ cố định. Small (170×170 pt trên iPhone) hiển thị thông tin nhỏ gọn — một giá trị, biểu tượng hoặc văn bản ngắn. Medium (364×170 pt) rộng gấp đôi small và phù hợp để hiển thị cặp giá trị hoặc biểu đồ nhỏ. Large (364×382 pt) chiếm gần một nửa màn hình theo chiều dọc và cho phép hiển thị bảng, danh sách hoặc dữ liệu mở rộng.
Nhà phát triển phải hỗ trợ ít nhất hai kích thước — Apple khuyến nghị small + medium. Widget Large chỉ cần thiết nếu ứng dụng có đủ nội dung để lấp đầy khối lượng đó. Mỗi kích thước có SwiftUI View riêng, được WidgetKit kết xuất trên màn hình hệ thống. Quan trọng là WidgetKit không hỗ trợ kích thước tùy chỉnh — chỉ ba kích thước cố định, đảm bảo tính nhất quán của giao diện.
struct WeatherWidget: Widget {
let kind: String = "WeatherWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WeatherWidgetView(entry: entry)
}
.configurationDisplayName("Weather")
.description("Current temperature and forecast")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
WidgetKit cung cấp hai loại cấu hình — StaticConfiguration và IntentConfiguration. StaticConfiguration phù hợp với widget hiển thị cùng nội dung cho tất cả người dùng: tỷ giá hối đoái, thời tiết, lịch. IntentConfiguration cho phép người dùng tùy chỉnh widget khi thêm nó thông qua hệ thống intent Siri — ví dụ: chọn thành phố cụ thể cho thời tiết hoặc mã cổ phiếu cụ thể cho giá chứng khoán.
IntentConfiguration sử dụng INWidgetIntent — một lớp con của INIntent từ SiriKit. Khi người dùng thêm widget và chọn tham số (ví dụ: thành phố), hệ thống lưu intent này và truyền nó cho TimelineProvider mỗi lần cập nhật. Nhà cung cấp nhận intent trong phương thức getTimeline và sử dụng các tham số của nó để tạo nội dung. IntentConfiguration là cách ưa thích cho widget được cá nhân hóa vì nó tích hợp với Siri và Shortcuts.
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text(entry.cityName)
.font(.caption)
.foregroundColor(.secondary)
Text("\(entry.temperature)°C")
.font(.largeTitle)
}
}
}
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
IntentConfiguration(
kind: "WeatherWidget",
intent: WeatherConfigIntent.self,
provider: WeatherTimelineProvider()
) { entry in
WeatherWidgetEntryView(entry: entry)
}
}
}
Việc tạo widget bắt đầu bằng cách thêm Widget Extension Target trong Xcode: File → New → Target → Widget Extension. Xcode tự động tạo cấu trúc với TimelineEntry, TimelineProvider và WidgetConfiguration. Nhà phát triển chỉ cần triển khai SwiftUI View để hiển thị dữ liệu và cấu hình nhà cung cấp cho lịch trình cập nhật chính xác.
Dưới đây là ví dụ đầy đủ về một widget đơn giản hiển thị giá Bitcoin hiện tại: Provider tải tỷ giá qua URLSession và tạo Timeline với cập nhật mỗi giờ. WidgetSwiftUIView hiển thị tỷ giá bằng phông chữ lớn và thời gian cập nhật cuối bằng phông chữ nhỏ.
struct BTCPriceEntry: TimelineEntry {
let date: Date
let price: Double
let change24h: Double
}
struct BTCWidgetEntryView: View {
var entry: BTCPriceEntry
var body: some View {
VStack {
Text("BTC/USD").font(.caption)
Text("$\(entry.price, specifier: "%.0f")")
.font(.title2).fontWeight(.bold)
Text(entry.change24h > 0 ? "+" : "")
}
}
}
Với iOS 16, WidgetKit đã mở rộng hỗ trợ cho Màn hình khóa — màn hình khóa iPhone. Widget màn hình khóa có hai loại: inline (một dòng văn bản dưới đồng hồ) và rectangular (vùng hình chữ nhật). Không giống như widget màn hình chính, widget màn hình khóa được cập nhật thường xuyên hơn — trình kích hoạt hệ thống cho phép cập nhật mỗi 15–30 phút để hiển thị thông tin hiện tại mà không cần mở khóa điện thoại.
Widget màn hình khóa yêu cầu cấu hình riêng qua WidgetConfiguration với accessoryFamilies: accessoryCircular, accessoryRectangular, accessoryInline. Các họ này có giới hạn nghiêm ngặt về kích thước và nội dung — chúng không hỗ trợ hình ảnh, hoạt ảnh hoặc phông chữ tùy chỉnh. Apple khuyến nghị chỉ sử dụng thông tin văn bản và biểu tượng hệ thống SF Symbols cho widget màn hình khóa.
Khi phát triển widget, điều quan trọng là phải xem xét các giới hạn của WidgetKit. Widget là các view chỉ đọc: chúng không xử lý sự kiện chạm (ngoại trừ chạm để mở ứng dụng). Widget không hỗ trợ hoạt ảnh, video, nhập bàn phím, cuộn hoặc các phần tử tương tác. Mỗi widget là một ảnh chụp nhanh tĩnh của dữ liệu tại một thời điểm nhất định và cố gắng thêm tính tương tác sẽ dẫn đến việc ứng dụng bị từ chối trên App Store.
Các thực tiễn tốt nhất bao gồm sử dụng Widget Center để cập nhật bắt buộc, lưu dữ liệu vào bộ nhớ đệm ở cấp TimelineProvider để phản hồi nhanh và sử dụng placeholder cho trạng thái ban đầu. Việc hỗ trợ nhiều kích thước cũng rất quan trọng — người dùng mong đợi widget có sẵn ở cả biến thể small và medium. Tránh hiển thị dữ liệu không chính xác hoặc lỗi thời — người dùng ghi nhớ thông tin sai từ widget trong một thời gian dài.
| Điều không được phép | Tại sao |
|---|---|
| Hoạt ảnh và video | Widget là ảnh chụp nhanh tĩnh; hoạt ảnh làm hao pin |
| Tính tương tác | WidgetKit không hỗ trợ phần tử UI ngoại trừ liên kết ứng dụng |
| Cuộn | Kích thước cố định không có cuộn |
| Bàn phím | Không thể nhập văn bản trong widget |
| Dữ liệu trực tiếp | Dữ liệu được cập nhật theo lịch Timeline, không phải thời gian thực |
| Kích thước tùy chỉnh | Chỉ có kích thước cố định small, medium, large, accessory* |
Câu hỏi thường gặp
Có, WidgetKit đa nền tảng. Cùng một Widget Extension có thể được đưa vào các target iOS, iPadOS và macOS với một mã SwiftUI duy nhất. Sự khác biệt chỉ xuất hiện ở các Family được hỗ trợ — Mac không có accessoryRectangular.
Theo lịch trình Timeline. Nhà phát triển xác định khi nào bản cập nhật tiếp theo sẽ diễn ra — trong một phút hoặc một ngày. Hệ thống cũng có thể tăng tốc cập nhật cho các widget được sử dụng thường xuyên.
Không, WidgetKit không hỗ trợ UIButton hoặc bất kỳ phần tử tương tác nào. Hành động duy nhất là chạm vào widget, mở ứng dụng qua deep link.
Sử dụng WidgetCenter.shared.reloadAllTimelines() hoặc reloadTimelines(ofKind:) cho một widget cụ thể. Lệnh gọi từ ứng dụng ngay lập tức yêu cầu Timeline mới từ nhà cung cấp.
Tối thiểu — ít hơn 1% pin mỗi ngày khi sử dụng thông thường. WidgetKit giới hạn cập nhật nền và không giữ ứng dụng hoạt động. Chi phí chính là tạo Timeline khi thêm lần đầu.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm