Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

파티션 기반 동기화 - Swift SDK

이 페이지의 내용

  • 파티션 기반 동기화 Realm 열기
  • 동기화되지 않은 Realm을 동기화된 Realm으로 열기
  • 동기화된 Realm을 동기화되지 않은 Realm으로 열기
  • 파티션 기반 동기화에서 Flexible Sync로 마이그레이션
  • 마이그레이션 후 클라이언트 코드 업데이트

파티션 기반 동기화는 Realm Swift SDK와 함께 Atlas Device Sync를 사용하기 위한 이전 모드입니다. 새 앱에는 Flexible Sync 를 사용하는 것이 좋습니다. 이 페이지의 정보는 아직 파티션 기반 동기화를 사용하고 있는 사용자를 위한 것입니다.

Realm Swift SDK v10.40.0 이상에서는 파티션 기반 동기화 에서 Flexible Sync로 마이그레이션 하는 기능 을 지원합니다. 자세한 내용은 파티션 기반 동기화 에서 Flexible Sync로 마이그레이션을 참조하세요.

파티션 기반 동기화 및 Atlas App Services 에서 구성하는 방법에 대한 자세한 내용은 App Services 문서의 파티션 기반 동기화 를 참조하세요.

When you select Partition-Based Sync for your backend App configuration, your client implementation must include a partition value. 이는 파티션 기반 동기화 를 구성할 때 선택하는 파티션 키 필드 의 값입니다.

파티션 값에 따라 클라이언트 애플리케이션이 액세스할 수 있는 데이터가 결정됩니다.

동기화된 영역을 열 때 파티션 값을 전달합니다.

동기화 구성 을 사용하여 동기화된 Realm을 초기화합니다. 이를 통해 데이터를 영역과 동기화해야 하는 파티션 값을 지정할 수 있습니다.

처음 로그인 하여 동기화된 Realm 을 열면 사용자를 로그인 하고 원하는 partitionValue 가 있는 사용자의 영역 객체 를 +[RLMRealm realmWithConfig:error:]에 전달합니다.

그러면 장치에서 동기화된 영역 이 열립니다. 영역 은 서버 의 변경 사항을 확인하기 위해 배경 에서 앱과 동기화 를 시도하거나 사용자가 변경한 내용을 업로드하려고 시도합니다.

RLMApp *app = [RLMApp appWithId:YOUR_APP_ID];
// Log in...
RLMUser *user = [app currentUser];
NSString *partitionValue = @"some partition value";
RLMRealmConfiguration *configuration = [user configurationWithPartitionValue:partitionValue];
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration
error:&error];
if (error != nil) {
NSLog(@"Failed to open realm: %@", [error localizedDescription]);
// handle error
} else {
NSLog(@"Opened realm: %@", realm);
// Use realm
}

원하는 파티션 값 이 포함된 로그인한 사용자의 구성 객체를 영역 이니셜라이저에 전달합니다.

영역을 열기 전에 변경 사항을 다운로드할지 여부를 선택적으로 지정할 수 있습니다. 다운로드 동작을 지정하지 않으면 장치에 있는 데이터가 포함된 영역이 열리고 백그라운드에서 변경 사항 동기화를 시도합니다.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Store a configuration that consists of the current user,
// authenticated to this instance of your app. If there is no
// user, your code should log one in.
let user = app.currentUser
let partitionValue = "some partition value"
var configuration = user!.configuration(partitionValue: partitionValue)
// Open the database with the user's configuration.
let syncedRealm = try! Realm(configuration: configuration)
print("Successfully opened the synced realm: \(syncedRealm)")

버전 10.23.0의 새로운 기능

동기화되지 않은 Realm이 다른 기기 및 Atlas App Services 백엔드와 동기화를 시작하려면 writeCopy(configuration: ) 메서드를 사용하여 동기화 구성에 사용할 동기화되지 않은 Realm의 복사본을 만들 수 있습니다. 아래 예에서는 동기화 구성과 함께 사용할 수 있는 동기화되지 않은 Realm 파일의 복사본과 기존 데이터가 모두 포함되어 있습니다.

동기화에 사용할 영역을 복사한 후에는 복사본을 동기화된 영역으로 열 수 있습니다. 동기화된 Realm에 대한 모든 변경 사항은 Realm 파일에 반영되며 다른 장치와 App Services 백엔드에도 전파됩니다.

참고

파티션 기반 동기화만 해당

이 방법은 비동기화 영역과 파티션 기반 동기화 간의 변환만 지원합니다. 앱에서 Flexible Sync를 사용하는 경우 영역의 객체를 수동으로 반복하고 다른 영역으로 복사해야 합니다.

앱이 async/await 컨텍스트에서 Realm에 액세스하는 경우 코드를 @MainActor(으)로 표시하여 스레드 관련 충돌을 방지합니다.

try await convertLocalRealmToSyncedRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func convertLocalRealmToSyncedRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to open as a synced realm
let syncUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the sync user's realm
var syncConfig = syncUser.configuration(partitionValue: "Your Partition Value")
syncConfig.objectTypes = [QsTask.self]
// Prepare the configuration for the user whose local realm you
// want to convert to a synced realm
var localConfig = Realm.Configuration()
localConfig.objectTypes = [QsTask.self]
// For this example, add some data to the local realm
// before copying it. No need to do this if you're
// copying a realm that already contains data.
let localRealm = addExampleData(config: localConfig)
// Create a copy of the local realm that uses the
// sync configuration. All the data that is in the
// local realm is available in the synced realm.
try! localRealm.writeCopy(configuration: syncConfig)
// Open the synced realm we just created from the local realm
let syncedRealm = try await Realm(configuration: syncConfig)
// Access the Task objects in the synced realm to see
// that we have all the data we expect
let syncedTasks = syncedRealm.objects(QsTask.self)
var frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("Synced realm opens and contains this many tasks: \(frodoSyncedTasks.count)")
// Add a new task to the synced realm, and see it in the task count
let task4 = QsTask(value: ["name": "Send gift basket to Tom Bombadil", "owner": "Frodo"])
try! syncedRealm.write {
syncedRealm.add(task4)
}
frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 4)
print("After adding a task, the synced realm contains this many tasks: \(frodoSyncedTasks.count)")
// Open the local realm, and confirm that it still only contains 3 tasks
let openedLocalRealm = try await Realm(configuration: localConfig)
let localTasks = openedLocalRealm.objects(QsTask.self)
let frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 3)
print("Local realm opens and contains this many tasks: \(frodoLocalTasks.count)")
XCTAssertNotEqual(frodoLocalTasks.count, frodoSyncedTasks.count)
/// Populate the local realm with some data that we'll use in the synced realm.
func addExampleData(config: Realm.Configuration) -> Realm {
// Prepare the configuration for the user whose local realm you
// want to convert to a synced realm
let localConfig = config
// Open the local realm, and populate it with some data before returning it
let localRealm = try! Realm(configuration: localConfig)
let task1 = QsTask(value: ["name": "Keep it secret", "owner": "Frodo"])
let task2 = QsTask(value: ["name": "Keep it safe", "owner": "Frodo"])
let task3 = QsTask(value: ["name": "Journey to Bree", "owner": "Frodo"])
try! localRealm.write {
localRealm.add([task1, task2, task3])
}
return localRealm
}
}

버전 10.23.0의 새로운 기능

동기화된 영역을 동기화되지 않은 영역으로 영구적으로 변경하지 않으려는 경우 동기화 세션을 일시적으로 일시 중지할 수 있습니다. 참조: 동기화 세션 일시 중단 또는 다시 시작.

Realm이 Atlas App Services 백엔드에 동기화되는 것을 영구적으로 중지하려면 writeCopy(configuration: ) 메서드를 사용하여 비동기 구성에 사용할 동기화된 Realm의 복사본을 만들 수 있습니다. 아래 예제에서는 지정한 파일 URL에 기존 데이터가 모두 포함된 Realm 파일의 복사본을 생성합니다.

이 프로세스는 로컬 영역에서 realm_id 을(를) 제거합니다. 속성을 삭제한 것처럼 스키마 버전을 증가시켜야 합니다.

동기화 없이 사용할 영역을 복사한 후에는 복사본을 동기화되지 않은 영역으로 열 수 있습니다. 동기화되지 않은 Realm에 대한 모든 변경 사항은 로컬 Realm 파일에만 반영됩니다. 다른 기기나 App Services 백엔드에 변경 사항이 전파되지 않습니다.

참고

파티션 기반 동기화만 해당

이 방법은 비동기화 영역과 파티션 기반 동기화 간의 변환만 지원합니다. 앱에서 Flexible Sync를 사용하는 경우 영역의 객체를 수동으로 반복하고 다른 영역으로 복사해야 합니다.

앱이 async/await 컨텍스트에서 Realm에 액세스하는 경우 코드를 @MainActor(으)로 표시하여 스레드 관련 충돌을 방지합니다.

try await convertSyncedRealmToLocalRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func convertSyncedRealmToLocalRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to open as a local realm
let syncUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the seed user's realm
var syncConfig = syncUser.configuration(partitionValue: "Some Partition Value")
syncConfig.objectTypes = [QsTask.self]
// Open the realm with the Sync user's config, downloading
// any remote changes before opening.
let syncedRealm = try await Realm(configuration: syncConfig, downloadBeforeOpen: .always)
print("Successfully opened realm: \(syncedRealm)")
// Verify the data we expect in the realm
// The synced realm we are copying contains 3 tasks whose owner is "Frodo"
let syncedTasks = syncedRealm.objects(QsTask.self)
var frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("Synced realm opens and contains this many tasks: \(frodoSyncedTasks.count)")
// Construct an output file path for the local Realm
guard let outputDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
// Append a file name to complete the path
let localRealmFilePath = outputDir.appendingPathComponent("local.realm")
// Construct a local realm configuration
var localConfig = Realm.Configuration()
localConfig.objectTypes = [QsTask.self]
localConfig.fileURL = localRealmFilePath
// `realm_id` will be removed in the local realm, so we need to bump
// the schema version.
localConfig.schemaVersion = 1
// Check to see if there is already a realm at the local realm file path. If there
// is already a realm there, delete it.
if Realm.fileExists(for: localConfig) {
try Realm.deleteFiles(for: localConfig)
print("Successfully deleted existing realm at path: \(localRealmFilePath)")
} else {
print("No file currently exists at path")
}
// Make a copy of the synced realm that uses a local configuration
try syncedRealm.writeCopy(configuration: localConfig)
// Try opening the realm as a local realm
let localRealm = try await Realm(configuration: localConfig)
// Verify that the copied realm contains the data we expect
let localTasks = localRealm.objects(QsTask.self)
var frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 3)
print("Local realm opens and contains this many tasks: \(frodoLocalTasks.count)")
let task = QsTask(value: ["name": "Send gift basket to Tom Bombadil", "owner": "Frodo"])
try! localRealm.write {
localRealm.add(task)
}
frodoLocalTasks = localTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoLocalTasks.count, 4)
print("After adding a task, the local realm contains this many tasks: \(frodoLocalTasks.count)")
frodoSyncedTasks = syncedTasks.where { $0.owner == "Frodo" }
XCTAssertEqual(frodoSyncedTasks.count, 3)
print("After writing to local realm, synced realm contains this many tasks: \(frodoSyncedTasks.count)")
XCTAssertNotEqual(frodoLocalTasks.count, frodoSyncedTasks.count)
}

App Services Realm Mobile Sync 모드를 파티션 기반 동기화에서 Flexible Sync로 마이그레이션할 수 있습니다. 마이그레이션은 애플리케이션 코드를 변경할 필요가 없는 자동 프로세스입니다. 자동 마이그레이션을 사용하려면 Realm Swift SDK 버전 10.40.0 이상이 필요합니다.

마이그레이션하면 기존 App Services 사용자 및 인증 구성을 유지할 수 있습니다. Flexible Sync는 더욱 다양한 권한 구성 옵션과 보다 세분화된 데이터 동기화를 제공합니다.

App Services App을 파티션 기반 동기화에서 Flexible Sync로 마이그레이션하는 방법에 대한 자세한 내용은 Device Sync 모드 마이그레이션을 참조하세요.

파티션 기반 동기화에서 Flexible Sync로 자동 마이그레이션할 때는 클라이언트 코드를 변경할 필요가 없습니다. 그러나 이 기능을 지원하기 위해 Realm은 다음을 통해 두 동기화 모드의 차이점을 자동으로 처리합니다.

  • partitionKey == partitionValue 인 각 Realm 객체 유형에 대해 Flexible Sync 구독을 자동으로 생성합니다.

  • 필드가 아직 없는 경우 모든 객체에 partitionKey 필드를 삽입합니다. 이는 자동 Flexible Sync 구독에 필요합니다.

마이그레이션 후 클라이언트 코드를 업데이트해야 하는 경우 클라이언트 코드베이스를 업데이트하여 숨겨진 마이그레이션 기능을 제거하는 것이 좋습니다. 다음과 같은 경우 클라이언트 코드베이스를 업데이트해야 할 수 있습니다.

  • 클라이언트 코드베이스에서 새 모델을 추가하거나 모델을 변경하는 경우

  • Realm 객체를 읽거나 쓰는 기능을 추가하거나 변경하는 경우

  • 동기화하는 데이터를 보다 세밀하게 제어하려는 경우

파티션 기반 동기화 클라이언트 코드를 Flexible Sync를 사용하도록 변환하려면 다음과 같이 변경하세요.

  • 동기화된 Realm을 여는 flexibleSyncConfiguration() 로 전환합니다.

  • Flexible Sync 구독에 사용할 관련 속성을 객체 모델에 추가합니다. 예를 들어 ownerId 속성을 추가하여 사용자가 자신의 데이터만 동기화할 수 있도록 할 수 있습니다.

  • 자동 Flexible Sync 구독을 제거하고 관련 구독을 수동으로 생성합니다.

이러한 전략에 대한 데이터 모델링 방법의 예를 포함하여 Flexible Sync 권한 전략의 예는 Device Sync 권한 가이드를 참조하세요.

파티션 기반 동기화에서 Flexible Sync로 마이그레이션하면 Realm은 앱에 대한 숨겨진 Flexible Sync 구독을 자동으로 생성합니다. 다음에 구독을 추가하거나 변경할 때 다음을 수행하는 것이 좋습니다.

  1. 자동으로 생성된 구독을 제거합니다.

  2. 클라이언트 코드베이스에 관련 구독을 수동으로 추가합니다.

이를 통해 향후 반복 및 디버깅을 위해 코드베이스에서 모든 구독 로직을 함께 볼 수 있습니다.

자동으로 생성된 Flexible Sync 구독에 대한 자세한 내용은 클라이언트 앱을 Flexible Sync로 마이그레이션을 참조하세요.

돌아가기

Atlas로 데이터 스트리밍