Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Cách chạy timer trong background trên iOS

Nếu muốn chạy timer khi app ở background, Apple cung cấp beginBackgroundTask(withExpirationHandler:). Tuy nhiên, thời gian tối đa chỉ khoảng 30 giây đến 3 phút (tùy iOS version và trạng thái thiết bị).

Tài liệu Apple chính thức

Ví dụ: In log mỗi giây khi app vào background

Bước 1: Tạo dự án

Xcode → Single View App → Tên: "BackgroundTimer".

Bước 2: Code trong AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    var backgroundTaskIdentifier: UIBackgroundTaskIdentifier?
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        // 1. Đăng ký background task
        backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            // Handler khi hết thời gian background
            UIApplication.shared.endBackgroundTask(self.backgroundTaskIdentifier!)
            self.backgroundTaskIdentifier = .invalid
        })
        
        // 2. Tạo timer lặp lại mỗi 1 giây
        Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(doSomething), userInfo: nil, repeats: true)
    }
    
    @objc func doSomething() {
        print("Đang chạy background: \(Date())")
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        // Kết thúc background task khi app quay lại foreground
        if let taskId = backgroundTaskIdentifier, taskId != .invalid {
            UIApplication.shared.endBackgroundTask(taskId)
            backgroundTaskIdentifier = .invalid
        }
    }
}

Giải thích quan trọng

Khía cạnh Chi tiết
Thời gian tối đa ~30 giây - 3 phút (iOS quyết định, không kiểm soát được)
expirationHandler Bắt buộc phải gọi endBackgroundTask ở đây, không thì app bị kill
Timer Chỉ chạy được trong thời gian background task được cấp
Foreground Timer tiếp tục chạy bình thường khi app active

Các trường hợp dùng background task hợp lệ

  • Hoàn tất upload/download file lớn
  • Lưu dữ liệu quan trọng trước khi tắt
  • Xử lý task ngắn (dưới 30s)
  • VoIP, Music playback, Location updates (cần capability đặc biệt)

Không nên dùng cho

  • Chạy timer vô thời hạn
  • Thực hiện network request dài
  • Xử lý logic phức tạp

Alternatives cho background execution dài hơn

  1. Background Fetch: setMinimumBackgroundFetchInterval - iOS tự quyết định khi nào chạy
  2. Background App Refresh: User bật trong Settings
  3. Silent Push Notification: Server push để đánh thức app
  4. Background Processing (iOS 13+): BGProcessingTask cho task nặng, cần điện nguồn + WiFi
  5. Location Updates: Capability "Location updates" trong Background Modes

Test

  1. Chạy app trên thiết bị thật (simulator không chính xác)
  2. Nhấn Home / vuốt lên để đưa app vào background
  3. Xem console Xcode: "Đang chạy background..." in ra mỗi giây
  4. Sau ~30-180 giây: log dừng lại (expirationHandler được gọi)
  5. Mở app lại: timer tiếp tục in log

Cách chạy timer trong background trên iOS

Lưu ý

Kể từ iOS 13, Apple khuyến nghị dùng Background Tasks Framework (BGAppRefreshTask, BGProcessingTask) thay vì beginBackgroundTask cho các tác vụ định kỳ.