Background Task?

* Background: 앱이 백그라운드에 있으며, 화면에 보이지 않지만 코드가 실행될 수 있는 상태.
* Suspended: 앱이 백그라운드에 있으며, 코드 실행이 일시 중지된 상태.

앱이 위 2가지 상태중에 하나 일때, 시스템에 "원하는 코드/작업"을 "언제 실행"시키라고 지정하는 것임

실제로 iOS는 해당시간이 되면 앱을 깨워 실행하게 되나, 시스템 상황에 따라 시간적 오차가 있을 수 있음.

주로, 유저가 앱을 안보고 있을 때 어떠한 업데이트를 하여 유저 사용성을 높이는데 사용되고 있음.

구현 방법

1. Signing & Capabilities 에 "Background Modes" 추가하기

  • Background Fetch 체크 (extension이 있어도 main target 한곳에만 기능추가하고 체크하면 됨)
  • 그 외에도 Background 작업의 선택지로는
    1) Background Processing : db작업, 다운로드 등 헤비한 작업할 때 사용 - 코드가 조금 다름)
    2) Remote Notifications : 서버에서 Slient Push Noti를 보내서 백단에서 앱을 깨우고 원하는 작업 실행하게 하는 것
    구조적으로 정기적(Fetch: 라이트한 작업/Processing: 헤비한 작업) 비정기적(Remote Notifications) 으로 나뉨

2. Info.plist에 식별자 추가하기

  • 우리가 Background Task를 등록할 때, 이 Task를 언제 실행되도록 해주세요. 라고 시스템에 등록하는 과정이 있음.

  • 이때 이 과정의 이름도 등록해야하는데, 그 이름들을 시스템에 모아서 알려주는 것임.

  • 아래 예시는 "randomImage"라고 등록하였음. (이때 따옴표까지 같이 값을 넣는 실수를 종종하곤 하는데 유의할것)


3. Background Task 등록하기

  • Background Task의 이름은 randomImage인데, 이 녀석을 언제 실행하도록 해주세요를 시스템에 등록하는 행위

  • 이때, Task의 존재만 등록하는 것이고, "그때가 되면 Task가 어떤 코드를 실행해야하는지"에 대해선 여기서 따로 셋팅하지는 않음.

  • 아래 코드를 보면,

1) BackgroundTasks를 import하였음

2) 실제로는 평범한 뷰 안에 있는 내용인데, 그 중에 관련된 코드만 뽑아서 따로 적은 것임

3) 버튼 뷰의 콜백메소드를 살펴보면, BGAppRefreshTaskRequest안에 identifier를 넣어줘야 하는데, 이게 Task의 이름임
- 위에서 randomImage로 등록해놨으니, 그걸 써야함.
- 실제로 이름은 안겹치게 하기 위해, bundleID + @의 조합으로 많이씀.

4) 이름 등록했으니, 언제 시작할지 셋팅해줘야하며, 그게 earlistBeginDate 파라미터임.

- Date 객체를 넣어서 시점을 주입해야함. 

- 이름부터 알 수 있지만, 이게 "최소 이때 이후로 실행되어라~"의 개념으로, iOS가 바쁠땐 배터리 소모 등을 고려해서 뒤로 미뤄질 수 있음. 

5) 이름/시점 셋팅 완료했으면 스케쥴러에 등록하는 과정을 거침

- BGTaskScheduler.shared.submit 메소드 안에 우리가 만든 TaskRequest를 넣어준다.

- 이때 do-catch로 처리해주는 게 좋음. 괜히 try? 로 했다가 무슨 에러인지 파악도 안되어서 시간낭비만 할 수 있음. 
import BackgroundTasks
---

Button("Schedule Background Task") {
				let request = BGAppRefreshTaskRequest(identifier: "randomImage") // Mark 1
				request.earliestBeginDate = Calendar.current.date(byAdding: .second, value: 30, to: Date()) // Mark 2
				do {
					try BGTaskScheduler.shared.submit(request) // Mark 3
					print("Background Task Scheduled!")
				} catch(let error) {
					print("Scheduling Error \(error.localizedDescription)")
				}
				
			}.buttonStyle(.bordered)
				.tint(.red)
				.padding()

4. BackgroundTask 콜백 등록하기

  • 3단계에서, Task의 이름 및 언제 발동되록 시스템에 등록해줌.

  • 이제 그럼 실제로 실행되었을 때, 어떤 코드가 실행되어야하는지 설정해줘야함.

  • 앱의 진입점에 해당하는, 최상단 view에 (보통은 WindowGroup) .backgroundTask Modifier에서 설정하면 됨.

  • 이때 app.Refresh(테스크이름) 파라미터로 넣어주어, 어떤 이름을 가진 BackgroundTask인지에 대해 인지해야함.

  • 그리고 식별이 되었을 때 우리가 원하는 코드를 클로저로 넣어주면 됨

  • 알아두어야 할 점은 여기서는 await/async를 사용할 수 있음.

  • 그리고 여기서 실행 전에, 다시 작업을 설정할 수 있음. 즉 위 3단계에서 했던 이름/시점 등록과정을 여기서 또 할 수 있음. 그러면 "정기적으로 백그라운드 실행환경"을 구현할 수 있게 됨. 위 예시에서는 버튼을 눌러서 작업 등록을 했지만. onAppear 등에서 셋팅할 수도 있음.

var body: some Scene {
        WindowGroup {
			ContentView(imageStore: imageStore)
        }
		.backgroundTask(.appRefresh("randomImage")) {
			await refreshAppData()
		}
    }
profile
RTFM
post-custom-banner

0개의 댓글