Background Task: 핵심 개념, 작업 등록 및 백그라운드 실행

저자: IT Sectr 게시일: 2026-03-27 읽는 시간: 10 분

Background Task는 애플리케이션이 백그라운드로 전환된 후 작업을 완료할 수 있도록 하는 iOS 메커니즘입니다. 시스템은 작업 실행을 위해 제한된 시간(최대 30초)을 할당하며, 이후 애플리케이션은 강제로 일시 중단됩니다. Apple, 2026에 따르면, 만료 핸들러 사용은 백그라운드 작업을 올바르게 완료하기 위한 필수 요구 사항입니다.

핵심 요점

  • Background Task — 앱이 백그라운드로 전환된 후 작업을 완료하기 위한 iOS 메커니즘.
  • beginBackgroundTask — 백그라운드 작업을 등록하는 UIApplication의 주요 메서드.
  • Expiration handler — 할당된 시간이 만료되면 시스템이 호출하는 코드 블록.
  • 30초 제한 — 표준 실행 시간, Background Modes를 통해 연장 가능.
  • UIApplication.shared.endBackgroundTask — 작업을 올바르게 완료하기 위한 필수 호출.

iOS에서 Background Task란?

Background Task는 애플리케이션이 백그라운드로 전환된 후 실행 시간을 연장할 수 있도록 하는 프로그래밍 가능한 iOS 메커니즘입니다. 사용자가 앱을 최소화하면 시스템이 UIApplicationDelegate.applicationDidEnterBackground를 호출합니다. 그 순간 중요한 작업(데이터 저장, 요청 전송)이 실행 중인 경우, 애플리케이션은 beginBackgroundTask를 통해 추가 시간을 요청할 수 있습니다.

Background Tasks가 필요한 이유

Background Task를 사용하지 않으면, 애플리케이션은 백그라운드 전환 후 3~5초 이내에 강제로 일시 중단됩니다. 완료되지 않은 모든 작업이 중단됩니다: 데이터가 저장되지 않고, 네트워크 요청이 중단되며, 상태가 손실됩니다. Background Task는 이러한 작업을 올바르게 완료할 수 있도록 최대 30초의 시간을 제공합니다.

  • 상태 저장 — CoreData, UserDefaults 또는 파일 시스템에 데이터 쓰기.
  • 네트워크 요청 완료 — 서버 응답 대기 및 결과 처리.
  • 분석 데이터 전송 — 일시 중단 전에 분석 서버로 이벤트 전송.
  • 리소스 정리 — 파일 디스크립터 닫기, 메모리 해제.
  • 캐싱 — 다음 실행 시 복원을 위한 중간 결과 저장.

역사와 발전

beginBackgroundTask는 멀티태스킹을 지원하는 첫 번째 릴리스인 iOS 4.0에서 등장했습니다. iOS 4 이전에는 홈 버튼을 누르면 애플리케이션이 완전히 종료되었습니다. iOS 7에서는 Background Fetch와 URLSession 백그라운드 구성이 도입되었습니다. iOS 13부터 Apple은 새 프로젝트에 BGTaskScheduler를 권장하지만, beginBackgroundTask는 단기 작업에 계속 유용합니다.

beginBackgroundTask 작동 방식: 생명주기

beginBackgroundTask는 작업을 등록하고 고유한 UIBackgroundTaskIdentifier를 반환하는 UIApplication 메서드입니다. 시스템이 백그라운드 실행 타이머를 증가시킵니다. 시간이 만료되면 expiration handler가 호출되고, 이후 애플리케이션은 작업을 올바르게 완료하기 위해 endBackgroundTask(identifier:)를 호출해야 합니다.

단계별 실행 프로세스

1단계 — 애플리케이션이 didEnterBackground 알림을 받습니다. 2단계 — beginBackgroundTask(expirationHandler:)가 호출됩니다. 3단계 — 중요한 작업(저장, 네트워크 요청)이 실행됩니다. 4단계 — 완료 시 endBackgroundTask(identifier:)가 호출됩니다. 30초 내에 작업이 완료되지 않으면 시스템이 expiration handler를 호출하고, 애플리케이션은 즉시 작업을 종료해야 합니다.

swift
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

func startBackgroundTask() {
    backgroundTaskID = UIApplication.shared.beginBackgroundTask {
        // Expiration handler
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }
}

func finishBackgroundTask() {
    UIApplication.shared.endBackgroundTask(backgroundTaskID)
    backgroundTaskID = .invalid
}

