동기화 세션 관리 - Swift SDK
이 페이지의 내용
동기화된 영역 을 열면 해당Realm 에 대한 영역 이 시작됩니다. Realm Swift SDK 는 동기화 세션 을 수동으로 일시 중지하고 다시 시작하는 메서드를 제공합니다.
동기화 연결 동작
버전 10.41.0의 새로운 기능.
Realm Swift SDK 버전 10.41.0 이상에서 Atlas App Services는 열려 있는 모든 동기화 Realm에 대해 서버에 대한 단일 연결을 공유하도록 기본 설정됩니다. 이는 둘 이상의 동기화된 영역을 열면 서버에 대한 추가 연결이 열리는 이전 버전과의 변경 사항입니다. 서버에 대한 연결은 SyncSession
와 독립적이며 App Services 사용자를 기반으로 합니다.
네트워크 연결 확인
팁
Realm의 오프라인 우선 설계는 일반적으로 현재 네트워크 연결 상태를 확인할 필요가 없음을 의미합니다. 즉, 앱이 연결 상태 표시를 요청하는 경우 connectionState
속성을 사용할 수 있습니다.
연결 상태를 확인하려면 동기화된 영역의 RLMSyncSession 인스턴스의 connectionState 속성을 직접 읽으면 됩니다.
이 속성 은 KVO를 준수합니다. KVO를 사용하여 변경 사항을 관찰할 수 있습니다. 다음 예시 에서는 관찰자 클래스를 구현 하는 방법을 보여 줍니다.
@interface MySyncSessionObserver: NSObject @end @implementation MySyncSessionObserver - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (![object isKindOfClass:RLMSyncSession.class]) { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; return; } if (![keyPath isEqualToString:@"connectionState"]) { // Not interested in observing this keypath return; } RLMSyncSession *syncSession = (RLMSyncSession *)object; RLMSyncConnectionState connectionState = [syncSession connectionState]; switch (connectionState) { case RLMSyncConnectionStateConnecting: NSLog(@"Connecting..."); break; case RLMSyncConnectionStateConnected: NSLog(@"Connected"); break; case RLMSyncConnectionStateDisconnected: NSLog(@"Disconnected"); break; } } @end
그런 다음 관찰자 인스턴스 를 RLMSyncSession 객체 에 연결할 수 있습니다. 완료되면 관찰자를 제거 해야 합니다.
// Observe connectionState for changes using KVO MySyncSessionObserver *observer = [[MySyncSessionObserver alloc] init]; [syncSession addObserver:observer forKeyPath:@"connectionState" options:NSKeyValueObservingOptionInitial context:nil]; // Later, when done... [syncSession removeObserver:observer forKeyPath:@"connectionState" context:nil];
연결 상태를 확인하려면 동기화된 영역의 SyncSession 인스턴스의 connectionState 속성을 직접 읽으면 됩니다.
이 속성은 KVO를 준수합니다., KVO 또는 결합을 사용하여 변경 사항을 관찰할 수 있습니다.
// Observe connectionState for changes using KVO let observer = syncSession.observe(\.connectionState, options: [.initial]) { (syncSession, change) in switch syncSession.connectionState { case .connecting: print("Connecting...") case .connected: print("Connected") case .disconnected: print("Disconnected") default: break } } // Observe using Combine let cancellable = syncSession.publisher(for: \.connectionState) .sink { connectionState in switch connectionState { case .connecting: print("Connecting...") case .connected: print("Connected") case .disconnected: print("Disconnected") default: break } }
동기화 세션 일시 중단 또는 다시 시작하기
영역에서 동기화 세션을 일시 중단했다가 다시 시작할 수 있습니다. 동기화 세션을 일시 중지하면 해당 Realm의 동기화 세션만 일시 중단됩니다. 열려 있는 영역이 두 개 이상 있는 경우 일시 중단해도 다른 영역의 동기화 세션에는 영향을 주지 않습니다.
동기화된 Realm 영역 RLMSyncSession 인스턴스 를 사용하여 동기화 세션 을 일시 중단하거나 재개할 수 있습니다.
RLMRealm *syncedRealm = [RLMRealm realmWithConfiguration:configuration error:nil]; RLMSyncSession *syncSession = [syncedRealm syncSession]; // Suspend synchronization [syncSession suspend]; // Later, resume synchronization [syncSession resume];
동기화된 Realm의 SyncSession 인스턴스를 사용하여 동기화 세션을 일시 중단하거나 다시 시작할 수 있습니다.
let syncSession = syncedRealm.syncSession! // Suspend synchronization syncSession.suspend() // Later, resume synchronization syncSession.resume()
동기화 세션을 일시 중지해야 하는 경우
대부분의 애플리케이션은 동기화 세션을 수동으로 일시 중지했다가 다시 시작할 필요가 없습니다. 그러나 동기화 세션을 일시 중지하거나 일시 중지해야 하는 몇 가지 상황이 있습니다.
사용자가 특정 조치를 취한 후에만 동기화하려는 경우
하루 중 특정 시간에만 동기화하려는 경우
네트워크 연결이 좋지 않을 때 동기화를 시도하고 싶지 않은 경우
동기화 세션을 명시적으로 강제로 연결하려는 경우
네트워크 연결이 좋지 않은 경우 계속해서 네트워크 연결을 설정하려고 하면 사용자의 장치 배터리가 소모될 수 있습니다.
동기화 세션을 연결하도록 명시적으로 강제하는 경우는 가장 일반적으로 일정 시간 동안 오프라인 상태인 것과 관련이 있습니다. 동기화 클라이언트는 연결을 시도하지만 실패 시 지수 백오프 상태가 됩니다. 클라이언트가 오랫동안 오프라인 상태였다가 즉시 다시 연결되지 않을 수 있습니다. 동기화 세션을 일시 중지했다가 다시 시작하면 명시적으로 연결이 강제로 적용됩니다.
동기화 세션을 일시 중지할 때는 다음 사항에 유의하세요.
클라이언트가 클라이언트 최대 오프라인 시간 보다 오래 오프라인 상태일 수 있는 경우 클라이언트는 동기화를 다시 시작할 수 없으며 클라이언트 재설정을 수행해야 합니다.
동기화 세션을 일시 중지하면 양쪽 방향에서 모두 일시 중지됩니다. 앱이 기기에서 수행하는 변경 사항은 백엔드 와 동기화되지 않으며, 백엔드 또는 다른 기기에서 변경한 데이터는 기기에 동기화되지 않습니다. 업로드만 일시 중지 또는 다운로드만 일시 중지할 수 있는 방법은 없습니다.
클라이언트가 백엔드와의 동기화를 영구적으로 중지하도록 하려면 동기화 세션을 일시 중지하지 마세요. 동기화를 영구적으로 중지하려면 동기화된 영역의 콘텐츠를 동기화되지 않은 영역에 복사하고 클라이언트에서 동기화되지 않은 영역을 사용합니다.
무기한 또는 월 및 연도 단위의 시간 범위 동안 동기화를 중지하기 위해 동기화를 일시 중지 하지 마세요 . 이 사용 사례에 맞게 기능이 설계되거나 테스트되지 않았습니다. 이러한 방식으로 사용하면 다양한 문제가 발생할 수 있습니다.
변경 사항이 업로드 또는 다운로드될 때까지 기다립니다.
버전 10.45.0의 새로운 기능.
동기화된 Realm 에서 모든 변경 사항이 업로드되거나 다운로드 될 때까지 기다리려면 영역 영역?.wait(for: )를 호출합니다.
이 메서드는 ProgressDirection 인수를 사용하여 업로드 또는 다운로드 진행 상황을 추적 할지 여부를 지정합니다.
이러한 메서드는 Swift의 비동기/await 구문 또는 콜백 구문과 함께 사용할 수 있습니다. 콜백 버전인 영역.syncSession?.wait(for:queue: 차단) 은 콜백 을 전달할 대기열과 대기가 완료될 때 호출할 차단 을 사용할 수 있습니다.
// Wait to download all pending changes from Atlas try await realm.syncSession?.wait(for: .download) // Add data locally try realm.write { realm.create(Task.self, value: [ "taskName": "Review proposal", "assignee": "Emma", "completed": false, "progressMinutes": 0, "dueDate": date ]) } // Wait for local changes to be uploaded to Atlas try await realm.syncSession?.wait(for: .upload)
// Wait to download all pending changes from Atlas realm.syncSession?.wait(for: .download, block: { _ in // You can provide a block to execute // after waiting for download to complete }) // Add data locally do { try realm.write { realm.create(Task.self, value: [ "taskName": "Review proposal", "assignee": "Emma", "completed": false, "progressMinutes": 0, "dueDate": date ]) } } catch { print("There was an error writing to realm: \(error.localizedDescription)") } // Wait for local changes to be uploaded to Atlas realm.syncSession?.wait(for: .upload, block: { _ in // You can provide a block to execute after // waiting for upload to complete })
동기화 세션에 대한 업로드 및 다운로드 진행률 확인
버전 10.50.0에서 변경됨: transferredBytes
및 transferrableBytes
가 더 이상 사용되지 않으며 progressEstimate
로 대체됨
지정된 업로드 또는 다운로드 방향 및 작업 범위에 대해 progressEstimate
를 제공하는 토큰을 등록하여 업로드 및 다운로드 진행률을 확인할 수 있습니다. ProgressMode
를 설정하다 하여 작업 범위를 결정할 수 있습니다: 무기한 관찰하거나 현재 작업 항목이 완료된 후 차단 을 등록 취소합니다.
토큰에서 제공하는 progressEstimate
값은 0.0
~ 1.0
범위의 double 입니다. 1.0
에서 업로드 또는 다운로드 가 완료됩니다. 이 progressEstimate
를 사용하여 진행률 표시기 또는 예상 데이터 전송 전송률을 표시할 수 있습니다.
버전 10.50.0에서 변경됨: addProgressNotificationForDirection
은(는) addSyncProgressNotificationForDirection
으)로 더 이상 사용되지 않습니다.
동기화된 영역의 RLMSyncSession 인스턴스의 [--addSyncProgressNotificationForDirection:mode:block:] 메서드를 사용하여 진행률 알림을 추가할 수 있습니다.
이 메서드는 업로드 또는 다운로드 진행 상황 관찰을 중단할 때까지 보유해야 하는 토큰을 반환합니다. 토큰을 지역 변수에 보관하면 지역 변수가 범위를 벗어나면 관찰이 중지됩니다.
RLMSyncSession *syncSession = [syncedRealm syncSession]; RLMProgressNotificationToken *token = [syncSession addSyncProgressNotificationForDirection:RLMSyncProgressDirectionUpload mode:RLMSyncProgressModeForCurrentlyOutstandingWork block:^(RLMSyncProgress syncProgress) { NSLog(@"Uploaded %fB", (double)syncProgress.progressEstimate); }]; // Upload something [syncedRealm transactionWithBlock:^{ [syncedRealm addObject:[[Task alloc] init]]; }];
동기화된 영역의 SyncSession 인스턴스의 addProgressNotification(for:mode:block:) 메서드를 사용하여 진행률 알림을 추가할 수 있습니다.
이 메서드는 업로드 또는 다운로드 진행 상황 관찰을 중단할 때까지 보유해야 하는 토큰을 반환합니다. 토큰을 지역 변수에 보관하면 지역 변수가 범위를 벗어나면 관찰이 중지됩니다.
let syncSession = realm.syncSession! let token = syncSession.addProgressNotification( for: .upload, mode: .forCurrentlyOutstandingWork) { (progress) in let progressEstimate = progress.progressEstimate let transferPercent = progressEstimate * 100 print("Uploaded (\(transferPercent)%)") }
모든 동기화 세션에 수동으로 다시 연결
버전 10.44.0의 새로운 기능.
Realm은 장치가 오프라인 상태였다가 다시 연결되면 자동으로 감지하고 증분 백오프 전략을 사용하여 다시 연결을 시도합니다. 예를 들어 Apple 플랫폼에서 Realm은 네트워크 변경 알림을 수신하고 수신 즉시 자동으로 Atlas Triggers 재연결을 합니다.
Swift SDK 버전 10.44.0 이상에서는 증분 백오프 기간 동안 기다리는 대신 SyncSession.reconnect()
으)로 재연결 시도를 수동으로 trigger하도록 선택할 수 있습니다. 이는 네트워크 상태를 더 정확하게 이해하고 있고 Realm의 자동 재연결 감지에 의존하고 싶지 않은 경우에 유용합니다.
let syncSession = realm.syncSession! // Work with the realm. When you need to force the sync session to reconnect... syncSession.reconnect()
이 메서드를 호출하면 SDK는 모든 동기화 세션이 즉시 재연결을 시도 하도록 강제합니다. 이렇게 하면 증분 백오프에 사용되는 모든 타이머가 재설정됩니다.
이 메서드를 호출한다고 해서 기기의 재연결이 보장되는 것은 아닙니다. SDK에 치명적인 오류가 발생하거나 장치가 이미 연결되었거나 연결을 시도하는 경우 이 메서드를 호출해도 아무런 효과가 없습니다.
중요
소켓 읽기 제한 시간 내에 다시 연결할 수 없음
Realm의 내부 기본 소켓 읽기 제한 시간은 2분이며, 읽기 작업이 2분 창 내에 데이터를 수신하지 않으면 Realm이 시간 초과됩니다. 해당 창 내에서 SyncSession.reconnect()
를 호출하면 Swift SDK는 다시 연결을 시도하지 않습니다 .