iOS에서 백그라운드 작업을 수행하는 가장 간단한 방법은 백그라운드 요구 사항을 작업으로 분리하고 백그라운드에서 작업을 실행하는 것입니다. 작업은 엄격한 시간 제한에 있으며, 일반적으로 애플리케이션이 iOS 6의 백그라운드로 이동한 후 처리 시간이 약 600초(10분)이고 iOS 7 이상에서는 10분 미만입니다.
백그라운드 작업은 다음 세 가지 범주로 나눌 수 있습니다.
- 백그라운드 금고 작업 - 애플리케이션이 배경을 입력할 때 중단하지 않으려는 작업이 있는 애플리케이션의 아무 곳이나 호출됩니다.
- DidEnterBackground 작업 - 애플리케이션 수명 주기 메서드 중에
DidEnterBackground
호출되어 클린 및 상태 저장을 지원합니다. - 백그라운드 전송(iOS 7 이상) - iOS 7에서 네트워크 전송을 수행하는 데 사용되는 특수한 유형의 백그라운드 작업입니다. 일반 작업과 달리 백그라운드 전송에는 미리 결정된 시간 제한이 없습니다.
백그라운드로부터 안전하며 DidEnterBackground
작업은 iOS 6 및 iOS 7 모두에서 안전하게 사용할 수 있으며 몇 가지 사소한 차이점이 있습니다. 이러한 두 가지 유형의 작업을 자세히 조사해 보겠습니다.
백그라운드 금고 작업 만들기
일부 애플리케이션에는 애플리케이션이 상태를 변경하는 경우 iOS에서 중단해서는 안 되는 작업이 포함되어 있습니다. 이러한 작업이 중단되지 않도록 보호하는 한 가지 방법은 iOS에 장기 실행 작업으로 등록하는 것입니다. 사용자가 앱을 백그라운드에 배치하는 경우 작업을 중단하지 않으려는 애플리케이션의 어디에서나 이 패턴을 사용할 수 있습니다. 이 패턴의 좋은 후보는 새 사용자의 등록 정보를 서버에 보내거나 로그인 정보를 확인하는 작업입니다.
다음 코드 조각은 백그라운드에서 실행할 작업을 등록하는 방법을 보여 줍니다.
nint taskID = UIApplication.SharedApplication.BeginBackgroundTask( () => {});
//runs on main or background thread
FinishLongRunningTask(taskID);
UIApplication.SharedApplication.EndBackgroundTask(taskID);
등록 프로세스는 작업을 고유 식별자와 taskID
쌍으로 연결한 다음 일치 BeginBackgroundTask
및 EndBackgroundTask
호출로 래핑합니다. 식별자를 생성하기 위해 개체에서 UIApplication
메서드를 BeginBackgroundTask
호출한 다음 일반적으로 새 스레드에서 장기 실행 작업을 시작합니다. 작업이 완료되면 동일한 식별자를 호출 EndBackgroundTask
하고 전달합니다. 호출에 일치하는 EndBackgroundTask
항목이 없는 경우 iOS에서 애플리케이션을 BeginBackgroundTask
종료하기 때문에 이 작업이 중요합니다.
Important
백그라운드로부터 안전한 작업은 애플리케이션의 요구에 따라 기본 스레드 또는 백그라운드 스레드에서 실행할 수 있습니다.
DidEnterBackground 중에 작업 수행
장기 실행 작업을 백그라운드에서 안전하게 만드는 것 외에도 애플리케이션이 백그라운드에 배치될 때 등록을 사용하여 작업을 시작할 수 있습니다. iOS는 애플리케이션이 백그라운드로 들어가기 전에 애플리케이션 상태를 저장하고, 사용자 데이터를 저장하고, 중요한 콘텐츠를 암호화하는 데 사용할 수 있는 AppDelegate 클래스에 이벤트 DidEnterBackground
메서드를 제공합니다. 애플리케이션이 이 메서드에서 반환하는 데 약 5초가 있거나 종료됩니다. 따라서 완료하는 데 5초 이상 걸릴 수 있는 클린up 작업을 메서드 내부에서 DidEnterBackground
호출할 수 있습니다. 이러한 작업은 별도의 스레드에서 호출해야 합니다.
이 프로세스는 장기 실행 작업을 등록하는 프로세스와 거의 동일합니다. 다음 코드 조각은 이 동작을 보여 줍니다.
public override void DidEnterBackground (UIApplication application) {
nint taskID = UIApplication.SharedApplication.BeginBackgroundTask( () => {});
new Task ( () => {
DoWork();
UIApplication.SharedApplication.EndBackgroundTask(taskID);
}).Start();
}
먼저 이전 예제에서AppDelegate
와 같이 작업을 BeginBackgroundTask
등록하는 DidEnterBackground
메서드를 재정의합니다. 다음으로, 새 스레드를 생성하고 장기 실행 작업을 수행합니다. 메서드가 EndBackgroundTask
이미 반환되었으므로 이제 장기 실행 작업 DidEnterBackground
내에서 호출이 수행됩니다.
Important
iOS는 Watchdog 메커니즘을 사용하여 애플리케이션의 UI가 응답하는 기본 보장합니다. 너무 많은 시간을 DidEnterBackground
소비하는 애플리케이션은 UI에서 응답하지 않습니다. 백그라운드에서 실행되도록 작업을 시작하면 적시에 반환하여 UI 응답성을 유지하고 Watchdog가 애플리케이션을 종료하지 못하도록 방지할 수 DidEnterBackground
있습니다.
백그라운드 작업 시간 제한 처리
iOS는 백그라운드 작업을 실행할 수 있는 기간에 엄격한 제한을 두며, 할당된 시간 내에 호출이 수행되지 않으면 EndBackgroundTask
애플리케이션이 종료됩니다. 다시 기본 백그라운드 시간을 추적하고 필요한 경우 만료 처리기를 사용하면 iOS에서 애플리케이션을 종료하지 않도록 방지할 수 있습니다.
백그라운드 시간 다시 액세스기본
등록된 작업이 있는 애플리케이션이 백그라운드로 이동되면 등록된 작업은 약 600초 동안 실행됩니다. 클래스의 UIApplication
정적 BackgroundTimeRemaining
속성을 사용하여 작업이 완료되는 시간을 검사 수 있습니다. 다음 코드는 백그라운드 작업이 남은 시간(초)을 제공합니다.
double timeRemaining = UIApplication.SharedApplication.BackgroundTimeRemaining;
만료 처리기로 앱 종료 방지
iOS는 속성에 BackgroundTimeRemaining
대한 액세스 권한을 부여하는 것 외에도 만료 처리기를 통해 백그라운드 시간 만료를 처리하는 정상적인 방법을 제공합니다. 작업에 할당된 시간이 만료될 때 실행되는 선택적 코드 블록입니다. 만료 처리기의 코드는 작업 ID를 호출 EndBackgroundTask
하고 전달합니다. 이는 앱이 잘 작동하고 있으며 작업이 시간이 부족하더라도 iOS가 앱을 종료하지 못하도록 합니다. EndBackgroundTask
는 일반적인 실행 과정뿐만 아니라 만료 처리기 내에서 호출되어야 합니다.
만료 처리기는 아래 그림과 같이 람다 식을 사용하여 익명 함수로 표현됩니다.
Task.Factory.StartNew( () => {
//expirationHandler only called if background time allowed exceeded
var taskId = UIApplication.SharedApplication.BeginBackgroundTask(() => {
Console.WriteLine("Exhausted time");
UIApplication.SharedApplication.EndBackgroundTask(taskId);
});
while(myFlag == true)
{
Console.WriteLine(UIApplication.SharedApplication.BackgroundTimeRemaining);
myFlag = SomeCalculationNeedsMoreTime();
}
//Only called if loop terminated due to myFlag and not expiration of time
UIApplication.SharedApplication.EndBackgroundTask(taskId);
});
코드가 실행되기 위해서는 만료 처리기가 필요하지 않지만 항상 백그라운드 작업과 함께 만료 처리기를 사용해야 합니다.
iOS 7 이상의 백그라운드 작업
백그라운드 작업과 관련하여 iOS 7의 가장 큰 변화는 태스크가 구현되는 방식이 아니라 실행할 때입니다.
iOS 7 이전에서는 백그라운드에서 실행 중인 작업이 완료되는 데 600초가 소요되었다는 점을 기억하세요. 이 제한의 한 가지 이유는 백그라운드에서 실행 중인 작업이 작업 기간 동안 디바이스를 해제 상태로 유지하기 때문입니다.
iOS 7 백그라운드 처리는 더 긴 배터리 수명을 위해 최적화되어 있습니다. iOS 7에서는 백그라운드 작업이 기회적입니다. 디바이스를 절전 모드로 유지하는 대신, 디바이스가 절전 모드로 전환될 때 작업을 존중하고, 디바이스가 절전 모드에서 해제되어 전화 통화, 알림, 들어오는 전자 메일 및 기타 일반적인 중단을 처리할 때 처리를 수행합니다. 다음 다이어그램은 작업을 분할하는 방법에 대한 인사이트를 제공합니다.
작업 실행 시간이 더 이상 연속되지 않으므로 네트워크 전송을 수행하는 작업은 iOS 7에서 다르게 처리되어야 합니다. 개발자는 API를 NSURlSession
사용하여 네트워크 전송을 처리하는 것이 좋습니다. 다음 섹션은 백그라운드 전송에 대한 개요입니다.
백그라운드 전송
iOS 7에서 백그라운드 전송의 중추는 새로운 NSURLSession
API입니다. NSURLSession
을 사용하면 다음 작업을 만들 수 있습니다.
- 네트워크 및 디바이스 중단을 통해 콘텐츠를 전송합니다.
- 대용량 파일( 백그라운드 전송 서비스 )을 업로드하고 다운로드합니다.
작동 원리를 자세히 살펴보겠습니다.
NSURLSession API
NSURLSession
는 네트워크를 통해 콘텐츠를 전송하기 위한 강력한 API입니다. 네트워크 중단 및 애플리케이션 상태 변경을 통해 데이터 전송을 처리하는 도구 집합을 제공합니다.
API는 NSURLSession
하나 또는 여러 세션을 만듭니다. 그러면 네트워크를 통해 관련 데이터의 블록을 셔틀하는 작업이 생성됩니다. 태스크는 데이터를 빠르고 안정적으로 전송하기 위해 비동기적으로 실행됩니다. 비동기이기 때문에 NSURLSession
모든 세션에는 전송이 완료될 때 시스템과 애플리케이션에 알리기 위해 완료 처리기 블록이 필요합니다.
iOS 7 이전 및 iOS 7 이후 모두에 유효한 네트워크 전송을 수행하려면 전송을 큐에 넣기 위해 사용할 수 있는지 NSURLSession
검사 일반 백그라운드 작업을 사용하여 전송을 수행합니다(그렇지 않은 경우).
if ([NSURLSession class]) {
// Create a background session and enqueue transfers
}
else {
// Start a background task and transfer directly
// Do NOT make calls to update the UI here!
}
Important
iOS 6은 백그라운드 UI 업데이트를 지원하지 않으며 애플리케이션을 종료하므로 iOS 6 규격 코드에서 백그라운드에서 UI를 업데이트하기 위해 호출하지 마세요.
API에는 NSURLSession
인증을 처리하고, 실패한 전송을 관리하고, 서버 쪽이 아닌 클라이언트 쪽 오류를 보고하는 다양한 기능 집합이 포함되어 있습니다. iOS 7에 도입된 작업 런타임의 중단을 해소하고 대용량 파일을 빠르고 안정적으로 전송할 수 있도록 지원합니다. 다음 섹션에서는 이 두 번째 기능을 살펴봅니다.
백그라운드 전송 서비스
iOS 7 이전에는 백그라운드에서 파일을 업로드하거나 다운로드할 수 없습니다. 백그라운드 작업은 실행 시간이 제한되지만 파일을 전송하는 데 걸리는 시간은 네트워크 및 파일 크기에 따라 다릅니다. iOS 7에서는 대용량 파일을 성공적으로 업로드하고 다운로드하는 데 사용할 NSURLSession
수 있습니다. 백그라운드에서 대용량 파일의 네트워크 전송을 처리하는 특정 NSURLSession
세션 유형을 백그라운드 전송 서비스라고 합니다.
백그라운드 전송 서비스를 사용하여 시작된 전송은 운영 체제에서 관리되며 인증 및 오류를 처리하는 API를 제공합니다. 전송은 임의의 시간 제한에 의해 바인딩되지 않으므로 큰 파일을 업로드하거나 다운로드하고 백그라운드에서 콘텐츠를 자동 업데이트하는 데 사용할 수 있습니다. 서비스를 구현하는 방법에 대한 자세한 내용은 백그라운드 전송 연습을 참조하세요.
백그라운드 전송 서비스는 애플리케이션이 백그라운드에서 콘텐츠를 새로 고치는 데 도움이 되도록 백그라운드 페치 또는 원격 알림과 페어링되는 경우가 많습니다. 다음 두 섹션에서는 iOS 6 및 iOS 7 모두에서 백그라운드에서 실행되도록 전체 애플리케이션을 등록하는 개념을 소개합니다.