UIApplication.shared.backgroundTimeRemaining

backgroundTimeRemaining 속성은 백그라운드 작업이 강제로 종료되기까지 남은 초 수를 반환합니다. 값은 실시간으로 감소합니다. 애플리케이션이 백그라운드에 없으면 DBL_MAX를 반환합니다. 이 속성을 사용하여 동작을 조정하세요: 5초 미만 남았을 때 장기 실행 작업을 중단하고 진행 상황을 저장합니다.

다중 작업

애플리케이션은 여러 Background Tasks를 동시에 등록할 수 있습니다. 각 작업은 고유한 식별자를 받습니다. 총 실행 시간은 누적됩니다 — 3개의 작업이 등록된 경우, 애플리케이션은 최대 90초까지 얻을 수 있습니다. 그러나 리소스가 고갈되거나 배터리 제한을 초과하면 시스템이 애플리케이션을 조기에 종료할 수 있습니다.

Expiration handler: 필수 완료 처리

Expiration handler는 백그라운드 작업에 할당된 시간이 만료될 때 시스템이 호출하는 코드 블록입니다. expiration handler를 보유하는 것은 Apple의 필수 요구 사항입니다. 이것이 없으면 애플리케이션이 시스템에 의해 강제로 종료되고 데이터가 손실될 수 있습니다.

Expiration handler에 포함해야 할 사항

expiration handler는 애플리케이션 상태를 저장하기 위한 최소한의 작업을 수행해야 합니다: 현재 데이터를 영구 저장소에 저장하고, 해당 식별자로 endBackgroundTask를 호출하며, 식별자를 .invalid로 설정합니다. expiration handler 내에서 새로운 장기 실행 작업을 시작하는 것은 금지됩니다 — 실행 시간이 1~2초로 제한됩니다.

swift
func handleExpiration() {
    // 실행 진행 상황 저장 중
    saveProgressToUserDefaults()

    // 활성 네트워크 요청 취소 중
    currentTask?.cancel()

    // Background Task 종료 중
    UIApplication.shared.endBackgroundTask(backgroundTaskID)
    backgroundTaskID = .invalid
}

// Expiration handler로 등록
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
    withName: "SaveDocument",
    expirationHandler: handleExpiration
)

Expiration handler의 일반적인 오류

가장 흔한 실수는 expiration handler 내에서 endBackgroundTask를 호출하지 않는 것입니다. 이 경우 시스템은 작업을 계속 활성 상태로 간주하고, 애플리케이션은 일시 중단 상태로 전환되지 않으며, 배터리가 소모됩니다. 두 번째 실수는 expiration handler 내에서 장기 실행 작업을 시작하는 것입니다. 시스템이 완료되기 전에 애플리케이션을 종료할 수 있으며, 데이터가 손실됩니다.

남은 시간 확인

expiration handler에서 실행 시간은 매우 제한적입니다 — 일반적으로 1초 미만. 따라서 handler 내에서는 다음을 수행할 수 없습니다: 복잡한 계산, 네트워크 요청, CoreData에 대량 데이터 쓰기. 원자적 작업만 가능: UserDefaults에 단일 키 쓰기, 상태 플래그 설정, endBackgroundTask 호출.

Swift의 Background Task 코드 예제

앱이 백그라운드로 전환될 때 문서를 저장하기 위한 완전한 Background Task 구현을 살펴보겠습니다. 예제에는 작업 등록, 남은 시간 확인을 통한 작업 실행, endBackgroundTask를 통한 올바른 완료가 포함됩니다.

진행 상황 표시와 문서 저장

백그라운드로 전환될 때, 애플리케이션은 큰 문서의 저장을 시작합니다. Background Task는 작업에 최대 30초를 제공합니다. 시간이 만료되면 expiration handler가 중간 결과를 저장합니다. 저장이 완료된 후, 리소스를 해제하기 위해 endBackgroundTask가 호출됩니다.

