Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

Realm オブジェクトモデルの定義 - Swift SDK

項目一覧

  • 新しいオブジェクトタイプの定義
  • プロパティを宣言
  • 永続化されたプロパティ属性
  • Objective-C の動的プロパティ属性
  • 任意/必須のプロパティを指定する
  • プライマリキーの指定
  • プロパティのインデックス作成
  • プロパティを無視
  • 列挙プロパティを宣言
  • プロパティ名の再マッピング
  • クラスプロジェクションを定義する
  • これらの例について
  • クラスプロジェクションの定義方法
  • 非対称オブジェクトの定義
  • 非構造化データの定義

Realm オブジェクトは、 RMObjectまたはRM embeddedObjectクラスから派生して定義できます。 クラスの名前はRealm内のテーブル名になり、クラスのプロパティはデータベースに永続します。 そのため、永続化されたオブジェクトの操作は、通常の Objective-C オブジェクトの操作と同様に簡単になります。

// A dog has an _id primary key, a string name, an optional
// string breed, and a date of birth.
@interface Dog : RLMObject
@property RLMObjectId *_id;
@property NSString *name;
@property NSString *breed;
@property NSDate *dateOfBirth;
@end
@implementation Dog
+ (NSString *)primaryKey {
return @"_id";
}
+ (NSArray<NSString *> *)requiredProperties {
return @[
@"_id", @"name", @"dateOfBirth"
];
}
@end

オブジェクト クラスまたは 埋め込み オブジェクト クラスから派生することで、Realm オブジェクトを定義できます。クラスの名前はRealm内のテーブル名になり、クラスのプロパティはデータベースに永続します。 そのため、永続化されたオブジェクトの操作は、通常の Swift オブジェクトの操作と同様に簡単になります。

// A dog has an _id primary key, a string name, an optional
// string breed, and a date of birth.
class Dog: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name = ""
@Persisted var breed: String?
@Persisted var dateOfBirth = Date()
}

注意

クラス名は最大 57 文字の UTF-8 文字に制限されています。

クラスのプロパティ属性を宣言するときに、それらのプロパティを Realm によって管理するかどうかを指定できます。 管理対象のプロパティは、 データベースに保存または更新されます。 無視されたプロパティはデータベースに保存されません。 クラス内で管理対象プロパティと無視されているプロパティを混在させることができます。

プロパティを管理対象または無視としてマークする構文は、使用している SDK のバージョンによって異なります。

バージョン 10.10.0 の新機能: @Persisted宣言のスタイルは、SDK の古いバージョンの@objc dynamicRealmOptional 、およびRealmProperty宣言表記を置き換えます。 SDK の古いバージョンについては、「 Objective-C 動的プロパティ属性」を参照してください。

データベースに保存するモデル プロパティを@Persistedとして宣言します。 これにより、基礎となるデータベース データにアクセスできるようになります。

クラス内で任意のプロパティを@Persistedとして宣言すると、そのクラス内の他のプロパティは自動的に無視されます。

クラス定義内で@Persisted@objc dynamicのプロパティ宣言を混在させると、 @objc dynamicとマークされたプロパティ属性は無視されます。

Tip

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

サポートされているプロパティのページ には、プロパティ宣言のチェックシートが含まれています。

バージョン10.10.0での変更: このプロパティ宣言情報は、10.10.0 より前のバージョンの SDK 用です。

Objective-C ランタイムで動的 Realm モデル プロパティを宣言します。 これにより、基礎となるデータベース データにアクセスできるようになります。

次のいずれかを実行できます。

  • 個々のプロパティを宣言するには、 @objc dynamic varを使用します

  • クラスを宣言するには、 @objcMembersを使用します。 次に、 dynamic varを使用して個々のプロパティを宣言します。

LinkingObjectsListRealmOptionalRealmPropertyを宣言するには、 letを使用します。 Objective-C ランタイムはこれらのジェネリック プロパティを表現できません。

バージョン 10.8.0 での変更: RealmPropertyRealmOptionalに置き換え

Tip

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

サポートされているプロパティのページ には、プロパティ宣言のチェックシートが含まれています。

Tip

Realm がサポートするプロパティとして使用するタイプについて詳しくは、「サポートされているプロパティ タイプ 」を参照してください。

