As an iOS developer, I often find myself in situations where I want to quickly prototype the implementation of an abstract data layer. Evolving from a simple, probably inefficient and temporary in-memory solution, to a more robust and efficient disk-based solution, that is persisted across app launches.
However committing right away to a suitable configuration for the Realm database is at times a bit overwhelming. A possibility to defer the configuration to a later stage, and transition easily to it later, would be a great help.
And then there are those times when a custom configuration is just redundant for small apps, and a simple, default configuration would suffice. In such scenarios the default Realm comes to the rescue.
What is Default Realm?
It is a realm that is created automatically by the RealmSwift
framework when the module is imported in any Swift file.
import RealmSwift
// The default Realm is created automatically
It is a disk-based Realm, which is persisted to disk and saves the data across app launches. An explicit configuration is not required to create the default Realm and the initializer does not require any arguments.
Usage
To use the default Realm, you need to import the RealmSwift
module in your Swift file and initialize the Realm instance, without any arguments.
import RealmSwift
do {
let defaultRealm: Realm = try Realm()
// Use the default Realm here
print("Opened default Realm: \(defaultRealm)")
} catch {
// Handle error opening the default Realm
print("Error opening default Realm: \(error)")
}
Successfully opening the default Realm will print the Realm instance to the console.
Opened default Realm: Realm(rlmRealm: <RLMRealm: 0x6000035180b0>)
Default Configuration
It is initialized with the default configuration, which includes the following settings:
File URL:
On iOS, the default Realm is created in the
Documents
directory of the app’s sandbox. On macOS, the default Realm is created in theApplication Support
directory of the app’s sandbox.In both cases, the Realm file is named
default.realm
.Realm’s auxiliary files are stored in the same directory. The directory tree looks like this:
Documents/ ├── default.realm ├── default.realm.lock ├── default.realm.management │ ├── access_control.control.mx │ ├── access_control.new_commit.cv │ ├── access_control.pick_writer.cv │ ├── access_control.versions.mx │ └── access_control.write.mx └── default.realm.note
In-Memory Identifier:
Since it is a disk-based Realm, the
inMemoryIdentifier
property is not set.Sync Configuration:
It is not configured for sync, so the
syncConfiguration
property is not set.Encryption Key:
It does not have encryption enabled, so the
encryptionKey
property is not set.Read-Only:
Read and write operations are allowed. The
readOnly
property is set tofalse
.Schema Version:
The schema version is
0
.Migration Block:
It does not have a migration block set.
Delete Realm If Migration Needed:
The
deleteRealmIfMigrationNeeded
property is set tofalse
, implying that the Realm is not deleted if a migration is needed.
Beware that an exception is thrown if a migration is needed.Should Compact On Launch:
The
shouldCompactOnLaunch
property is set tonil
, implying that the Realm is not compacted on launch.Object Types:
It does not have any object types defined.
Seed File Path:
The
seed
property is not set, implying that the Realm is not seeded with data.
Custom Configuration
Although an explicit configuration is not required to create the default Realm, in times when you want to use the default Realm as the primary storage for your app, you can create a custom configuration.
The following are some scenarios where you might want to create a custom configuration for the default Realm:
Custom File URL:
You want to store the Realm file in a custom location.
Custom Schema Version:
You want to set a schema version for the Realm in order to perform migrations.
Custom Migration Block:
You want to define a migration block to handle schema migrations.
Custom Object Types:
You want to define custom object types for the Realm.
Custom Encryption Key:
You want to encrypt the Realm file.
To achieve this, you need to set the defaultConfiguration
property of the Realm.Configuration
struct to a custom configuration.
The following code snippet demonstrates the same:
import RealmSwift
// Define a custom URL for the default Realm
let documentsDirectoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let defaultRealmCustomURL: URL = documentsDirectoryURL.appending(path: "custom.realm")
// Define a custom configuration for the default Realm
let customConfig: Realm.Configuration = .init(
fileURL: defaultRealmCustomURL,
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 1 {
// Perform migration
}
}
)
// Set the default configuration to the custom configuration
Realm.Configuration.defaultConfiguration = customConfig
do {
let defaultRealm: Realm = try Realm()
// Use the default Realm here
print("Opened default Realm with custom configuration: \(defaultRealm)")
} catch {
// Handle error opening the default Realm
print("Error opening default Realm: \(error)")
}
Successfully opening the default Realm with a custom configuration will print the Realm instance to the console.
Opened default Realm with custom configuration: Realm(rlmRealm: <RLMRealm: 0x60000350cd10>)
Use Cases
With a relatively simple and limited out-of-the-box configuration, the default Realm is suitable for the following use cases:
Quick Prototyping
When building a prototype or test app, you may want to jump quickly into development without worrying about database configuration. The default Realm is a good choice for this scenario. Once you have a working prototype, you can migrate to a custom Realm configuration if and as needed.
Single-User iOS Applications
If your iOS application is for a single user and does not require complex data relationships, the default Realm may be sufficient. This could include personal note-taking apps, to-do list apps, or a game that stores player scores and settings.
Simple Data Models
Apps that deal with simple and unconnected data models can benefit from the default Realm. This is because all your data is stored in one place, eliminating the need for managing multiple realms.
Learning and Tutorials
If you are learning how to use the Realm database or are following a tutorial, using the default Realm is a simple way to get started. You don’t have to worry about creating and managing configurations, allowing you to focus on learning the basics of Realm.
Snippets
Here are some useful snippets.
Print Default Realm File Path
print("Default Realm file path: \((try? Realm())?.configuration.fileURL)")
Custom URL for Default Realm
let documentsDirectoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let defaultRealmCustomURL: URL = documentsDirectoryURL.appending(path: "custom.realm")
let customConfiguration: Realm.Configuration = .init(fileURL: defaultRealmCustomURL)
Realm.Configuration.defaultConfiguration = customConfiguration