Realm 구성 및 열기 - Swift SDK
이 페이지의 내용
영역 을 열 때Realm 파일을 구성하는 방법에 대한 추가 세부 정보를 지정하는 영역 을 전달할 수 파일. 여기에는 다음과 같은 것이 포함됩니다.
fileURL 또는 인메모리 식별자를 전달하여 기기에서 영역이 저장되는 방식을 사용자 지정합니다.
realm과 함께 동기화를 사용하기 위해 로그인한 사용자와 동기화 세부 정보 제공
앱 클래스의 하위 집합만 사용하도록 realm 지정
realm의 파일 크기를 줄이기 위해 언제 그리고 어떻게 압축할지 여부
realm을 암호화하기 위한 암호화 키 전달
스키마 변경 시 스키마 버전 또는 마이그레이션 블록 제공
팁
다음도 참조하세요.
이 페이지에서는 데이터를 동기화하지 않는 영역 파일을 여는 방법에 대해 설명합니다. Device Sync를 사용하여 다른 기기와 데이터를 동기화하려면 구성 및 동기화된 Realm 열기를 참조하세요.
동기화 없이 Realm 열기
여러 가지 다른 구성 옵션을 사용하여 동기화되지 않은 로컬 영역을 열 수 있습니다.
구성 없음 - i.e. 기본 구성
영역의 파일 URL 지정
파일 시스템에 파일을 저장하지 않고 메모리에서만 영역 열기
동기화된 영역을 복사하여 동기화 없이 사용하기
Realm 또는 File URL에서 기본 Realm 열기
기본값 Realm은 +[ 영역 defaultRealm]으로 열 수 있습니다.
RLMRealmConfiguration 객체 를 +[RLMRealm 영역 :error:] 에 전달하여 특정 파일 URL, 메모리 또는 Device Sync 를 사용하여 Realm을 열 수도 있습니다.
RLMRealmConfiguration 인스턴스 를 +[ 영역 setDefaultConfiguration:]에 전달하여 기본값 Realm 구성을 설정하다 수 있습니다.
// Open the default realm RLMRealm *defaultRealm = [RLMRealm defaultRealm]; // Open the realm with a specific file URL, for example a username NSString *username = @"GordonCole"; RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration]; configuration.fileURL = [[[configuration.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:username] URLByAppendingPathExtension:@"realm"]; NSError *error = nil; RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:&error];
Realm() 이니셜라이저 를 사용하여 Realm을 열 수 있습니다. Realm.Configuration 매개변수를 생략하면 기본 Realm이 열립니다.
새 Realm.Configuration 인스턴스를 Realm.Configuration.defaultConfiguration 클래스 속성에 할당하여 기본 영역 구성을 설정할 수 있습니다.
// Open the default realm let defaultRealm = try! Realm() // Open the realm with a specific file URL, for example a username let username = "GordonCole" var config = Realm.Configuration.defaultConfiguration config.fileURL!.deleteLastPathComponent() config.fileURL!.appendPathComponent(username) config.fileURL!.appendPathExtension("realm") let realm = try! Realm(configuration: config)
In-Memory Realm 열기
버전 10.46.0에서 변경됨: 메모리에서 동기화된 데이터베이스 열기를 지원합니다.
메모리에서 영역을 완전히 열어도 .realm
파일이나 관련 보조 파일이 생성되지 않습니다. 대신 SDK는 영역이 열려 있는 동안 메모리에 객체를 저장하고 모든 인스턴스가 닫히면 즉시 삭제합니다.
이 속성은 fileURL
에 결합할 수 없습니다. Swift SDK 버전 10.45.3 및 이전 버전에서는 이 속성을 syncConfiguration
버전과 결합할 수 없습니다.
영역 구성의 inMemoryIdentifier 속성을 설정합니다.
// Open the realm with a specific in-memory identifier. NSString *identifier = @"MyRealm"; RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init]; configuration.inMemoryIdentifier = identifier; // Open the realm RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];
영역 구성의 inMemoryIdentifier 속성을 설정합니다.
// Open the realm with a specific in-memory identifier. let identifier = "MyRealm" let config = Realm.Configuration( inMemoryIdentifier: identifier) // Open the realm let realm = try! Realm(configuration: config)
중요
특정 식별자를 가진 모든 인메모리 영역 인스턴스가 범위를 벗어나면 영역은 해당 영역의 모든 데이터를 삭제합니다. 이를 방지하려면 앱의 수명 동안 모든 인메모리 영역에 대한 강력한 참조를 유지합니다.
Swift 동시성 기능으로 Realm 열기
Swift의 비동기/대기 구문을 사용하여 메인 행위자로 격리된 영역을 열거나 비동기적으로 영역을 열 때 행위자를 지정할 수 있습니다.
func mainThreadFunction() async throws { // These are identical: the async init produces a // MainActor-isolated Realm if no actor is supplied let realm1 = try await Realm() let realm2 = try await Realm(actor: MainActor.shared) try await useTheRealm(realm: realm1) }
또는 사용자 지정 영역 행위자를 정의하여 모든 영역 작업을 관리할 수 있습니다.
actor RealmActor { // An implicitly-unwrapped optional is used here to let us pass `self` to // `Realm(actor:)` within `init` var realm: Realm! init() async throws { realm = try await Realm(actor: self) } var count: Int { realm.objects(Todo.self).count } func createTodo(name: String, owner: String, status: String) async throws { try await realm.asyncWrite { realm.create(Todo.self, value: [ "_id": ObjectId.generate(), "name": name, "owner": owner, "status": status ]) } } func getTodoOwner(forTodoNamed name: String) -> String { let todo = realm.objects(Todo.self).where { $0.name == name }.first! return todo.owner } struct TodoStruct { var id: ObjectId var name, owner, status: String } func getTodoAsStruct(forTodoNamed name: String) -> TodoStruct { let todo = realm.objects(Todo.self).where { $0.name == name }.first! return TodoStruct(id: todo._id, name: todo.name, owner: todo.owner, status: todo.status) } func updateTodo(_id: ObjectId, name: String, owner: String, status: String) async throws { try await realm.asyncWrite { realm.create(Todo.self, value: [ "_id": _id, "name": name, "owner": owner, "status": status ], update: .modified) } } func deleteTodo(id: ObjectId) async throws { try await realm.asyncWrite { let todoToDelete = realm.object(ofType: Todo.self, forPrimaryKey: id) realm.delete(todoToDelete!) } } func close() { realm = nil } }
액터 분리 realm은 로컬 또는 글로벌 액터와 함께 사용될 수 있습니다.
// A simple example of a custom global actor actor BackgroundActor: GlobalActor { static var shared = BackgroundActor() } func backgroundThreadFunction() async throws { // Explicitly specifying the actor is required for anything that is not MainActor let realm = try await Realm(actor: BackgroundActor.shared) try await realm.asyncWrite { _ = realm.create(Todo.self, value: [ "name": "Pledge fealty and service to Gondor", "owner": "Pippin", "status": "In Progress" ]) } // Thread-confined Realms would sometimes throw an exception here, as we // may end up on a different thread after an `await` let todoCount = realm.objects(Todo.self).count print("The number of Realm objects is: \(todoCount)") } func mainThreadFunction() async throws { try await backgroundThreadFunction() }
행위자 격리형 영역 작업에 대한 자세한 내용은 행위자와 영역 사용 - Swift SDK를 참조하세요.
Realm 닫기
Swift 또는 오브젝티브-C 에서 영역 을 수동으로 닫을 필요가 없습니다. 영역 이 범위를 벗어나면 ARC 으로 인해 메모리에서 제거됩니다. , 영역 이 닫힙니다.
Realm 액세스 시 오류 처리하기
Realm에 액세스할 때 오류를 처리하려면 error
매개변수에 NSError
포인터를 제공합니다.
NSError *error = nil; RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error]; if (!realm) { // Handle error return; } // Use realm
영역 접근 시 오류를 처리하려면 Swift에 내장된 오류 처리 메커니즘을 사용하세요.
do { let realm = try Realm() // Use realm } catch let error as NSError { // Handle error }
Realm에 클래스 하위 집합 제공하기
팁
메모리 제약이 적은 상태에서 작동
watchOS 앱 및 iOS 앱 확장 프로그램과 같은 일부 애플리케이션은 메모리 사용량에 엄격한 제약이 있습니다. 메모리가 부족한 환경에 맞게 데이터 모델을 최적화하려면 클래스의 하위 집합으로 영역을 엽니다.
기본적으로 Swift SDK는 실행 파일의 모든 RLMObject및 RLMEmbeddedObject파생 클래스를 Realm 스키마에 자동으로 추가합니다. RLMRealmConfiguration 객체의 objectClasses 속성을 설정하여 추가되는 객체를 제어할 수 있습니다.
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; // Given a RLMObject subclass called `Task` // Limit the realm to only the Task object. All other // Object- and EmbeddedObject-derived classes are not added. config.objectClasses = @[[Task class]]; NSError *error = nil; RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error]; if (error != nil) { // Something went wrong } else { // Use realm }
기본값 으로 Swift SDK 는 실행 파일의 모든 객체및 포함된객체 파생 클래스를 영역 스키마 에 자동으로 추가합니다. Realm.Configuration 객체 의 objectTypes 속성 을 설정하여 추가되는 객체를 제어할 수 있습니다.
var config = Realm.Configuration.defaultConfiguration // Given: `class Dog: Object` // Limit the realm to only the Dog object. All other // Object- and EmbeddedObject-derived classes are not added. config.objectTypes = [Dog.self] let realm = try! Realm(configuration: config)
Realm API를 이용한 속성 초기화하기
Realm API를 사용하여 값이 초기화되는 속성을 정의할 수 있습니다. 예시:
class SomeSwiftType { let persons = try! Realm().objects(Person.self) // ... }
Realm 구성을 설정하기 전에 초기화 코드를 실행하면 예기치 않은 동작이 발생할 수 있습니다. 예를 들어 applicationDidFinishLaunching()
에서 기본 영역 구성에 대한 마이그레이션 차단을 설정했지만 applicationDidFinishLaunching()
이전에 SomeSwiftType
인스턴스를 생성한 경우 영역이 올바르게 구성되기 전에 영역에 액세스할 수 있습니다.
이러한 문제를 방지하려면 다음 중 하나를 수행하는 것이 좋습니다.
앱이 영역 구성 설정을 완료할 때까지 영역 API를 사용하여 속성을 적극적으로 초기화하는 모든 유형의 인스턴스화를 연기합니다.
Swift의
lazy
키워드를 사용하여 속성을 정의합니다. 이렇게 하면 앱이 영역 구성을 설정하기 전까지는lazy
속성에 액세스하지 않는 한 애플리케이션 라이프사이클 중 언제든지 이러한 유형을 안전하게 인스턴스화할 수 있습니다.사용자 지정 구성을 명시적으로 받아들이는 Realm API를 사용하여 속성만 초기화하세요. 사용 중인 구성 값이 영역을 여는 데 사용되기 전에 제대로 설정되었는지 확인할 수 있습니다.
장치가 잠겨 있을 때 Realm 사용
기본적으로 iOS 8 이상에서는 기기가 잠겨 있을 때마다 NSFileProtection
을(를) 사용하여 앱 파일을 암호화합니다. 기기가 잠겨 있는 동안 앱이 영역에 액세스하려고 하면 다음 오류가 표시될 수 있습니다.
open() failed: Operation not permitted
이 문제를 해결하려면 처리하다 Realm 이 들어 있는 폴더의 파일 보호 기능을 다운그레이드하세요. NSFileProtectionCompleteUntilFirstUserAuthentication 과 같이 덜 엄격한 보호 수준 장치가 잠겨 있어도 파일 액세스 를 허용합니다.
팁
iOS 파일 암호화를 줄이려면 대신 Realm의 기본 제공 암호화를 사용하여 데이터를 보호하는 것이 좋습니다.
이 예시에서는 기본 영역의 상위 디렉토리에 덜 엄격한 보호 수준을 적용하는 방법을 보여줍니다.
let realm = try! Realm() // Get the realm file's parent directory let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().path // Disable file protection for this directory after the user has unlocked the device once try! FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication], ofItemAtPath: folderPath)
Realm은 언제든지 보조 파일을 생성하고 삭제할 수 있습니다. 파일의 파일 보호 기능을 다운그레이드하는 대신 상위 폴더에 적용하세요. 이렇게 하면 생성 시간에 관계없이 모든 관련 파일에 파일 보호가 적용됩니다.