非ジェネリック プロパティを宣言する場合は、 @Persistedアノテーションを使用します。 @Persisted属性は、Realm モデル プロパティを基礎となるデータベース データのアクセス権に変換します。

通常の Objective-C インターフェースと同様に、オブジェクトタイプのプロパティを宣言します。

Realm 配列でインターフェースを使用するには、インターフェース名をRLM_COLLECTION_TYPE()マイクロに渡します。 これは、インターフェースの ヘッダー ファイルの下部に配置できます。 RLM_COLLECTION_TYPE()マイクロは、 RMArrayにタイプでタグを付けるためのプロトコルを作成します。

// Task.h
@interface Task : RLMObject
@property NSString *description;
@end
// Define an RLMArray<Task> type
RLM_COLLECTION_TYPE(Task)
// User.h
// #include "Task.h"
@interface User : RLMObject
@property NSString *name;
// Use RLMArray<Task> to have a list of tasks
// Note the required double tag (<Task *><Task>)
@property RLMArray<Task *><Task> *tasks;
@end

非ジェネリック プロパティを宣言する場合は、 @objc dynamic varアノテーションを使用します。 @objc dynamic var属性は、Realm モデル プロパティを基礎となるデータベース データのアクセス権に変換します。 クラスが@objcMembers (Swift 4以降)として宣言されている場合は、 @objcを使用せずにプロパティをdynamic varとして宣言できます。

ジェネリック型LinkingObjectsListRealmPropertyのプロパティを宣言するには、 letを使用します。 ジェネリック プロパティは、Realm が動的プロパティの動的ディスパッチに使用する Objective-C ランタイムでは表現できません。

注意

プロパティ名は最大 63 文字の UTF-8 文字に制限されています。

標準の Swift 構文を使用して、プロパティを任意または必須(任意以外)として宣言できます。

class Person: Object {
// Required string property
@Persisted var name = ""
// Optional string property
@Persisted var address: String?
// Required numeric property
@Persisted var ageYears = 0
// Optional numeric property
@Persisted var heightCm: Float?
}

特定のプロパティを必須として宣言するには、 requireProperties メソッドを実装し、必要なプロパティ名の配列を返します。

@interface Person : RLMObject
// Required property - included in `requiredProperties`
// return value array
@property NSString *name;
// Optional string property - not included in `requiredProperties`
@property NSString *address;
// Required numeric property
@property int ageYears;
// Optional numeric properties use NSNumber tagged
// with RLMInt, RLMFloat, etc.
@property NSNumber<RLMFloat> *heightCm;
@end
@implementation Person
// Specify required pointer-type properties here.
// Implicitly required properties (such as properties
// of primitive types) do not need to be named here.
+ (NSArray<NSString *> *)requiredProperties {
return @[@"name"];
}
@end

バージョン 10.8.0 での変更: RealmPropertyRealmOptionalに置き換え

標準の Swift 構文を使用して、 StringDateData 、およびObjectIdプロパティを任意または必須(任意ではない)として宣言できます。 RealmProperty型を使用して任意の数値型を宣言します。

class Person: Object {
// Required string property
@objc dynamic var name = ""
// Optional string property
@objc dynamic var address: String?
// Required numeric property
@objc dynamic var ageYears = 0
// Optional numeric property
let heightCm = RealmProperty<Float?>()
}

RealmProperty は、 IntFloatDoubleBool 、およびIntのすべてのサイズ バージョン( Int8Int16Int32Int64 )をサポートしています。

プロパティをクラスのプライマリキーとして指定できます。

プライマリキーを使用すると、オブジェクトを効率的に検索、アップデート、およびアップサートすることができます。

プライマリキーには、次の制限が適用されます。

  • オブジェクトモデルごとに定義できるプライマリキーは 1 つだけです。

  • プライマリキー値は、Realm 内のオブジェクトのすべてのインスタンスで一意である必要があります。 重複するプライマリキー値を挿入しようとすると、Realm はエラーをスローします。

  • プライマリキーの値は不変です。 オブジェクトのプライマリキー値を変更するには、元のオブジェクトを削除し、別のプライマリキー値を持つ新しいオブジェクトを挿入する必要があります。

  • 埋め込みオブジェクトではプライマリキーを定義できません。

