Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

Realm 파일 번들 - Swift SDK

이 페이지의 내용

  • 개요
  • 번들링을 위한 Realm 파일 만들기
  • 프로덕션 애플리케이션에 Realm 파일 번들
  • 번들 Realm 파일에서 Realm 열기

참고

동기화된 Realm 번들

Swift SDK 버전 10.23.0 동기화된 Realm을 번들로 묶는 기능을 도입했습니다. 10.23.0 이전 버전, 로컬 Realm만 번들로 묶을 수 있습니다.

Realm은 Realm 파일 번들 을 지원합니다. Realm 파일을 번들로 제공하면 애플리케이션 다운로드에 데이터베이스와 모든 해당 데이터가 포함됩니다.

이를 통해 사용자는 초기 데이터 설정하다 로 애플리케이션을 처음 시작할 수 있습니다. 동기화된 Realm의 경우 번들을 사용하면 사용자가 애플리케이션 을 처음 열 때 시간이 오래 걸리는 초기 다운로드 를 방지할 수 있습니다. 대신 사용자는 번들 파일 을 생성한 이후 발생한 동기화된 변경 사항만 다운로드 하면 됩니다.

중요

동기화된 Realm 번들

백엔드 애플리케이션 에서 Flexible Sync 를 사용하는 경우 사용자가 번들 영역 파일 을 처음 열 때 클라이언트 재설정 을 경험할 수 있습니다. 이는 클라이언트 최대 오프라인 시간 이 활성화된 경우(클라이언트 최대 오프라인 시간은 기본값 활성화되어 있음) 발생할 수 있습니다. 사용자가 처음 동기화하기 전에 번들 영역 파일 이 클라이언트 최대 오프라인 시간 설정에 지정된 일수보다 오래 생성된 경우 사용자는 클라이언트 재설정 을 경험하게 됩니다.

클라이언트 재설정을 수행하는 애플리케이션은 애플리케이션 백엔드에서 영역의 전체 상태를 다운로드합니다. 이렇게 하면 Realm 파일을 번들로 제공할 때 얻을 수 있는 이점이 무효화됩니다. 클라이언트 재설정을 방지하고 Realm 파일 번들의 이점을 보존하려면 다음을 수행합니다.

  • 동기화된 영역을 번들로 제공하는 애플리케이션에서는 클라이언트 최대 오프라인 시간을 사용하지 않도록 합니다.

  • 애플리케이션에서 클라이언트 최대 오프라인 시간을 사용하는 경우 애플리케이션 다운로드에 항상 최근에 동기화된 Realm 파일이 포함되어 있는지 확인하세요. 각 애플리케이션 버전마다 새 파일을 생성하고 클라이언트 최대 오프라인 시간 (일)을 초과하는 버전이 최신 상태로 유지되지 않도록 합니다.

Realm 파일을 생성하고 애플리케이션과 함께 번들로 제공하려면 다음과 같이 하세요:

  1. 번들로 제공하려는 데이터가 포함 된 Realm 파일을 만듭니다 .

  2. 프로덕션 애플리케이션에 Realm 파일을 번들로 제공합니다.

  3. 프로덕션 애플리케이션 의 번들 자산 파일 에서 Realm을 엽니다. 동기화된 영역의 경우 파티션 키를 제공해야 합니다.

  1. 애플리케이션의 데이터 모델을 공유하는 임시 Realm 앱을 빌드합니다.

  2. Realm을 열고 번들로 제공하려는 데이터를 추가합니다. 동기화된 Realm을 사용하는 경우 Realm이 완전히 동기화될 때까지 기다립니다.

  3. writeCopy(configuration:) 메서드를 사용하여 영역을 새 파일에 복사합니다:

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

try await createBundledRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func createBundledRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in the user whose realm you want to copy for bundling
let seedUser = try await app.login(credentials: Credentials.anonymous)
// Create a configuration to open the seed user's realm
var config = seedUser.configuration(partitionValue: "Partition You Want to Bundle")
config.objectTypes = [Todo.self]
// Open the realm with the seed user's config
let realm = try await Realm(configuration: config, downloadBeforeOpen: .always)
print("Successfully opened realm: \(realm)")
// Verify there is a todo object in the realm whose
// owner's name is "Daenerys". When we open the bundled
// realm later, we should see the same result.
let todos = realm.objects(Todo.self)
let daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 1)
// Specify an output directory for the bundled realm
// We're using FileManager here for tested code examples,
// but this could be a static directory on your computer.
guard let outputDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
// Append a file name to complete the path
let bundleRealmFilePath = outputDir.appendingPathComponent("seed.realm")
// Update the config file path to the path where you want to save the bundled realm
config.fileURL = bundleRealmFilePath
// Check to see if there is already a realm at the bundled realm file path. If there
// is already a realm there, delete it.
if Realm.fileExists(for: config) {
try Realm.deleteFiles(for: config)
print("Successfully deleted existing realm at path: \(bundleRealmFilePath)")
} else {
print("No file currently exists at path")
}
// Write a copy of the realm at the URL we specified
try realm.writeCopy(configuration: config)
// Verify that we successfully made a copy of the realm
XCTAssert(FileManager.default.fileExists(atPath: bundleRealmFilePath.path))
print("Successfully made a copy of the realm at path: \(bundleRealmFilePath)")
// Verify that opening the realm at the new file URL works.
// Don't download changes, because this can mask a copy
// that does not contain the expected data.
let copiedRealm = try await Realm(configuration: config, downloadBeforeOpen: .never)
print("Successfully opened realm: \(realm)")
// Verify that the copied realm contains the data we expect
let copiedTodos = copiedRealm.objects(Todo.self)
let daenerysCopiedTodos = copiedTodos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysCopiedTodos.count, 1)
print("Copied realm opens and contains this many tasks: \(daenerysCopiedTodos.count)")
}

