https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler
"A class for scheduling task requests that launch your app in the background."
백그라운드에서 앱을 launch 하는 작업 요청에 대해 스케줄링하기 위한 클래스입니다.
class BGTaskScheduler : NSObject
작업은 데이터베이스 유지보수, 머신러닝 모델 업데이트, 앱에서 표시된 데이터 업데이트와 같은 독립적인 활동입니다. 프로세싱 시간과 전력의 사용을 효율적으로 만드려면 시스템은 기기가 사용 중이지 않을 때에도 작업이 백그라운드에서 실행되도록 앱을 launch할 수 있습니다.
작업은 여러번 실행될 수 있습니다. 백그라운드에서 실행하는 작업을 스케줄링하려면, 앱을 백그라운드 작업 실행 가능하도록 설정해야 하고, 다음으로 작업에 대한 launch 핸들러를 등록해야 합니다.
필요한 백그라운드 모드 기능을 추가하고 허용된 작업 아이덴티파이어의 리스트를 추가해서 백그라운드 작업을 위해 앱을 설정하시기 바랍니다.
기능을 추가하려면 아래처럼 해야 합니다.
시스템은 허용된 작업 아이덴티파이어의 리스트에 아이덴티파이어를 갖는 등록된 작업만 실행합니다. 이 리스트를 생성하려면 Info.plist 파일에 아이덴티파이어를 추가해야 합니다.
BGTaskSchedulerPermittedIdentifiers
배열에 상응하는 “Permitted background task scheduler identifiers”를 선택합니다.iOS 13 및 이후 버전에서 Info.plist에 BGTaskSchedulerPermittedIdentifiers
키를 추가하는 것은 application(_:performFetchWithCompletionHandler:)
및 setMinimumBackgroundFetchInterval(_:)
을 비활성화합니다.
앱 시작 중 작업을 실행하는 코드의 작은 블록인 launch 핸들러를 등록할 수 있으며, 각 작업에 관련이 있는 고유한 아이덴티파이어를 등록할 수 있습니다. 앱 launch 단계가 끝나기 전에 모든 작업을 등록하시기 바랍니다. About the App Launch Sequence를 살펴보시기 바랍니다.
About the App Launch Sequence
https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence
https://velog.io/@panther222128/About-the-App-Launch-Sequence
Note
확장 역시 스케줄링을 할 수 있습니다. 메인 앱에 확장으로 스케줄링한 작업을 등록합니다(시스템이 작업 실행을 위해 앱을 launch합니다).
아래 코드는 핸들러를 등록하고 있습니다. handleAppRefresh(task:)
부분이며, 시스템이 아이덴티파이어 com.example.apple-samplecode.ColorFeed.refresh
와 함께 작업 요청을 실행할 때 호출됩니다.
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.apple-samplecode.ColorFeed.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
submit(_:)
을 사용해서 이후에 백그라운드에서 앱을 launch 하기 위해 시스템에 작업 요청을 보내야 합니다. 작업을 다시 보내면 이전에 보낸 것을 교체합니다. 예를 들어 작업의 설정을 업데이트하는 것은 작업을 다시 보낼 것을 요구합니다.
아래 코드는 이전에 등록했던 com.example.apple-samplecode.ColorFeed.refresh
작업 아이덴티파이어에 대해 리프레시 작업 요청을 스케줄링합니다.
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: "com.example.apple-samplecode.ColorFeed.refresh")
// Fetch no earlier than 15 minutes from now
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
시스템이 백그라운드에서 앱을 열 때, 작업 실행을 위해 launch 핸들러를 호출합니다.
func handleAppRefresh(task: BGAppRefreshTask) {
// Schedule a new refresh task
scheduleAppRefresh()
// Create an operation that performs the main part of the background task
let operation = RefreshAppContentsOperation()
// Provide an expiration handler for the background task
// that cancels the operation
task.expirationHandler = {
operation.cancel()
}
// Inform the system that the background task is complete
// when the operation completes
operation.completionBlock = {
task.setTaskCompleted(success: !operation.isCancelled)
}
// Start the operation
operationQueue.addOperation(operation)
}
작업은 시스템이 작업 종료가 필요한 경우 호출하는 만료 핸들러를 제공합니다. 작업이 성공적으로 완료되었을 경우 시스템에게 알리기 위한 코드를 추가할 수도 있습니다.
작업을 시작하기 위해, 그리고 컴플리션 전에 작업을 종료시키기 위해 개발 중 디버거를 사용합니다.
https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development
https://velog.io/@panther222128/Starting-and-Terminating-Tasks-During-Development
앱에서 백그라운드 런타임 스케줄링을 위한 최선의 메소드를 선택합니다.
https://developer.apple.com/documentation/backgroundtasks/choosing_background_strategies_for_your_app
https://velog.io/@panther222128/Choosing-Background-Strategies-for-Your-App