swift
class DocumentManager {
    private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    func saveDocumentInBackground(document: Document) {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask {
            self.saveProgress(document)
            self.endBackgroundTask()
        }

        DispatchQueue.global().async {
            document.save()
            self.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }
}

서버로 데이터 전송

백그라운드에서의 네트워크 요청은 특별한 주의가 필요합니다 — expiration handler가 응답을 받기 전에 요청을 중단할 수 있습니다. dataTask와 함께 URLSession을 사용하고 전송 전에 backgroundTimeRemaining을 확인하세요. 5초 미만 남은 경우, 다음 앱 실행까지 전송을 연기하세요.

swift
func sendCriticalData(data: Data) {
    backgroundTaskID = UIApplication.shared.beginBackgroundTask {
        // 재전송을 위한 데이터 저장 중
        saveForRetry(data)
        self.endBackgroundTask()
    }

    let task = URLSession.shared.dataTask(with: request) { _, _, error in
        if error != nil {
            saveForRetry(data)
        }
        self.endBackgroundTask()
    }
    task.resume()
}

남은 시간 모니터링

장기 실행 작업의 경우 UIApplication.shared.backgroundTimeRemaining을 모니터링하세요. 값이 임계값(10초) 아래로 떨어지면 현재 작업을 중단하고 중간 결과 저장을 시작하세요. 이렇게 하면 expiration handler가 강제로 호출되기 전에 올바르게 완료할 수 있습니다.

Background Task 사용 모범 사례

Background Task는 강력한 메커니즘이지만, 부적절하게 사용하면 배터리 및 성능 문제가 발생합니다. Apple의 권장 사항과 커뮤니티에서 검증된 방법을 따르면 일반적인 실수를 피하고 안정적인 애플리케이션 운영을 보장할 수 있습니다.

실행 시간 최소화

Background Task를 가능한 한 빨리 완료하세요. 백그라운드 실행의 1초마다 배터리를 소모합니다. 최적 시간 — 5초 미만. 작업 시간이 더 오래 걸리면 BGTaskScheduler 또는 Background Modes 사용을 고려하세요. 실제 필요 없이 beginBackgroundTask 호출로 인위적으로 작업을 연장하지 마세요.

식별자의 올바른 사용

UIBackgroundTaskIdentifier를 클래스 또는 구조체 속성으로 저장하세요. 전역 변수로 전달하지 마세요 — 여러 작업에서 충돌이 발생합니다. 이중 완료를 방지하기 위해 endBackgroundTask 호출 후 식별자를 .invalid로 설정하세요.

Background Task 테스트

Xcode 시뮬레이터에서 홈 버튼(Command + Shift + H)을 통해 앱을 백그라운드로 전환하세요. Debug — Simulate Background Fetch를 사용하여 백그라운드 실행을 테스트하세요. 시간 만료를 시뮬레이션하려면 환경 변수 BACKGROUND_TASK_SIMULATE_EXPIRATION = YES를 설정하세요 — expiration handler가 5초 이내에 호출됩니다.

swift
// 작업 시작 전 남은 시간 확인
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
    // 시간 부족 — 작업 연기
    scheduleForNextLaunch()
    return
}

// 시간 제어로 작업 실행
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
    saveProgress()
    self.endBackgroundTask()
}

Retain cycle 방지

expiration handler는 self를 캡처합니다 — backgroundTaskID가 동일한 객체의 속성으로 저장된 경우 retain cycle이 발생할 수 있습니다. 클로저에서 [weak self]를 사용하거나 식별자를 별도로 저장하세요. Retain cycle은 메모리 누수를 일으켜 애플리케이션이 종료될 때까지 객체가 해제되지 않습니다.

Background Task vs BGTaskScheduler: 접근 방식 비교

iOS 13 출시와 함께 Apple은 BGTaskScheduler를 도입했습니다 — 기존 Background Task API의 현대적인 대체품입니다. 두 메커니즘 모두 유사한 작업을 해결하지만, BGTaskScheduler는 더 많은 제어와 유연성을 제공합니다. 차이점을 이해하면 특정 시나리오에 적합한 도구를 선택하는 데 도움이 됩니다.

특성Background TaskBGTaskScheduler
iOS 버전4.0+13.0+
최대 시간30초30초 / 10분 (processing)
시작didEnterBackground스케줄링 + 시스템
실행 보장백그라운드 전환 시에만시스템이 편리한 모든 시간
Expiration handler예, 필수예, task.expirationHandler를 통해
인터넷시작 시 필요requiresNetworkConnectivity를 통해 사용 가능
충전필요 없음processing에서 선택 사항

Background Task를 사용해야 하는 경우

beginBackgroundTask는 백그라운드 전환 시 즉시 실행해야 하는 단기 작업에 적합합니다: 상태 저장, 네트워크 요청 완료, 데이터 캐싱. API가 간단하고 Info.plist 구성이나 식별자 등록이 필요하지 않습니다. 10초 미만이 소요되는 작업에 이상적입니다.

