SwiftUI를 사용하여 백그라운드에서 데이터 동기화 - Swift SDK
이 페이지의 내용
개요
SwiftUI BackgroundTask 를 사용할 수 있습니다. 앱이 백그라운드에 있을 때 동기화된 Realm을 업데이트합니다. 이 예제는 iOS 앱에서 백그라운드 동기화를 구성하고 수행하는 방법을 보여줍니다.
SwiftUI Device Sync Template 앱을 사용하여 이 페이지의 예제를 따라할 수 있습니다. SwiftUI Device Sync Template 앱의 사본을 얻으려면 Device Sync SwiftUI 튜토리얼 과 Prerequisites 및 Start with the Template 섹션으로 Go 합니다.
앱의 백그라운드 모드 활성화
앱에 백그라운드 작업을 활성화하는 방법:
백그라운드 작업 예약
앱의 백그라운드 프로세스를 활성화한 후 앱에 코드를 추가하여 백그라운드 작업을 예약하고 실행할 수 있습니다. 먼저 이 코드를 쓸 파일에서 BackgroundTasks
을 가져옵니다.
import SwiftUI import RealmSwift import BackgroundTasks
이제 예정된 백그라운드 작업을 추가할 수 있습니다. Template 앱을 통해 팔로우하는 경우 @main
보기를 업데이트할 수 있습니다.
@main struct realmSwiftUIApp: SwiftUI.App { private var phase (\.scenePhase) var body: some Scene { WindowGroup { ContentView(app: realmApp) } .onChange(of: phase) { newPhase in switch newPhase { case .background: scheduleAppRefresh() default: break } } }
환경 변수를 추가해 scenePhase
에 변경 사항을 저장할 수 있습니다: @Environment(\.scenePhase) private var phase
.
그런 다음 앱이 백그라운드로 전환될 때 scheduleAppRefresh()
함수를 호출하는 .onChange(of: phase)
블록을 추가할 수 있습니다.
scheduleAppRefresh()
scheduleAppRefresh()
함수를 생성합니다.
func scheduleAppRefresh() { let backgroundTask = BGAppRefreshTaskRequest(identifier: "refreshTodoRealm") backgroundTask.earliestBeginDate = .now.addingTimeInterval(10) try? BGTaskScheduler.shared.submit(backgroundTask) }
이렇게 하면 백그라운드 모드를 활성화할 때 위의 Info.plist에 식별자를 추가한 백그라운드 작업을 실행하도록 작업이 예약됩니다. 이 예제에서 식별자 refreshTodoRealm
은 이 작업을 합니다.
백그라운드 작업 생성
이제 백그라운드 작업을 예약했으니 동기화된 Realm을 업데이트하기 위해 실행할 백그라운드 작업을 생성해야 합니다.
Template 앱을 팔로우하는 경우 .onChange(of: phase)
다음 @main
보기에 이 backgroundTask
을 추가할 수 있습니다.
.onChange(of: phase) { newPhase in switch newPhase { case .background: scheduleAppRefresh() default: break } } .backgroundTask(.appRefresh("refreshTodoRealm")) { guard let user = realmApp.currentUser else { return } let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in if let foundSubscription = subs.first(named: "user_tasks") { foundSubscription.updateQuery(toType: Item.self, where: { $0.owner_id == user.id }) } else { subs.append(QuerySubscription<Item>(name: "user_tasks") { $0.owner_id == user.id }) } }, rerunOnOpen: true) await refreshSyncedRealm(config: config) }
이 백그라운드 작업은 먼저 앱에 로그인한 사용자가 있는지 확인합니다. 이 경우 .flexibleSyncConfiguration 앱이 Realm을 동기화하는 데 사용할 수 있는 구독 으로 설정합니다.
이는 Template 앱의 ContentView
에 사용된 것과 동일한 구성입니다. 그러나 여기에서 사용하려면 뷰 계층 구조에서 더 상위 단계로 액세스해야 합니다. 이를 두 보기에서 호출할 수 있는 함수로 리팩터링하면 사용자 를 매개 변수로 사용하고 Realm.configuration을 반환합니다.
마지막으로 이 작업은 실제로 Realm을 동기화하는 함수의 결과를 기다립니다. 다음 함수를 추가합니다.
func refreshSyncedRealm(config: Realm.Configuration) async { do { try await Realm(configuration: config, downloadBeforeOpen: .always) } catch { print("Error opening the Synced realm: \(error.localizedDescription)") } }
이 동기화된 Realm을 열고 downloadBeforeOpen
매개 변수를 사용하여 업데이트를 다운로드하도록 지정하면, 배경에서 새 데이터를 Realm에 로드합니다. 그런 다음 앱이 다시 열리면 이미 장치에 업데이트된 데이터가 있습니다.
중요
이 백그라운드 작업에서는 Realm에 직접 쓰려고 하지 마세요. Realm의 스레드 제한 아키텍처로 인해 스레딩 관련 문제가 발생할 수 있습니다.
백그라운드 작업 테스트
배경 작업을 예약할 때, 시스템이 작업을 실행할 수 있는 가장 이른 시간을 설정하고 있는 것입니다 그러나, 운영 체제는 여러분이 예약한 earliestBeginDate
이후에 배경 작업의 실행을 오랫동안 지연시킬 수 있는 많은 다른 고려 사항들을 고려합니다. 장치가 배경 작업을 실행하여 원하는 작업을 수행하는지 기다리는 대신, 중단점을 설정하고 LLDB를 사용하여 작업을 호출할 수 있습니다
앱 실행을 위한 장치 구성
백그라운드 작업이 백그라운드에서 동기화된 Realm을 업데이트하는지 테스트하려면 최소 iOS 16 를 실행하는 물리적 장치가 필요합니다. 개발자 모드 에서 실행되도록 기기를 구성해야 합니다. . Untrusted Developer
알림을 받으면 Settings, General 및 VPN & Device Management로 Go 합니다. 여기에서 개발 중인 앱을 실행할 것인지 확인할 수 있습니다.
여러분의 장치에서 앱을 성공적으로 실행할 수 있으면 배경 작업을 테스트할 수 있습니다.
중단점 설정
scheduleAppRefresh()
함수에 중단점을 설정하는 것으로 시작하세요. 작업을 BGTaskScheduler
에 제출하는 줄 뒤에 중단점을 설정합니다. 이 예제에서는 print
줄을 추가하고 인쇄 줄에 중단점을 설정할 수 있습니다:
func scheduleAppRefresh() { let backgroundTask = BGAppRefreshTaskRequest(identifier: "refreshTodoRealm") backgroundTask.earliestBeginDate = .now.addingTimeInterval(10) try? BGTaskScheduler.shared.submit(backgroundTask) print("Successfully scheduled a background task") // Set a breakpoint here }
Atlas에서 데이터 추가 또는 변경
Xcode에서 앱이 배경에 있지만 여전히 실행 중일 때, 동기화되어야 할 관련 Atlas 컬렉션에 새 문서를 삽입하세요. 또는, 장치에서 생성한 기존 문서의 값을 변경하세요. 배경 작업이 성공적으로 실행된 후, 배경 프로세스에서 장치로 이 데이터가 동기화된 것을 볼 수 있어야 합니다.
SwiftUI 템플릿 앱을 사용하는 경우 Atlas cluster의 Item
컬렉션에서 관련 문서를 찾을 수 있습니다. Atlas에서 문서를 추가하거나 변경하는 방법에 대한 자세한 내용은 MongoDB Atlas: 문서 생성, 보기, 업데이트 및 삭제를 참조하세요.
LLDB에서 백그라운드 작업 호출
이 명령을 사용하여 LLDB에서 배경 작업을 수동으로 실행할 수 있습니다:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"refreshTodoRealm"]
배경 작업에 다른 식별자를 사용한 경우 refreshTodoRealm
작업 식별자로 바꿉니다. 그러면 작업이 즉시 실행되기 시작합니다.
성공하면 다음과 같은 내용이 표시됩니다:
2022-11-11 15:09:10.403242-0500 App[1268:196548] Simulating launch for task with identifier refreshTodoRealm 2022-11-11 15:09:16.530201-0500 App[1268:196811] Starting simulated task
작업을 시작한 후 Xcode 디버그 패널의 Continue program execution 버튼을 사용하여 앱 실행을 다시 시작합니다.