@Persisted表記でprivateKey: trueを使用してプロパティを宣言し、モデルのプライマリキーを設定します。

class Project: Object {
@Persisted(primaryKey: true) var id = 0
@Persisted var name = ""
}

+[RMObjectプライマリキー]をオーバーライドして、モデルのプライマリキーを設定します。

@interface Project : RLMObject
@property NSInteger id; // Intended primary key
@property NSString *name;
@end
@implementation Project
// Return the name of the primary key property
+ (NSString *)primaryKey {
return @"id";
}
@end

Object.primaryKey()をオーバーライドして、モデルのプライマリキーを設定します。

class Project: Object {
@objc dynamic var id = 0
@objc dynamic var name = ""
// Return the name of the primary key property
override static func primaryKey() -> String? {
return "id"
}
}

モデルの特定のプロパティにインデックスを作成できます。 インデックスは、等価演算子と IN 演算子を使用するクエリを高速化します。 挿入および更新操作速度が若干遅くなります。 インデックスはメモリを使用するため、Realm ファイル内のより多くのスペースが必要になります。 各インデックスエントリは 12 バイト以上です。 特定の状況に合わせて読み取りパフォーマンスを最適化する場合にのみインデックスを追加することをお勧めします。

Realmは、 string 、整数、ブール値、DateUUIDObjectId、および AnyRealmValue プロパティのインデックス作成をサポートしています。

バージョン 10.8.0 の新機能 UUID:AnyRealmValue タイプと タイプ

プロパティをインデックス化するには、 @Persisted表記でindexed:trueを使用してプロパティを宣言します。

class Book: Object {
@Persisted var priceCents = 0
@Persisted(indexed: true) var title = ""
}

プロパティをインデックス化するには+[RMObject indexedProperties]をオーバーライドし、インデックス付きプロパティ名のリストを返します。

@interface Book : RLMObject
@property int priceCents;
@property NSString *title;
@end
@implementation Book
// Return a list of indexed property names
+ (NSArray *)indexedProperties {
return @[@"title"];
}
@end

プロパティをインデックス化するには、 Object.indexedProperties()をオーバーライドし、インデックス化されたプロパティ名のリストを返します。

class Book: Object {
@objc dynamic var priceCents = 0
@objc dynamic var title = ""
// Return a list of indexed property names
override static func indexedProperties() -> [String] {
return ["title"]
}
}

無視されたプロパティは、通常のプロパティと完全に一致します。クエリでは使用できず、 Realm通知はトリガーされません。これらは引き続き KVM を使用して観察できます。

Tip

Realm は読み取り専用プロパティを自動的に無視します。

バージョン10.10.0から非推奨: ignoredProperties()

モデル内のフィールドをそのRealmに保存しない場合は、プロパティ属性から@Persisted表記を削除します。

さらに、クラス内で@Persisted@objc dynamicのプロパティ宣言を混在させると、 @objc dynamicプロパティは無視されます。

class Person: Object {
// If some properties are marked as @Persisted,
// any properties that do not have the @Persisted
// annotation are automatically ignored.
var tmpId = 0
// The @Persisted properties are managed
@Persisted var firstName = ""
@Persisted var lastName = ""
// Read-only properties are automatically ignored
var name: String {
return "\(firstName) \(lastName)"
}
// If you mix the pre-10.10 property declaration
// syntax `@objc dynamic` with the 10.10+ @Persisted
// annotation within a class, `@objc dynamic`
// properties are ignored.
@objc dynamic var email = ""
}

モデル内のフィールドをそのRealmに保存したくない場合は、 +[RMObject無視Properties]をオーバーライドし、無視されたプロパティ名のリストを返します。

@interface Person : RLMObject
@property NSInteger tmpId;
@property (readonly) NSString *name; // read-only properties are automatically ignored
@property NSString *firstName;
@property NSString *lastName;
@end
@implementation Person
+ (NSArray *)ignoredProperties {
return @[@"tmpId"];
}
- (NSString *)name {
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
@end

モデル内のフィールドをそのRealmに保存しない場合は、 Object.ignoreProperties()をオーバーライドし、無視されたプロパティ名のリストを返します。

class Person: Object {
@objc dynamic var tmpId = 0
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
// Read-only properties are automatically ignored
var name: String {
return "\(firstName) \(lastName)"
}
// Return a list of ignored property names
override static func ignoredProperties() -> [String] {
return ["tmpId"]
}
}

バージョン10.10.0での変更: プロトコルは ではなくPersistableEnum RealmEnumになりました。

PeristableEnumプロトコルに準拠しているとマークすることで、 @Persistedで列挙型を使用できます。 PersistableEnumは、未加工の型がRealm がサポートする型である任意のRawRepresentable列挙型になります。

// Define the enum
enum TaskStatusEnum: String, PersistableEnum {
case notStarted
case inProgress
case complete
}
// To use the enum:
class Task: Object {
@Persisted var name: String = ""
@Persisted var owner: String?
// Required enum property
@Persisted var status = TaskStatusEnum.notStarted
// Optional enum property
@Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum?
}

Realm はIntベースの@objc列挙型のみをサポートします。

// Define the enum
@objc enum TaskStatusEnum: Int, RealmEnum {
case notStarted = 1
case inProgress = 2
case complete = 3
}
// To use the enum:
class Task: Object {
@objc dynamic var name: String = ""
@objc dynamic var owner: String?
// Required enum property
@objc dynamic var status = TaskStatusEnum.notStarted
// Optional enum property
let optionalTaskStatusEnumProperty = RealmProperty<TaskStatusEnum?>()
}

Tip

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

バージョン10.33.0の新機能

オブジェクトモデル内のプロパティのパブリック名を、Realm に保存する別のプライベート名にマッピングできます。 たとえば、プロジェクトでは Swift 慣用のキャメルケースが使用されている場合など、Device Sync スキーマのプロパティ名でスニペットのケースが使用されている場合は、これを実行する必要があるかもしれません。

プロジェクトで使用する名前を、オブジェクトモデルの@Persistedプロパティとして宣言します。 次に、 propertiesMapping()関数を介して、プロパティ名のパブリック値とプライベート値を含む辞書を渡します。

この例では、 firstNameは、CRUD 操作を実行するためにプロジェクト全体のコードで使用するパブリック プロパティ名です。 propertiesMapping()関数を使用して、それを Realm 内のプライベートプロパティ名first_nameを使用して値を保存するようにマッピングします。 同期された Realm に書き込むと、Sync スキーマにはプライベートプロパティ名first_nameを使用して保存された値が表示されます。

class Person: Object {
@Persisted var firstName = ""
@Persisted var lastName = ""
override class public func propertiesMapping() -> [String: String] {
["firstName": "first_name",
"lastName": "last_name"]
}
}

このセクションの例では、単純なデータセットを使用します。 2 つの Realm オブジェクトタイプは、 Personと埋め込みオブジェクトAddressです。 Personには、氏名の名前、任意のAddress 、および他のPersonオブジェクトで構成される友人のリストがあります。 Addressには都市と国があります。

これらの 2 つのクラス、 PersonAddressのスキーマを以下で参照してください。

class Person: Object {
@Persisted var firstName = ""
@Persisted var lastName = ""
@Persisted var address: Address?
@Persisted var friends = List<Person>()
}
class Address: EmbeddedObject {
@Persisted var city: String = ""
@Persisted var country = ""
}

バージョン10.21.0の新機能

プロジェクション型のクラスを作成して、クラス プロジェクションを定義します。 クラスのプロジェクションで使用するプロパティを持つオブジェクトまたは埋め込みオブジェクトのベースを指定します。 @Projectedプロパティ ラッパーを使用して、基本オブジェクトの@Persistedプロパティからプロジェクションするプロパティを宣言します。

注意

クラス プロジェクションでListまたはMutableSetを使用する場合、クラス プロジェクションの型はProjectedCollection でなければなりません。

class PersonProjection: Projection<Person> {
@Projected(\Person.firstName) var firstName // Passthrough from original object
@Projected(\Person.address?.city) var homeCity // Rename and access embedded object property through keypath
@Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String> // Collection mapping
}

クラス プロジェクションを定義する際、元の@Persistedプロパティをいくつかの方法で変換できます。

  • パスオーバー: プロパティは元のオブジェクトと同じ名前と型

  • 名前変更: プロパティは元のオブジェクトと同じ型ですが、名前が異なります

  • キーパス解決: キーパス解決を使用して、埋め込みオブジェクトプロパティを含む、元のオブジェクトのプロパティにアクセス

  • コレクション マッピング: ObjectEmbeddedObjectプロジェクトは、プリミティブ値のコレクションとして、 または の 可変セット を 一覧表示 します。

  • 除外: クラス プロジェクションを使用する場合、クラス プロジェクションを通じて@Projectedではない基礎オブジェクトのプロパティは除外されます。 これにより、クラス プロジェクションの変更を監視し、クラス プロジェクションの一部ではないプロパティの変更を確認できなくなります。

バージョン 10.29.0 の新機能

アプリが Flexible Sync を使用する場合は、 Data Ingestを使用して、デバイスから Atlas App Services App にリンクされたデータベースにオブジェクトを一方向に同期できます。 AsyncMongoDB から継承して非対称オブジェクトを定義します

class WeatherSensor: AsymmetricObject {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var deviceId: String
@Persisted var temperatureInFahrenheit: Float
@Persisted var barometricPressureInHg: Float
@Persisted var windSpeedInMph: Int
}

バージョン 10.42.4 での変更: 非対称オブジェクトは非埋め込みオブジェクトにリンクできます。

AsymmetricObject は、いくつかの例外を除いて、 Objectと同じプロパティタイプをほぼサポートしています。

  • 非対称オブジェクトは埋め込みオブジェクトにのみリンクできます
    • Object およびList<Object>プロパティは、Swift SDK バージョン 10.42.3 以前ではサポートされていません。 Swift SDK バージョン 10.42.4 以降では、非対称オブジェクトは非埋め込みオブジェクトにリンクできます。

    • EmbeddedObjectList<EmbeddedObject>はサポートされています。

Object内からAsymmetricObjectにはリンクできません。 指定すると、エラーがスローされます。

非対称オブジェクトは他の Realm オブジェクトと同じように機能することはありません。 次の操作はできません。

  • 非対称オブジェクトを Realm に追加する

  • Realm から非対称オブジェクトを削除する

  • 非対称オブジェクトのクエリ

非対称オブジェクトのみを作成できます。これにより、Device Sync でアプリにリンクされた Atlas データベースに一方向に同期されます。

詳細については、「非対称オブジェクトの作成 」を参照してください。

バージョン10.51.0の新機能

SDK バージョン10.51.0以降、 AnyRealmValueプロパティ内に混合データのコレクションを保存できます。 この機能を使用すると、厳密なデータモデルを定義することなく、JSON や MongoDB ドキュメントなどの複雑なデータ構造をモデル化できます。

非構造化データとは、期待されるスキーマに簡単に準拠していないデータであるため、個々のデータ クラスにモデル化するのが困難または非効率的です。 たとえば、アプリには、実行時に構造が不明な高度に変数データや動的データがある場合があります。

コレクションを混合プロパティに保存すると、Device Sync を使用する際のパフォーマンス的な同期など、機能を犠牲にすることなく柔軟性が高まります。 そして、混合されていないコレクションと同じ方法でそれらを操作できます。

  • 混合コレクションは最大100レベルまでネストできます。

  • 混合コレクションのReactに対応する と をクエリできます。

  • 個々の混合コレクション要素を検索して更新できます。

ただし、混合コレクションにデータを保存する場合、構造化スキーマを使用したり、JSON string を単一の string プロパティに直列化したりする場合よりパフォーマンスが低くなります。

アプリ内の非構造化データをモデル化するには、スキーマ内の適切なプロパティをAnyRealmValue型として定義します。 次に、これらのAnyRealmValueプロパティをAnyRealmValue要素のリストまたは辞書コレクションとして設定できます。 AnyRealmValueMutableSetまたは埋め込みオブジェクトを表すことができないことに注意してください。

Tip

  • 型が不明であるが、各値には一意の識別子が付けられる場合は、混合データ型のマップを使用します。

  • 型が不明であるが、オブジェクトの順序に意味がある場合は、混合データ型のリストを使用します。

戻る

モデルデータ