Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

Realm の設定とオープン - Swift SDK

項目一覧

  • 同期なしで Realm を開く
  • デフォルトの Realm または ファイル URL で Realm を開きます
  • インメモリ Realm のオープン
  • Swift 同時実行機能で Realm を開く
  • Realm を閉じる
  • Realm へのアクセス時のエラーの処理
  • Realm へのクラスのサブセットの提供
  • Realm API を使用してプロパティを初期化
  • デバイスがロックされているときに Realm を使用する

Realm を開く際に、Realm ファイルの構成方法に関する追加の詳細を指定する Realm.Configurationを渡すことができます。 これには、次のようなものが含まれます。

  • ファイルURL またはメモリ内識別子を渡して、Realm をデバイスに保存する方法をカスタマイズします

  • Realm との同期を使用するには、ログイン ユーザーと同期の詳細を指定します

  • アプリの クラスのサブセットのみを使用する Realm を指定する

  • ファイル サイズを縮小するためにRealmを圧縮するかどうか、またいつ圧縮するか

  • 暗号化のキーを渡してRealmを暗号化

  • スキーマ変更を行う際に、スキーマのバージョンまたは移行ブロックを指定する

Tip

以下も参照してください。

このページでは、データ を同期しない Realm ファイルを開く方法について説明します。 Device Sync を使用して他のデバイスとデータを同期する場合は、「同期された Realm の構成とオープン」を参照してください。

同期されていないローカル Realm は、いくつかの異なる構成オプションを使用して開くことができます。

  • 構成なし - デフォルト構成

  • Realm のファイル URL の指定

  • ファイルをファイル システムに保存せず、メモリ内のみでRealmを開きます

  • 同期された Realm をコピーして、同期なしで使用する

+[RMRealm defaultRealm] を使用してデフォルトの邦土を開くことができます。

また、 RMRealmConfigurationオブジェクトを+[RMRealm RealmWithConfiguration:error:]に渡して、メモリ内の特定のファイル URL で Realm を開くことも、 Device Sync を使用して開くこともできます。

RMRealmConfiguration インスタンスを+[RMRealmConfiguration 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に割り当てることで、デフォルトの Realm 構成を設定できます クラスのプロパティ

// 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)

バージョン 10.46.0 での変更: メモリ内で同期されたデータベースを開くことをサポートします。

メモリ内でRealm全体を開くことができます。この場合、 .realmファイルやそれに関連する予備ファイルは作成されません。 代わりに、SDK は Realm が開いている間にオブジェクトをメモリに保存し、すべての インスタンスが閉じられるとすぐにそれらを破棄します。

このプロパティはfileURLと組み合わせることはできないことに注意してください。 Swift SDK バージョン 10.45.3 以前では、このプロパティはsyncConfigurationと組み合わせることはできません。

Realm 構成の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];

Realm 構成の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)

重要

特定の識別子を持つすべて のメモリ 内 RealmGo インスタンスが範囲を超えると、Realm はその Realm 内の すべてのデータ を削除し 。これを回避するには、アプリの有効期間中にメモリ内のRealmへの強力な参照を保持します。

Swift の async/await 構文を使用して、mainActor 分離の Realm を開くか、Realm を非同期に開くときにアクターを指定できます。

@MainActor
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)
}

または、すべての Realm 操作を管理するカスタム Realm アクターを定義することもできます。

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
@globalActor actor BackgroundActor: GlobalActor {
static var shared = BackgroundActor()
}
@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)")
}
@MainActor
func mainThreadFunction() async throws {
try await backgroundThreadFunction()
}

アクター分離された Realm の操作の詳細については、「 アクターでRealm を使用する - Swift SDK 」を参照してください。

Swift または Objective-C では、Realm を手動で閉じる必要はありません。 ARM がスコープを超え、メモリから削除された場合 の場合、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

Realm にアクセスするときにエラーを処理するには、Swift に組み込まれているエラー処理メカニズムを使用します。

do {
let realm = try Realm()
// Use realm
} catch let error as NSError {
// Handle error
}

Tip

低メモリ制約での動作

watchOS アプリや iOS アプリ拡張機能などの一部のアプリケーションは、メモリのフットプリントに厳格な制約があります。 低メモリ環境用にデータモデルを最適化するには、クラスのサブセットを使用してRealmを開きます。

デフォルトでは、Swift SDK は 実行可能ファイル内のすべてのRMObjectおよびRRM埋め込みObjectからのクラスを Realm スキーマへの自動的に追加します。 どのオブジェクトを追加するかは、 RMRealmConfiguration オブジェクトの 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 スキーマに自動的に追加します。 どのオブジェクトを追加するかは、 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 を使用して、値が初期化されるプロパティを定義できます。 例:

class SomeSwiftType {
let persons = try! Realm().objects(Person.self)
// ...
}

この初期化コードが Realm 構成を設定する前に実行すると、予期しない動作が発生する可能性があります。 たとえば、 applicationDidFinishLaunching()でデフォルトの Realm 構成の移行ブロックを設定しているが、 applicationDidFinishLaunching()より前にSomeSwiftTypeのインスタンスを作成している場合は、正しく構成される前に Realm にアクセスしている可能性があります。

このような問題を回避するには、次のいずれかを実行することを検討してください。

  • Realm API を使用してプロパティを早期に初期化するタイプのインスタンス化は、アプリが Realm 構成の設定を完了するまで延期されます。

  • Swift のlazyキーワードを使用してプロパティを定義します。 これにより、アプリが Realm 構成を設定するまで、 lazyプロパティにアクセスしようとしない限り、アプリケーションのライフサイクル中にいつでもこのようなタイプを安全にインスタンス化できます。

  • ユーザー定義の構成を明示的に受け取る Realm API を使用してのみプロパティを初期化します。 使用している構成値が、Realm を開くために使用される前に、適切に設定されていることを確認できます。

デフォルトでは、iOS 8 以降では、デバイスがロックされているたびにNSFileProtectionを使用してアプリファイルを暗号化します。 デバイスがロックされているときにアプリが Realm にアクセスしようとすると、次のエラーが表示される場合があります。

open() failed: Operation not permitted

これを処理するには、 Realm ファイルを含む フォルダのファイル保護をダウングレードします。 DNSFileProtectionCompleteUntilFirstUserAuthentication のような低い保護レベル デバイスがロックされている場合でもファイルにアクセスできるようにします。

Tip

iOS ファイルの暗号化を解除する場合は、代わりに Realmに組み込まれている暗号化を使用してデータを保護することを検討してください。

この例では、デフォルトの 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 ではいつでも予備ファイルを作成および削除できます。 ファイルのファイル保護をダウングレードする代わりに、親フォルダーに適用します。 こうすることで、作成時間に関係なく、関連するすべてのファイルにファイル保護が適用されます。

Tip

以下も参照してください。

戻る

Realm ファイル