BGTaskScheduler를 사용해야 하는 경우

BGTaskScheduler는 편리한 시간에 실행할 수 있는 작업에 적합합니다: 주기적 동기화, 캐시 정리, 위젯 업데이트. 시스템 자체가 사용자 행동과 배터리 상태를 고려하여 최적의 시간을 선택합니다. 장기 실행 작업(최대 10분)에는 BGProcessingTask를 사용하세요.

병행 사용

두 API를 동일한 애플리케이션에서 사용할 수 있습니다. Background Task — 백그라운드 전환 시 즉시 작업(초안 저장)에 사용합니다. BGTaskScheduler — 예약된 업데이트(6시간마다 동기화)에 사용합니다. 책임 분리를 통해 데이터의 올바른 보존과 에너지 효율적인 백그라운드 유지보수를 보장합니다.

자주 묻는 질문

didEnterBackground 외부에서 beginBackgroundTask를 호출할 수 있나요?

네, beginBackgroundTask는 애플리케이션 실행 중 언제든지 호출할 수 있습니다. 그러나 시스템 시간 할당은 백그라운드로 전환된 후에만 시작됩니다. 애플리케이션이 포그라운드에 있는 경우 beginBackgroundTask를 호출해도 효과가 없습니다 — backgroundTimeRemaining이 DBL_MAX를 반환하고, 작업은 백그라운드로 전환될 때 활성화됩니다.

endBackgroundTask를 호출하지 않으면 어떻게 되나요?

endBackgroundTask가 호출되지 않으면 시스템은 애플리케이션을 백그라운드에서 활성 상태로 계속 간주합니다. 30초 후에 expiration handler가 호출되지만, 여기에도 endBackgroundTask가 없으면 애플리케이션이 메모리에 남아 배터리를 소모합니다. iOS 13+에서는 시스템이 3분 후에 해당 애플리케이션을 강제 종료합니다.

Background Task를 30초 이상 연장하려면?

표준 시간은 30초입니다. Background Modes: 오디오(재생), 위치(GPS), 블루투스(BLE)를 통해서만 연장할 수 있습니다. 또는 BGProcessingTask(iOS 13+)를 통해 충전 및 Wi-Fi 환경에서 최대 10분까지 가능합니다. beginBackgroundTask 자체는 제한을 늘리는 방법을 제공하지 않습니다.

Background Task가 iPad에서 작동하나요?

네, iPadOS는 iOS와 동일한 제한 사항으로 beginBackgroundTask를 완전히 지원합니다. Stage Manager가 있는 iPad에서는 애플리케이션이 메모리에 더 오래 머무를 수 있습니다 — 더 큰 RAM으로 인해 시스템이 애플리케이션을 덜 자주 일시 중단합니다. 그러나 백그라운드 작업의 30초 제한은 유지됩니다.

실제 기기에서 Background Task를 디버그하려면?

기기를 Xcode에 연결하고, 애플리케이션을 실행한 후 최소화하면 콘솔에 시스템 로그가 표시됩니다. sysdiagnose를 사용하여 자세한 로그를 수집하세요: 기기에서 sysdiagnose를 강제 트리거합니다(볼륨 업 + 볼륨 다운 + 전원). Xcode Debug Navigator에서 백그라운드 작업 활동을 모니터링하세요.

요약

  • Background Task — iOS 4.0부터 사용 가능한, 백그라운드 전환 후 작업 완료를 위한 iOS 메커니즘.
  • beginBackgroundTask — 작업을 등록하고 완료를 위한 식별자를 반환하는 UIApplication 메서드.
  • Expiration handler — 30초 제한이 만료될 때 시스템이 호출하는 필수 코드 블록.
  • endBackgroundTask — 작업을 올바르게 완료하기 위한 필수 호출; 없으면 애플리케이션이 메모리에 남음.
  • BGTaskScheduler — 스케줄링, 두 가지 작업 유형 및 실행 조건을 갖춘 현대적 대안(iOS 13+).
  • backgroundTimeRemaining — 남은 시간을 확인하고 작업 동작을 조정하기 위한 속성.
  • 즉시 단기 작업에는 Background Task를, 새 프로젝트의 예약된 백그라운드 업데이트에는 BGTaskScheduler를 사용하세요.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기