writeCopy(configuration: ) 는 복사하기 전에 영역 을 가능한 가장 작은 크기로 자동 압축합니다.

참고

동기화된 Realm과 로컬 전용 Realm의 차이점

위의 예에서는 SyncConfiguration 를 사용하여 동기화된 Realm을 구성합니다. 로컬 Realm의 복사본을 만들려면 대신 RealmConfiguration 로 Realm을 구성합니다.

이제 초기 데이터가 포함된 Realm의 복사본이 있으므로 이를 프로덕션 애플리케이션과 번들로 제공합니다. 이는 광범위한 수준에서 다음을 수반합니다.

  1. 프로덕션 앱과 정확히 동일한 데이터 모델을 사용하여 새 프로젝트를 만듭니다. Realm을 열고 번들로 제공하려는 데이터를 추가합니다. Realm 파일은 크로스 플랫폼이므로 macOS 앱에서 이 작업을 수행할 수 있습니다.

  2. Realm 파일의 압축된 복사본을 프로덕션 앱의 Xcode 프로젝트 네비게이터로 드래그합니다.

  3. Xcode에서 앱 타겟의 Build Phases 탭으로 이동합니다. Copy Bundle Resources 빌드 단계에 Realm 파일을 추가합니다.

  4. 이 점 에서 앱 은 번들로 제공되는 영역 파일 에 액세스 할 수 있습니다.Bundle.main.path(forResource:ofType)를 사용하여 경로를 찾습니다.

Realm.Configuration readOnly 속성이 true 로 설정된 경우 번들 경로에서 Realm을 직접 열 수 있습니다. 번들 Realm을 수정하려면 먼저 구성에서 번들 Realm의 URL로 seedFilePath 를 설정하여 번들 파일을 앱의 문서 폴더에 복사합니다.

마이그레이션 샘플 앱 보기 번들 로컬 Realm을 사용하는 완전한 작동 앱입니다.

이제 프로덕션 애플리케이션에 포함된 Realm의 복사본이 있으므로 이를 사용하려면 코드를 추가해야 합니다. 번들 파일에서 Realm을 열도록 Realm을 구성할 때 SeedFilePath 메서드를 사용합니다.

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

try await openBundledSyncedRealm()
// Opening a realm and accessing it must be done from the same thread.
// Marking this function as `@MainActor` avoids threading-related issues.
@MainActor
func openBundledSyncedRealm() async throws {
let app = App(id: YOUR_APP_SERVICES_APP_ID)
// Log in an app user who will use the bundled realm
let user = try await app.login(credentials: Credentials.anonymous)
// Create a configuration for the app user's realm
// This should use the same partition value as the bundled realm
var newUserConfig = user.configuration(partitionValue: "Partition You Want to Bundle")
newUserConfig.objectTypes = [Todo.self]
// Find the path of the seed.realm file in your project
let realmURL = Bundle.main.url(forResource: "seed", withExtension: ".realm")
print("The bundled realm URL is: \(realmURL)")
// When you use the `seedFilePath` parameter, this copies the
// realm at the specified path for use with the user's config
newUserConfig.seedFilePath = realmURL
// Open the synced realm, downloading any changes before opening it.
// This starts with the existing data in the bundled realm, but checks
// for any updates to the data before opening it in your application.
let realm = try await Realm(configuration: newUserConfig, downloadBeforeOpen: .always)
print("Successfully opened the bundled realm")
// Read and write to the bundled realm as normal
let todos = realm.objects(Todo.self)
// There should be one todo whose owner is Daenerys because that's
// what was in the bundled realm.
var daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 1)
print("The bundled realm has \(daenerysTodos.count) todos whose owner is Daenerys")
// Write as usual to the realm, and see the object count increment
let todo = Todo(value: ["name": "Banish Ser Jorah", "owner": "Daenerys", "status": "In Progress"])
try realm.write {
realm.add(todo)
}
print("Successfully added a todo to the realm")
daenerysTodos = todos.where { $0.owner == "Daenerys" }
XCTAssertEqual(daenerysTodos.count, 2)
}

참고

동기화된 Realm과 로컬 전용 Realm의 차이점

위의 예에서는 SyncConfiguration 를 사용하여 동기화된 Realm을 구성합니다. 로컬 Realm의 복사본을 만들려면 대신 Realm.Configuration 로 Realm을 구성합니다.

돌아가기

Realm 삭제