Background Fetch là cơ chế iOS định kỳ đánh thức ứng dụng trong nền để tải nội dung mới. Hệ thống phân tích hành vi người dùng và chọn các khung thời gian tối ưu để cập nhật. Theo Apple, 2026, ứng dụng có từ 30 đến 120 giây để thực hiện thao tác, sau đó hệ thống tạm dừng hoặc kết thúc tiến trình.
Những điểm chính
Background Fetch là API iOS cho phép ứng dụng nhận dữ liệu mới định kỳ trong nền. Được giới thiệu lần đầu trong iOS 7 cùng với cơ chế Background App Refresh. Mục tiêu chính là nội dung được cập nhật vào thời điểm người dùng mở ứng dụng, không cần chờ tải.
Thông báo đẩy được khởi tạo bởi máy chủ — máy chủ gửi tín hiệu đến thiết bị và hệ thống quyết định có đánh thức ứng dụng hay không. Background Fetch được iOS tự khởi tạo dựa trên mẫu sử dụng thiết bị. Đẩy phù hợp hơn cho tin nhắn khẩn cấp, còn Fetch phù hợp cho cập nhật nội dung theo lịch (tin tức, nguồn cấp mạng xã hội).
Background Fetch là một trong nhiều cơ chế thực thi nền trong iOS. BGAppRefreshTask (iOS 13+) thực hiện cùng tác vụ nhưng với lập lịch linh hoạt hơn. Background Modes (âm thanh, vị trí) dành cho các thao tác liên tục. Silent Push là cập nhật do máy chủ khởi tạo. Fetch vẫn phù hợp cho các dự án hỗ trợ iOS 12 trở xuống.
iOS sử dụng thuật toán học máy để xác định thời điểm tối ưu đánh thức ứng dụng. Hệ thống phân tích khi nào người dùng thường mở ứng dụng, sử dụng bao lâu và quay lại bao nhiêu lần. Dựa trên dữ liệu này, iOS tính toán các khung thời gian cho Background Fetch.
Khi hệ thống quyết định đánh thức ứng dụng, nó gọi phương thức application(_:performFetchWithCompletionHandler:) trong AppDelegate. Ứng dụng cần tải một lượng dữ liệu mới tối thiểu và gọi trình xử lý hoàn tất với một trong ba trạng thái: .newData (dữ liệu đã tải), .noData (không có dữ liệu mới) hoặc .failed (lỗi). Trạng thái ảnh hưởng đến tần suất đánh thức trong tương lai.
Trạng thái .newData báo cho hệ thống rằng bản cập nhật hữu ích — iOS có thể tăng tần suất đánh thức. .noData cho biết không có dữ liệu — tần suất giữ nguyên hoặc giảm. .failed báo hiệu sự cố — hệ thống giảm tần suất để tiết kiệm pin. Cần nhấn mạnh vào trạng thái trung thực, không ép buộc .newData.
| Trạng thái | Ý nghĩa | Tác động |
|---|---|---|
| .newData | Dữ liệu đã tải thành công | Tần suất có thể tăng |
| .noData | Kiểm tra không có dữ liệu mới | Tần suất giữ nguyên |
| .failed | Lỗi mạng hoặc máy chủ | Tần suất giảm |
Để kích hoạt Background Fetch, cần hai bước: kích hoạt khả năng trong Xcode và đặt khoảng thời gian tối thiểu trong mã. Khả năng này nằm ở Target — Signing & Capabilities — Background Modes — chọn hộp Background Fetch. Nếu không có bước này, hệ thống sẽ không đánh thức ứng dụng.
Phương thức UIApplication.shared.setMinimumBackgroundFetchInterval đặt thời gian tối thiểu tính bằng giây giữa các lần gọi Fetch. Giá trị UIApplication.backgroundFetchIntervalMinimum (khoảng 15 phút) báo hệ thống đánh thức ứng dụng thường xuyên nhất có thể một cách tiết kiệm năng lượng. Đặt khoảng thời gian trong application(_:didFinishLaunchingWithOptions:) là thông lệ chuẩn.
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
return true
}
Khi kích hoạt Background Fetch trong Xcode, nó tự động cập nhật Info.plist — thêm khóa UIBackgroundModes với giá trị fetch. Đây là bước bắt buộc: nếu không có, ứng dụng sẽ không nhận được lời gọi performFetchWithCompletionHandler. Bạn có thể kiểm tra qua P list Source hoặc Build Settings.
Hãy xem triển khai Background Fetch hoàn chỉnh cho ứng dụng tin tức. Triển khai bao gồm tải dữ liệu, lưu đệm và gọi trình xử lý hoàn tất. Mã thực thi trong AppDelegate — nơi duy nhất hệ thống gọi fetch.
func application(
_ application: UIApplication,
performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
let url = URL(string: "https://api.example.com/latest")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
handler(.failed)
return
}
do {
let articles = try JSONDecoder().decode([Article].self, from: data)
cacheArticles(articles)
handler(articles.isEmpty ? .noData : .newData)
} catch {
handler(.failed)
}
}.resume()
}
Sau khi tải dữ liệu qua Background Fetch, cần lưu vào bộ nhớ cục bộ — CoreData, UserDefaults hoặc File Manager. Khi ứng dụng mở, dữ liệu đã sẵn sàng. Sử dụng CoreData với ngữ cảnh nền để ghi an toàn luồng. Sau khi lưu, cập nhật giao diện người dùng trên luồng chính.
func cacheArticles(_ articles: [Article]) {
let container = NSPersistentContainer(name: "AppModel")
container.performBackgroundTask { context in
articles.forEach { article in
let entity = ArticleEntity(context: context)
entity.id = Int64(article.id)
entity.title = article.title
entity.body = article.body
}
try? context.save()
}
}
Để kiểm tra, sử dụng Trình mô phỏng — chọn Debug — Simulate Background Fetch trong Xcode. Trên thiết bị thật, bạn cần đợi hệ thống quyết định thực hiện fetch. Để tăng tốc, bạn có thể đặt khoảng thời gian tối thiểu là 1 phút, nhưng hệ thống có thể bỏ qua khi pin yếu.
Background Fetch có một số giới hạn quan trọng cần xem xét khi thiết kế kiến trúc ứng dụng. Quan trọng nhất là hệ thống kiểm soát hoàn toàn tần suất gọi và nhà phát triển không thể đảm bảo nó. Ngay cả khi đã đặt khoảng thời gian tối thiểu, hệ thống có thể không gọi fetch trong nhiều giờ.
Hệ thống cấp thời gian hạn chế cho ứng dụng thực thi tác vụ — thường tối đa 30 giây. Nếu ứng dụng không gọi trình xử lý hoàn tất trong thời gian đó, hệ thống buộc kết thúc tiến trình và giảm tần suất đánh thức trong tương lai. Tất cả yêu cầu mạng phải nhỏ gọn — không quá 1-2 mỗi lần gọi.
iOS xem xét mức pin khi lập lịch Background Fetch. Khi sạc dưới 20%, tần suất đánh thức giảm. Khi Chế độ nguồn điện thấp được kích hoạt, hệ thống có thể tắt hoàn toàn cập nhật nền cho tất cả ứng dụng. Người dùng cũng có thể tắt Background App Refresh cho ứng dụng cụ thể trong cài đặt.
URLSession khởi tạo từ Background Fetch hoạt động ở chế độ tiêu chuẩn — không hỗ trợ phiên nền. Để tải xuống lớn, sử dụng URLSession với cấu hình nền. Hệ thống sẽ tiếp tục tải xuống ngay cả sau khi fetch kết thúc, nhưng tiến trình sẽ không được theo dõi cho đến lần đánh thức tiếp theo.
Từ iOS 13, Apple khuyến nghị BGTaskScheduler thay thế cho Background Fetch. BGTaskScheduler cung cấp lập lịch linh hoạt hơn, hai loại tác vụ (refresh và processing) và đăng ký tác vụ với định danh. Việc di chuyển bao gồm nhiều bước và được khuyến nghị cho tất cả dự án mới.
Bước đầu tiên — xác định định danh tác vụ trong Info.plist qua khóa BGTaskSchedulerPermittedIdentifiers. Bước hai — đăng ký tác vụ trong AppDelegate qua BGTaskScheduler.shared.register. Bước ba — thay thế lời gọi performFetchWithCompletionHandler bằng trình xử lý được truyền cho register. Bước bốn — gọi submit để lập lịch tác vụ.
// Trước đây (Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
// Sau khi di chuyển (BGTaskScheduler)
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
let request = BGAppRefreshTaskRequest(
identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
BGTaskScheduler cung cấp nhiều kiểm soát hơn: BGProcessingTask cho thao tác dài (tối đa 10 phút), điều kiện thực thi qua requiresNetworkConnectivity và requiresExternalPower, và trình xử lý hết hạn để kết thúc có kiểm soát. Hệ thống cũng phân tích mức sử dụng ứng dụng, nhưng nhà phát triển có thể đặt yêu cầu chính xác hơn.
Nếu ứng dụng hỗ trợ iOS 12 trở xuống, Background Fetch vẫn là lựa chọn duy nhất cho cập nhật định kỳ. BGTaskScheduler chỉ khả dụng từ iOS 13+. Trong trường hợp này, sử dụng lớp bọc: kiểm tra khả dụng qua if #available(iOS 13, *) và gọi API tương ứng.
Câu hỏi thường gặp
Tần suất chính xác không được ghi chép và phụ thuộc vào hành vi người dùng. Hệ thống phân tích tần suất người dùng mở ứng dụng và điều chỉnh tần suất tương ứng. Trung bình, với sử dụng tích cực, fetch có thể được gọi 1–3 lần mỗi giờ. Với sử dụng không thường xuyên — 1–2 lần mỗi ngày.
Kiểm tra ba điều kiện: khả năng Background Fetch được kích hoạt trong Xcode, minimumBackgroundFetchInterval đã được đặt và người dùng chưa tắt Background App Refresh cho ứng dụng trong cài đặt. Cũng kiểm tra thiết bị không ở Chế độ nguồn điện thấp và mức pin trên 20%.
Background Fetch là API cũ (iOS 7), BGAppRefreshTask là API mới (iOS 13+). BGAppRefreshTask cung cấp nhiều kiểm soát hơn: trình xử lý hết hạn, khả năng lập lịch lại và kiểm tra trạng thái. Background Fetch đơn giản hơn để triển khai nhưng kém linh hoạt. Apple khuyến nghị sử dụng BGAppRefreshTask cho dự án mới.
Không khuyến nghị. Background Fetch bị giới hạn thời gian (tối đa 30 giây). Để tải xuống lớn, sử dụng URLSession với cấu hình nền — hệ thống sẽ tiếp tục tải xuống ngay cả sau khi fetch kết thúc. Thay thế là BGProcessingTask (iOS 13+), cho phép tối đa 10 phút và điều kiện sạc.
Có, mỗi lần đánh thức tiêu thụ năng lượng để bật bộ xử lý, khởi tạo ngăn xếp mạng và tải dữ liệu. iOS tối ưu hóa tần suất để giảm thiểu tác động. Với triển khai đúng — chỉ tải dữ liệu mới, gọi trình xử lý hoàn tất nhanh — tác động đến pin là tối thiể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