When you open a realm, you can pass a Realm.Configuration that specifies additional details about how to configure the realm file. This includes things like:
Pass a fileURL or in-memory identifier to customize how the realm is stored on device
Provide a logged-in user and Sync details to use Sync with the realm
Specify the realm use only a subset of your app's classes
Whether and when to compact a realm to reduce its file size
Pass an encryption key to encrypt a realm
Provide a schema version or migration block when making schema changes
You can open a non-synced local realm with several different configuration options:
No configuration - i.e. default configuration
Specify a file URL for the realm
Open the realm only in memory, without saving a file to the file system
Copy a synced realm to use without Sync
You can open the default realm with +[RLMRealm defaultRealm].
You can also pass a RLMRealmConfiguration object to +[RLMRealm realmWithConfiguration:error:] to open a realm at a specific file URL, in memory, or with Device Sync.
You can set the default realm configuration by passing a RLMRealmConfiguration instance to +[RLMRealmConfiguration setDefaultConfiguration:].
RLMRealm *defaultRealm = [RLMRealm defaultRealm];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];
You can open a realm with the Realm() initializer. If you omit the Realm.Configuration parameter, you will open the default realm.
You can set the default realm configuration by assigning a new Realm.Configuration instance to the Realm.Configuration.defaultConfiguration class property.
let defaultRealm = try! Realm()let username = "GordonCole"var config = Realm.Configuration.defaultConfigurationconfig.fileURL!.deleteLastPathComponent()config.fileURL!.appendPathComponent(username)config.fileURL!.appendPathExtension("realm")let realm = try! Realm(configuration: config)
Changed in version 10.46.0: Supports opening a synced database in memory.
You can open a realm entirely in memory, which will not create a .realm
file or its associated auxiliary files. Instead the SDK stores objects in memory while the realm is open and discards them immediately when all instances are closed.
Note that this property cannot be combined with fileURL
. In Swift SDK versions 10.45.3 and earlier, this property cannot be combined with syncConfiguration
.
Set the inMemoryIdentifier property of the realm configuration.
NSString *identifier = @"MyRealm";RLMRealmConfiguration *configuration = [[RLMRealmConfiguration alloc] init];configuration.inMemoryIdentifier = identifier;RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];
Set the inMemoryIdentifier property of the realm configuration.
let identifier = "MyRealm"let config = Realm.Configuration( inMemoryIdentifier: identifier)let realm = try! Realm(configuration: config)
Important
When all in-memory realm instances with a particular identifier go out of scope, Realm deletes all data in that realm. To avoid this, hold onto a strong reference to any in-memory realms during your app's lifetime.
You can use Swift's async/await syntax to open a MainActor-isolated realm, or specify an actor when opening a realm asynchronously:
@MainActorfunc mainThreadFunction() async throws { let realm1 = try await Realm() let realm2 = try await Realm(actor: MainActor.shared) try await useTheRealm(realm: realm1)}
Or you can define a custom realm actor to manage all of your realm operations:
actor RealmActor { 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 } }
An actor-isolated realm may be used with either local or global actors.
@globalActor actor BackgroundActor: GlobalActor { static var shared = BackgroundActor()}@BackgroundActorfunc backgroundThreadFunction() async throws { 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" ]) } let todoCount = realm.objects(Todo.self).count print("The number of Realm objects is: \(todoCount)")}@MainActorfunc mainThreadFunction() async throws { try await backgroundThreadFunction()}
For more information about working with actor-isolated realms, refer to Use Realm with Actors - Swift SDK.
There is no need to manually close a realm in Swift or Objective-C. When a realm goes out of scope and is removed from memory due to ARC , the realm is closed.
To handle errors when accessing a realm, provide an NSError
pointer to the error
parameter:
NSError *error = nil;RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];if (!realm) { return;}
To handle errors when accessing a realm, use Swift's built-in error handling mechanism:
do { let realm = try Realm() } catch let error as NSError { }
Tip Operating with Low Memory Constraints
Some applications, such as watchOS apps and iOS app extensions, have tight constraints on their memory footprints. To optimize your data model for low-memory environments, open the realm with a subset of classes.
By default, the Swift SDK automatically adds all RLMObject- and RLMEmbeddedObject-derived classes in your executable to the realm schema. You can control which objects get added by setting the objectClasses property of the RLMRealmConfiguration object.
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];config.objectClasses = @[[Task class]];NSError *error = nil;RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:&error];if (error != nil) { } else { }
By default, the Swift SDK automatically adds all Object- and EmbeddedObject-derived classes in your executable to the realm schema. You can control which objects get added by setting the objectTypes property of the Realm.Configuration object.
var config = Realm.Configuration.defaultConfigurationconfig.objectTypes = [Dog.self]let realm = try! Realm(configuration: config)
You might define properties whose values are initialized using Realm APIs. For example:
class SomeSwiftType { let persons = try! Realm().objects(Person.self) }
If this initialization code runs before you set up your Realm configurations, you might get unexpected behavior. For example, if you set a migration block for the default realm configuration in applicationDidFinishLaunching()
, but you create an instance of SomeSwiftType
before applicationDidFinishLaunching()
, you might be accessing your realm before it has been correctly configured.
To avoid such issues, consider doing one of the following:
Defer instantiation of any type that eagerly initializes properties using Realm APIs until after your app has completed setting up its realm configurations.
Define your properties using Swift's lazy
keyword. This allows you to safely instantiate such types at any time during your application's lifecycle, as long as you do not attempt to access your lazy
properties until after your app has set up its realm configurations.
Only initialize your properties using Realm APIs that explicitly take in user-defined configurations. You can be sure that the configuration values you are using have been set up properly before they are used to open realms.
By default, iOS 8 and above encrypts app files using NSFileProtection
whenever the device is locked. If your app attempts to access a realm while the device is locked, you might see the following error:
open() failed: Operation not permitted
To handle this, downgrade the file protection of the folder containing the Realm files. A less strict protection level like NSFileProtectionCompleteUntilFirstUserAuthentication allows file access even when the device is locked.
TipIf you reduce iOS file encryption, consider using Realm's built-in encryption to secure your data instead.
This example shows how to apply a less strict protection level to the parent directory of the default realm.
let realm = try! Realm()let folderPath = realm.configuration.fileURL!.deletingLastPathComponent().pathtry! FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication], ofItemAtPath: folderPath)
Realm may create and delete auxiliary files at any time. Instead of downgrading file protection on the files, apply it to the parent folder. This way, the file protection applies to all relevant files regardless of creation time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4