BGTaskScheduler là một framework của Apple để lên lịch và thực thi các tác vụ nền trong ứng dụng iOS 13 trở lên. Nó thay thế Background Fetch và performFetch lỗi thời, cung cấp một API thống nhất để làm việc với các hoạt động nền. Theo Apple Developer Documentation, 2026, framework bao gồm hai loại tác vụ: BGProcessingTask cho các hoạt động dài và BGAppRefreshTask cho các cập nhật nội dung ngắn.
Những điểm chính
BGTaskScheduler là một framework hệ thống của Apple được giới thiệu trong iOS 13, quản lý tập trung việc thực thi các tác vụ nền. Trước khi nó ra đời, các nhà phát triển sử dụng UIApplication backgroundTasks, performFetch và xử lý sự kiện trong appDelegate, dẫn đến phân mảnh mã và hành vi không thể đoán trước.
Framework hoạt động theo nguyên tắc lên lịch hoãn lại: ứng dụng đăng ký tác vụ với các định danh duy nhất, và iOS tự xác định thời điểm tối ưu để thực thi chúng. Hệ thống xem xét mức pin, hoạt động của người dùng, trạng thái mạng và các yếu tố khác.
Các khả năng chính bao gồm làm việc với cả hoạt động nền ngắn và dài. Không giống như AlarmManager trên Android, BGTaskScheduler không đảm bảo thời gian thực thi chính xác — hệ thống có quyền trì hoãn tác vụ nếu điều kiện không thuận lợi.
BGTaskScheduler sử dụng kiến trúc dựa trên bộ xử lý (handler). Ứng dụng đăng ký một handler cho mỗi loại tác vụ, và hệ thống gọi nó khi đến thời điểm thích hợp. Bản thân framework không trực tiếp thực thi tác vụ — nó chỉ thông báo cho ứng dụng rằng đã đến lúc chạy nó.
Việc đăng ký bắt đầu bằng cách khai báo định danh tác vụ trong Info.plist thông qua mảng BGTaskSchedulerPermittedIdentifiers. Sau đó, trong mã ứng dụng, phương thức registerHandler(forTaskWithIdentifier:) được gọi với một closure handler.
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// được gọi khi kết thúc buộc
}
processBackgroundTask(task as! BGAppRefreshTask)
}
Sau khi đăng ký, ứng dụng phải yêu cầu thực thi tác vụ một cách rõ ràng thông qua submitTaskRequest. Yêu cầu chứa định danh tác vụ và ngày bắt đầu sớm nhất có thể. Hệ thống lưu yêu cầu và xử lý nó khi thấy điều kiện phù hợp.
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Lỗi lên lịch: \(error)")
}
BGTaskScheduler cung cấp hai loại tác vụ chính, mỗi loại được thiết kế cho trường hợp sử dụng riêng. Chọn đúng loại ảnh hưởng trực tiếp đến xác suất thực thi thành công tác vụ của hệ thống.
BGAppRefreshTask được thiết kế cho các cập nhật nội dung nền ngắn: tải dữ liệu mới, đồng bộ với máy chủ, cập nhật widget. Thời gian thực thi giới hạn ở 30 giây, sau đó hệ thống buộc kết thúc tác vụ. Loại tác vụ này chạy thường xuyên hơn BGProcessingTask và có ưu tiên cao hơn.
BGProcessingTask được thiết kế cho các hoạt động dài hơn: xử lý tệp phương tiện, lập chỉ mục Core Data, tạo bản sao lưu. Tác vụ có thể chạy đến vài phút, nhưng hệ thống khởi chạy nó ít thường xuyên hơn và chỉ trong điều kiện thuận lợi — kết nối nguồn, Wi-Fi ổn định và tải thiết bị thấp.
| Tham số | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Giới hạn thời gian | 30 giây | vài phút |
| Tần suất khởi chạy | cao | thấp |
| Điều kiện | bất kỳ | nguồn + Wi-Fi |
| Yêu cầu nguồn | không | khuyến nghị |
| Ví dụ | cập nhật feed | xử lý video |
Đăng ký chính xác là điều kiện bắt buộc để BGTaskScheduler hoạt động. Nếu một tác vụ không được đăng ký trong Info.plist, hệ thống sẽ bỏ qua mọi yêu cầu thực thi nó.
Tệp Info.plist phải bao gồm mảng BGTaskSchedulerPermittedIdentifiers với danh sách các định danh chuỗi. Mỗi định danh phải là duy nhất trong ứng dụng. Apple khuyến nghị sử dụng ký hiệu tên miền ngược.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
Để lên lịch một tác vụ, sử dụng phương thức submitTaskRequest. Nếu một tác vụ không còn cần thiết, nó có thể bị hủy qua cancelTaskRequest hoặc cancelAllTaskRequests. Hệ thống cũng tự động hủy tác vụ khi ứng dụng bị xóa hoặc dữ liệu được đặt lại.
BGTaskScheduler cung cấp khả năng theo dõi trạng thái của các tác vụ đã lên lịch thông qua getPendingTaskRequests. Phương thức này trả về danh sách tất cả các yêu cầu đang hoạt động với thông tin về loại, định danh và earliestBeginDate của chúng. Đối với mỗi yêu cầu, bạn có thể kiểm tra xem nó đã hoàn thành hay bị hủy và quyết định có lên lịch lại hay không.
Điều quan trọng cần lưu ý là hệ thống không cung cấp callback trực tiếp về sự thành công của tác vụ nền — bản thân handler phải báo cáo kết quả thông qua các thuộc tính của tác vụ. setTaskCompleted cho phép đánh dấu một tác vụ là đã hoàn thành thành công, sau đó hệ thống có thể khởi chạy tác vụ đã lên lịch tiếp theo của loại này. Nếu một tác vụ không gọi setTaskCompleted, hệ thống coi nó đã hoàn thành khi hết thời gian chờ hoặc bị kết thúc buộc.
Để chẩn đoán, khuyến nghị sử dụng OSLog trong handler và xem nhật ký qua Console.app trên Mac. Apple cũng cung cấp công cụ MetricKit để phân tích hiệu suất tác vụ nền — nó thu thập dữ liệu về thời gian thực thi, mức tiêu thụ năng lượng và tần suất khởi chạy có thể được sử dụng để tối ưu hóa.
// Hủy tác vụ cụ thể
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// Hủy tất cả tác vụ
BGTaskScheduler.shared.cancelAllTaskRequests()
// Kiểm tra tác vụ đã lên lịch
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("Đã lên lịch \(requests.count) tác vụ")
}
BGTaskScheduler áp đặt các giới hạn nghiêm ngặt đối với công việc nền. Hệ thống có thể trì hoãn một tác vụ vô thời hạn nếu điều kiện không thuận lợi. Các nhà phát triển phải hiểu rằng framework không dành cho các tác vụ thời gian thực.
Các giới hạn chính bao gồm: hệ thống không đảm bảo thực thi tác vụ vào thời gian chỉ định, số lượng tác vụ đồng thời tối đa bị giới hạn và mức tiêu thụ năng lượng được kiểm soát chặt chẽ. Chạy nhiều tác vụ liên tiếp có thể dẫn đến việc chúng bị hợp nhất hoặc hủy bỏ.
Để tăng khả năng thực thi, khuyến nghị đặt earliestBeginDate không sớm hơn 1 giờ cho BGProcessingTask và 15 phút cho BGAppRefreshTask. Việc xử lý expirationHandler cũng rất quan trọng — nếu một tác vụ không thể đáp ứng giới hạn thời gian, hệ thống gọi handler này để kết thúc thích hợp. Việc lên lịch lại nên được thực hiện bên trong chính handler để duy trì chu kỳ công việc nền liên tục.
Một giới hạn quan trọng khác liên quan đến yêu cầu mạng. BGTaskScheduler không đảm bảo kết nối mạng hoạt động trong quá trình thực thi tác vụ. Ứng dụng phải tự kiểm tra khả năng khả dụng của mạng qua NWPathMonitor và hoãn xử lý nếu không có kết nối. Điều này khác với Android JobScheduler, có thể kích hoạt tác vụ chỉ khi kết nối với một loại mạng cụ thể. Trong thực tế, các nhà phát triển thường kết hợp BGTaskScheduler với các phiên URL nền NSURLSession để tải dữ liệu đáng tin cậy.
Bắt đầu từ macOS Catalina, BGTaskScheduler cũng có sẵn trên Mac. Điều này cho phép tạo các tác vụ nền đa nền tảng cho các ứng dụng UIKit chạy trên Apple Silicon. Trên watchOS, framework có chức năng hạn chế — chỉ có BGAppRefreshTask ngắn để cập nhật complication và đồng bộ dữ liệu với iPhone. Các nhà phát triển nên tính đến sự khác biệt nền tảng khi lập kế hoạch kiến trúc nền.
Apple cung cấp một số công cụ để gỡ lỗi BGTaskScheduler. Lệnh e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] trong lldb buộc khởi chạy một tác vụ nền, bỏ qua các giới hạn hệ thống. Xcode có cờ Simulate Background Fetch trong menu Debug mô phỏng một cập nhật nền ngắn. MetricKit được sử dụng để phân tích hiệu suất — nó thu thập thông tin về tần suất khởi chạy, thời gian thực thi và mức tiêu thụ năng lượng của mỗi tác vụ. Dữ liệu này giúp tối ưu hóa tần suất lên lịch và chọn đúng loại tác vụ.
Trong thực tế, BGTaskScheduler phù hợp để cập nhật dữ liệu widget, đồng bộ iCloud, xử lý thông báo push có nội dung và lập chỉ mục cho tìm kiếm Spotlight. Nó không phù hợp cho phân tích thời gian thực, ứng dụng trò chuyện hoặc bất kỳ tác vụ nào yêu cầu thực thi ngay lập tức.
Để nghiên cứu sâu về BGTaskScheduler, Apple khuyến nghị tài liệu WWDC chính thức: phiên "Advances in Background Tasks" (2020) bao gồm việc di chuyển từ các API lỗi thời, và "Background Tasks in Practice" (2021) chứa các trường hợp sử dụng thực tế. Phần Energy Efficiency Guide cũng hữu ích, mô tả cách framework phù hợp với chiến lược tiết kiệm năng lượng tổng thể của Apple. Các ví dụ mã có sẵn trong kho lưu trữ chính thức của Apple Developer trên GitHub với các dự án hoàn chỉnh cho iOS và macOS.
Câu hỏi thường gặp
Background Fetch bị giới hạn ở một tác vụ nền cho mỗi ứng dụng và không có cơ chế ưu tiên. BGTaskScheduler hỗ trợ nhiều tác vụ với các loại khác nhau, cung cấp API thống nhất và quản lý năng lượng tự động.
Apple không đặt giới hạn rõ ràng về số lượng định danh được đăng ký, nhưng trong thực tế khuyến nghị sử dụng không quá 5–10 tác vụ. Số lượng lớn hơn làm giảm xác suất mỗi tác vụ cụ thể được thực thi do cạnh tranh tài nguyên hệ thống.
Để gỡ lỗi, sử dụng lệnh e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] trong lldb. Nó buộc khởi chạy một tác vụ, bỏ qua các giới hạn hệ thống. Cờ Xcode Simulate Background Fetch trong menu Debug cũng có sẵn.
Có, BGTaskScheduler có thể khởi chạy một tiến trình ngay cả khi ứng dụng bị người dùng buộc đóng. Tuy nhiên, hệ thống có thể áp dụng thêm độ trễ và không phải tất cả các loại tác vụ đều đảm bảo thực thi trong kịch bản này.
Hệ thống gọi expirationHandler, báo hiệu cho tác vụ rằng nó cần kết thúc. Nếu ứng dụng bỏ qua tín hiệu này và tiếp tục hoạt động, iOS buộc kết thúc tiến trình. Sau đó, hệ thống có thể giảm mức ưu tiên của tất cả các tác vụ nền của ứng dụng.
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