BGTaskScheduler คือเฟรมเวิร์กของ Apple สำหรับการกำหนดเวลาและดำเนินการงานพื้นหลังในแอปพลิเคชัน iOS 13 ขึ้นไป มันแทนที่ Background Fetch และ performFetch ที่เลิกใช้งานแล้ว โดยมี API แบบรวมสำหรับการทำงานกับปฏิบัติการพื้นหลัง ตาม Apple Developer Documentation, 2026 เฟรมเวิร์กประกอบด้วยงานสองประเภท: BGProcessingTask สำหรับปฏิบัติการระยะยาว และ BGAppRefreshTask สำหรับการอัปเดตเนื้อหาสั้นๆ
ประเด็นสำคัญ
BGTaskScheduler คือเฟรมเวิร์กระบบของ Apple ที่เปิดตัวใน iOS 13 ซึ่งจัดการการดำเนินการงานพื้นหลังแบบรวมศูนย์ ก่อนที่จะมีการเปิดตัว นักพัฒนาใช้ UIApplication backgroundTasks, performFetch และการจัดการเหตุการณ์ใน appDelegate ซึ่งนำไปสู่การกระจัดกระจายของโค้ดและพฤติกรรมที่คาดเดาไม่ได้
เฟรมเวิร์กทำงานบนหลักการกำหนดเวลาแบบเลื่อนออกไป: แอปพลิเคชันลงทะเบียนงานด้วยตัวระบุที่ไม่ซ้ำกัน และ iOS เองจะกำหนดช่วงเวลาที่เหมาะสมที่สุดในการดำเนินการ ระบบพิจารณาระดับแบตเตอรี่ กิจกรรมของผู้ใช้ สถานะเครือข่าย และปัจจัยอื่นๆ
ความสามารถหลัก รวมถึงการทำงานกับทั้งปฏิบัติการพื้นหลังระยะสั้นและระยะยาว แตกต่างจาก AlarmManager ใน Android BGTaskScheduler ไม่รับประกันเวลาดำเนินการที่แน่นอน — ระบบขอสงวนสิทธิ์ในการเลื่อนงานหากเงื่อนไขไม่เอื้ออำนวย
BGTaskScheduler ใช้สถาปัตยกรรมที่ใช้ตัวจัดการ (handler) แอปพลิเคชันลงทะเบียนตัวจัดการสำหรับงานแต่ละประเภท และระบบจะเรียกมันเมื่อถึงเวลาที่เหมาะสม เฟรมเวิร์กไม่ได้ดำเนินการงานโดยตรง — มันเพียงแจ้งให้แอปพลิเคชันทราบว่าถึงเวลาที่ต้องทำงาน
การลงทะเบียนเริ่มต้นด้วยการประกาศตัวระบุงานใน Info.plist ผ่านอาร์เรย์ BGTaskSchedulerPermittedIdentifiers จากนั้นในโค้ดแอปพลิเคชัน เมธอด registerHandler(forTaskWithIdentifier:) จะถูกเรียกด้วยคลosures ตัวจัดการ
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// ถูกเรียกเมื่อสิ้นสุดโดยบังคับ
}
processBackgroundTask(task as! BGAppRefreshTask)
}
หลังจากการลงทะเบียน แอปพลิเคชันต้องขอการดำเนินการงานอย่างชัดเจนผ่าน submitTaskRequest คำขอประกอบด้วยตัวระบุงานและวันที่เริ่มต้นที่เป็นไปได้เร็วที่สุด ระบบบันทึกคำขอและประมวลผลเมื่อเห็นว่าเงื่อนไขเหมาะสม
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("ข้อผิดพลาดการกำหนดเวลา: \(error)")
}
BGTaskScheduler มีงานหลักสองประเภท แต่ละประเภทออกแบบมาสำหรับกรณีการใช้งานของตนเอง การเลือกประเภทที่ถูกต้องส่งผลโดยตรงต่อความน่าจะเป็นที่ระบบจะดำเนินการงานสำเร็จ
BGAppRefreshTask ออกแบบมาสำหรับการอัปเดตเนื้อหาพื้นหลังสั้นๆ: โหลดข้อมูลใหม่ ซิงค์กับเซิร์ฟเวอร์ อัปเดตวิดเจ็ต เวลาดำเนินการจำกัดที่ 30 วินาที หลังจากนั้นระบบจะบังคับสิ้นสุดงาน งานประเภทนี้ทำงานบ่อยกว่า BGProcessingTask และมีลำดับความสำคัญสูงกว่า
BGProcessingTask ออกแบบมาสำหรับปฏิบัติการที่ยาวนานกว่า: ประมวลผลไฟล์มีเดีย จัดทำดัชนี Core Data สร้างสำรองข้อมูล งานสามารถทำงานได้นานหลายนาที แต่ระบบจะเริ่มงานน้อยครั้งและเฉพาะในเงื่อนไขที่เอื้ออำนวย — เชื่อมต่อกับไฟเลี้ยง, Wi-Fi ที่เสถียร และโหลดอุปกรณ์ต่ำ
| พารามิเตอร์ | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| ขีดจำกัดเวลา | 30 วินาที | หลายนาที |
| ความถี่ในการเริ่ม | สูง | ต่ำ |
| เงื่อนไข | ใดๆ | ไฟเลี้ยง + Wi-Fi |
| ต้องการไฟเลี้ยง | ไม่ | แนะนำ |
| ตัวอย่าง | อัปเดตฟีด | ประมวลผลวิดีโอ |
การลงทะเบียนที่ถูกต้อง เป็นเงื่อนไขบังคับสำหรับการทำงานของ BGTaskScheduler หากงานไม่ได้ลงทะเบียนใน Info.plist ระบบจะไม่สนใจคำขอให้ดำเนินการ
ไฟล์ Info.plist ต้องมีอาร์เรย์ BGTaskSchedulerPermittedIdentifiers พร้อมรายการตัวระบุสตริง ตัวระบุแต่ละตัวต้องไม่ซ้ำกันภายในแอปพลิเคชัน Apple แนะนำให้ใช้สัญกรณ์โดเมนย้อนกลับ
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
ในการกำหนดเวลางาน ให้ใช้เมธอด submitTaskRequest หากไม่ต้องการงานอีกต่อไป สามารถยกเลิกผ่าน cancelTaskRequest หรือ cancelAllTaskRequests ระบบจะยกเลิกงานโดยอัตโนมัติเมื่อลบแอปพลิเคชันหรือรีเซ็ตข้อมูล
BGTaskScheduler มีความสามารถในการติดตามสถานะของงานที่กำหนดเวลาผ่าน getPendingTaskRequests เมธอดนี้ส่งคืนรายการคำขอที่ใช้งานอยู่ทั้งหมดพร้อมข้อมูลเกี่ยวกับประเภท ตัวระบุ และ earliestBeginDate สำหรับแต่ละคำขอ คุณสามารถตรวจสอบว่าได้ดำเนินการเสร็จสิ้นหรือถูกยกเลิกแล้ว และตัดสินใจกำหนดเวลาใหม่
สิ่งสำคัญที่ต้องทราบคือระบบไม่ได้ให้การเรียกกลับโดยตรงเกี่ยวกับความสำเร็จของงานพื้นหลัง — ตัวจัดการต้องรายงานผลลัพธ์ผ่านคุณสมบัติของงาน setTaskCompleted อนุญาตให้ทำเครื่องหมายงานว่าเสร็จสมบูรณ์ หลังจากนั้นระบบสามารถเริ่มงานที่กำหนดเวลาถัดไปของประเภทนี้ หากงานไม่เรียก setTaskCompleted ระบบจะถือว่าเสร็จสมบูรณ์เมื่อหมดเวลาหรือถูกบังคับสิ้นสุด
สำหรับการวินิจฉัย แนะนำให้ใช้ OSLog ในตัวจัดการและดูบันทึกผ่าน Console.app บน Mac Apple ยังมีเครื่องมือ MetricKit สำหรับวิเคราะห์ประสิทธิภาพงานพื้นหลัง — มันรวบรวมข้อมูลเกี่ยวกับเวลาดำเนินการ การใช้พลังงาน และความถี่ในการเริ่มที่สามารถใช้สำหรับการปรับให้เหมาะสม
// ยกเลิกงานเฉพาะ
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// ยกเลิกงานทั้งหมด
BGTaskScheduler.shared.cancelAllTaskRequests()
// ตรวจสอบงานที่กำหนดเวลา
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("กำหนดเวลา \(requests.count) งานแล้ว")
}
BGTaskScheduler กำหนดข้อจำกัดที่เข้มงวดเกี่ยวกับงานพื้นหลัง ระบบอาจเลื่อนงานออกไปอย่างไม่มีกำหนดหากเงื่อนไขไม่เอื้ออำนวย นักพัฒนาต้องเข้าใจว่าเฟรมเวิร์กไม่ได้ออกแบบมาสำหรับงานแบบเรียลไทม์
ข้อจำกัดหลักรวมถึง: ระบบไม่รับประกันการดำเนินการงานตามเวลาที่กำหนด จำนวนงานพร้อมกันสูงสุดถูกจำกัด และ การใช้พลังงาน ถูกควบคุมอย่างเข้มงวด การเรียกใช้งานหลายรายการติดต่อกันอาจส่งผลให้งานถูกรวมหรือถูกยกเลิก
เพื่อเพิ่มความน่าจะเป็นในการดำเนินการ แนะนำให้ตั้งค่า earliestBeginDate ไม่เร็วกว่า 1 ชั่วโมง สำหรับ BGProcessingTask และ 15 นาทีสำหรับ BGAppRefreshTask การจัดการ expirationHandler ก็สำคัญเช่นกัน — หากงานไม่สามารถทำตามขีดจำกัดเวลาได้ ระบบจะเรียกตัวจัดการนี้เพื่อการสิ้นสุดที่เหมาะสม การกำหนดเวลาใหม่ควรทำภายในตัวจัดการเองเพื่อรักษาวงจรการทำงานพื้นหลังอย่างต่อเนื่อง
ข้อจำกัดสำคัญอีกประการเกี่ยวข้องกับ คำขอเครือข่าย BGTaskScheduler ไม่รับประกันการเชื่อมต่อเครือข่ายที่ทำงานอยู่ในระหว่างการดำเนินการงาน แอปพลิเคชันต้องตรวจสอบความพร้อมใช้งานของเครือข่ายโดยอิสระผ่าน NWPathMonitor และเลื่อนการประมวลผลหากไม่มีการเชื่อมต่อ ซึ่งแตกต่างจาก Android JobScheduler ที่สามารถเปิดใช้งานงานเฉพาะเมื่อเชื่อมต่อกับเครือข่ายประเภทใดประเภทหนึ่ง ในทางปฏิบัติ นักพัฒนามักรวม BGTaskScheduler เข้ากับเซสชัน URL พื้นหลังของ NSURLSession สำหรับการโหลดข้อมูลที่เชื่อถือได้
เริ่มจาก macOS Catalina BGTaskScheduler ยังใช้งานได้บน Mac ซึ่งช่วยให้สามารถสร้างงานพื้นหลังข้ามแพลตฟอร์มสำหรับแอปพลิเคชัน UIKit ที่ทำงานบน Apple Silicon บน watchOS เฟรมเวิร์กมีฟังก์ชันการทำงานจำกัด — มีเฉพาะ BGAppRefreshTask สั้นๆ สำหรับอัปเดตคอมพลิเคชันและซิงค์ข้อมูลกับ iPhone นักพัฒนาควรคำนึงถึงความแตกต่างของแพลตฟอร์มเมื่อวางแผนสถาปัตยกรรมพื้นหลัง
Apple มีเครื่องมือหลายอย่างสำหรับการดีบัก BGTaskScheduler คำสั่ง e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] ใน lldb จะบังคับเริ่มงานพื้นหลัง โดยข้ามข้อจำกัดของระบบ Xcode มีแฟล็ก Simulate Background Fetch ในเมนู Debug ที่จำลองการอัปเดตพื้นหลังสั้นๆ MetricKit ใช้สำหรับการวิเคราะห์ประสิทธิภาพ — มันรวบรวมข้อมูลเกี่ยวกับความถี่ในการเริ่ม ระยะเวลาดำเนินการ และการใช้พลังงานของแต่ละงาน ข้อมูลนี้ช่วยปรับความถี่ในการกำหนดเวลาให้เหมาะสมและเลือกประเภทงานที่ถูกต้อง
ในทางปฏิบัติ BGTaskScheduler เหมาะสำหรับการอัปเดตข้อมูลวิดเจ็ต การซิงค์ iCloud การประมวลผลการแจ้งเตือนแบบพุชที่มีเนื้อหา และการจัดทำดัชนีสำหรับการค้นหา Spotlight ไม่เหมาะสำหรับการวิเคราะห์แบบเรียลไทม์ แอปพลิเคชันแชท หรืองานใดๆ ที่ต้องการการดำเนินการทันที
สำหรับการศึกษาเชิงลึกเกี่ยวกับ BGTaskScheduler Apple แนะนำเอกสารประกอบ WWDC อย่างเป็นทางการ: เซสชัน "Advances in Background Tasks" (2020) ครอบคลุมการย้ายจาก API ที่เลิกใช้งานแล้ว และ "Background Tasks in Practice" (2021) มีกรณีการใช้งานจริง ส่วน Energy Efficiency Guide ก็มีประโยชน์ โดยอธิบายว่าเฟรมเวิร์กเข้ากับกลยุทธ์การประหยัดพลังงานโดยรวมของ Apple อย่างไร ตัวอย่างโค้ดพร้อมใช้งานในที่เก็บ Apple Developer อย่างเป็นทางการบน GitHub พร้อมโปรเจกต์ที่สมบูรณ์สำหรับ iOS และ macOS
คำถามที่พบบ่อย
Background Fetch ถูกจำกัดให้มีงานพื้นหลังหนึ่งงานต่อแอปพลิเคชันและไม่มีกลไกลำดับความสำคัญ BGTaskScheduler รองรับหลายงานด้วยประเภทที่แตกต่างกัน มี API แบบรวม และการจัดการพลังงานอัตโนมัติ
Apple ไม่ได้กำหนดขีดจำกัดที่ชัดเจนสำหรับจำนวนตัวระบุที่ลงทะเบียน แต่ในทางปฏิบัติแนะนำให้ใช้ไม่เกิน 5–10 งาน จำนวนที่มากขึ้นจะลดความน่าจะเป็นที่แต่ละงานเฉพาะจะถูกดำเนินการเนื่องจากการแข่งขันเพื่อทรัพยากรระบบ
สำหรับการดีบัก ให้ใช้คำสั่ง e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] ใน lldb มันจะบังคับเริ่มงานโดยข้ามข้อจำกัดของระบบ แฟล็ก Xcode Simulate Background Fetch ในเมนู Debug ก็สามารถใช้ได้
ได้ BGTaskScheduler สามารถเริ่มกระบวนการได้แม้ว่าแอปพลิเคชันจะถูกปิดบังคับโดยผู้ใช้ อย่างไรก็ตาม ระบบอาจใช้ความล่าช้าเพิ่มเติม และงานบางประเภทไม่รับประกันการดำเนินการในสถานการณ์นี้
ระบบเรียก expirationHandler ส่งสัญญาณให้งานทราบว่าต้องสิ้นสุด หากแอปพลิเคชันไม่สนใจสัญญาณนี้และทำงานต่อไป iOS จะบังคับสิ้นสุดกระบวนการ หลังจากนั้น ระบบอาจลดลำดับความสำคัญของงานพื้นหลังทั้งหมดของแอปพลิเคชัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม