Realm オブジェクトモデルの定義 - Swift SDK
項目一覧
新しいオブジェクトタイプの定義
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 { true) var _id: ObjectId (primaryKey: var name = "" var breed: String? var dateOfBirth = Date() }
注意
クラス名は最大 57 文字の UTF-8 文字に制限されています。
プロパティを宣言
クラスのプロパティ属性を宣言するときに、それらのプロパティを Realm によって管理するかどうかを指定できます。 管理対象のプロパティは、 データベースに保存または更新されます。 無視されたプロパティはデータベースに保存されません。 クラス内で管理対象プロパティと無視されているプロパティを混在させることができます。
プロパティを管理対象または無視としてマークする構文は、使用している SDK のバージョンによって異なります。
永続化されたプロパティ属性
バージョン 10.10.0 の新機能: @Persisted
宣言のスタイルは、SDK の古いバージョンの@objc dynamic
、 RealmOptional
、およびRealmProperty
宣言表記を置き換えます。 SDK の古いバージョンについては、「 Objective-C 動的プロパティ属性」を参照してください。
データベースに保存するモデル プロパティを@Persisted
として宣言します。 これにより、基礎となるデータベース データにアクセスできるようになります。
クラス内で任意のプロパティを@Persisted
として宣言すると、そのクラス内の他のプロパティは自動的に無視されます。
クラス定義内で@Persisted
と@objc dynamic
のプロパティ宣言を混在させると、 @objc dynamic
とマークされたプロパティ属性は無視されます。
Objective-C の動的プロパティ属性
バージョン10.10.0での変更: このプロパティ宣言情報は、10.10.0 より前のバージョンの SDK 用です。
Objective-C ランタイムで動的 Realm モデル プロパティを宣言します。 これにより、基礎となるデータベース データにアクセスできるようになります。
次のいずれかを実行できます。
個々のプロパティを宣言するには、
@objc dynamic var
を使用しますクラスを宣言するには、
@objcMembers
を使用します。 次に、dynamic var
を使用して個々のプロパティを宣言します。
LinkingObjects
、 List
、 RealmOptional
、 RealmProperty
を宣言するには、 let
を使用します。 Objective-C ランタイムはこれらのジェネリック プロパティを表現できません。
バージョン 10.8.0 での変更: RealmProperty
がRealmOptional
に置き換え
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
として宣言できます。
ジェネリック型LinkingObjects
、 List
、 RealmProperty
のプロパティを宣言するには、 let
を使用します。 ジェネリック プロパティは、Realm が動的プロパティの動的ディスパッチに使用する Objective-C ランタイムでは表現できません。
注意
プロパティ名は最大 63 文字の UTF-8 文字に制限されています。
任意/必須のプロパティを指定する
標準の Swift 構文を使用して、プロパティを任意または必須(任意以外)として宣言できます。
class Person: Object { // Required string property var name = "" // Optional string property var address: String? // Required numeric property var ageYears = 0 // Optional numeric property 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 での変更: RealmProperty
がRealmOptional
に置き換え
標準の Swift 構文を使用して、 String
、 Date
、 Data
、および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 は、 Int
、 Float
、 Double
、 Bool
、およびInt
のすべてのサイズ バージョン( Int8
、 Int16
、 Int32
、 Int64
)をサポートしています。
プライマリキーの指定
プロパティをクラスのプライマリキーとして指定できます。
プライマリキーを使用すると、オブジェクトを効率的に検索、アップデート、およびアップサートすることができます。
プライマリキーには、次の制限が適用されます。
オブジェクトモデルごとに定義できるプライマリキーは 1 つだけです。
プライマリキー値は、Realm 内のオブジェクトのすべてのインスタンスで一意である必要があります。 重複するプライマリキー値を挿入しようとすると、Realm はエラーをスローします。
プライマリキーの値は不変です。 オブジェクトのプライマリキー値を変更するには、元のオブジェクトを削除し、別のプライマリキー値を持つ新しいオブジェクトを挿入する必要があります。
埋め込みオブジェクトではプライマリキーを定義できません。
@Persisted
表記でprivateKey: trueを使用してプロパティを宣言し、モデルのプライマリキーを設定します。
class Project: Object { true) var id = 0 (primaryKey: 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 、整数、ブール値、Date
、UUID
、ObjectId
、および AnyRealmValue
プロパティのインデックス作成をサポートしています。
バージョン 10.8.0 の新機能 UUID
:AnyRealmValue
タイプと タイプ
プロパティをインデックス化するには、 @Persisted
表記でindexed:trueを使用してプロパティを宣言します。
class Book: Object { var priceCents = 0 true) var title = "" (indexed: }
プロパティをインデックス化するには+[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 var firstName = "" 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 { var name: String = "" var owner: String? // Required enum property var status = TaskStatusEnum.notStarted // Optional enum property 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?>() }
プロパティ名の再マッピング
バージョン10.33.0の新機能。
オブジェクトモデル内のプロパティのパブリック名を、Realm に保存する別のプライベート名にマッピングできます。 たとえば、プロジェクトでは Swift 慣用のキャメルケースが使用されている場合など、Device Sync スキーマのプロパティ名でスニペットのケースが使用されている場合は、これを実行する必要があるかもしれません。
プロジェクトで使用する名前を、オブジェクトモデルの@Persisted
プロパティとして宣言します。 次に、 propertiesMapping()
関数を介して、プロパティ名のパブリック値とプライベート値を含む辞書を渡します。
この例では、 firstName
は、CRUD 操作を実行するためにプロジェクト全体のコードで使用するパブリック プロパティ名です。 propertiesMapping()
関数を使用して、それを Realm 内のプライベートプロパティ名first_name
を使用して値を保存するようにマッピングします。 同期された Realm に書き込むと、Sync スキーマにはプライベートプロパティ名first_name
を使用して保存された値が表示されます。
class Person: Object { var firstName = "" var lastName = "" override class public func propertiesMapping() -> [String: String] { ["firstName": "first_name", "lastName": "last_name"] } }
クラスプロジェクションを定義する
これらの例について
このセクションの例では、単純なデータセットを使用します。 2 つの Realm オブジェクトタイプは、 Person
と埋め込みオブジェクトAddress
です。 Person
には、氏名の名前、任意のAddress
、および他のPerson
オブジェクトで構成される友人のリストがあります。 Address
には都市と国があります。
これらの 2 つのクラス、 Person
とAddress
のスキーマを以下で参照してください。
class Person: Object { var firstName = "" var lastName = "" var address: Address? var friends = List<Person>() } class Address: EmbeddedObject { var city: String = "" var country = "" }
クラスプロジェクションの定義方法
バージョン10.21.0の新機能。
プロジェクション型のクラスを作成して、クラス プロジェクションを定義します。 クラスのプロジェクションで使用するプロパティを持つオブジェクトまたは埋め込みオブジェクトのベースを指定します。 @Projected
プロパティ ラッパーを使用して、基本オブジェクトの@Persisted
プロパティからプロジェクションするプロパティを宣言します。
注意
クラス プロジェクションでListまたはMutableSetを使用する場合、クラス プロジェクションの型はProjectedCollection でなければなりません。
class PersonProjection: Projection<Person> { Person.firstName) var firstName // Passthrough from original object (\ Person.address?.city) var homeCity // Rename and access embedded object property through keypath (\ Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String> // Collection mapping (\}
クラス プロジェクションを定義する際、元の@Persisted
プロパティをいくつかの方法で変換できます。
パスオーバー: プロパティは元のオブジェクトと同じ名前と型
名前変更: プロパティは元のオブジェクトと同じ型ですが、名前が異なります
キーパス解決: キーパス解決を使用して、埋め込みオブジェクトプロパティを含む、元のオブジェクトのプロパティにアクセス
コレクション マッピング:
Object
EmbeddedObject
プロジェクトは、プリミティブ値のコレクションとして、 または の 可変セット を 一覧表示 します。除外: クラス プロジェクションを使用する場合、クラス プロジェクションを通じて
@Projected
ではない基礎オブジェクトのプロパティは除外されます。 これにより、クラス プロジェクションの変更を監視し、クラス プロジェクションの一部ではないプロパティの変更を確認できなくなります。
非対称オブジェクトの定義
バージョン 10.29.0 の新機能。
アプリが Flexible Sync を使用する場合は、 Data Ingestを使用して、デバイスから Atlas App Services App にリンクされたデータベースにオブジェクトを一方向に同期できます。 AsyncMongoDB から継承して非対称オブジェクトを定義します。
class WeatherSensor: AsymmetricObject { true) var _id: ObjectId (primaryKey: var deviceId: String var temperatureInFahrenheit: Float var barometricPressureInHg: Float var windSpeedInMph: Int }
バージョン 10.42.4 での変更: 非対称オブジェクトは非埋め込みオブジェクトにリンクできます。
AsymmetricObject
は、いくつかの例外を除いて、 Object
と同じプロパティタイプをほぼサポートしています。
- 非対称オブジェクトは埋め込みオブジェクトにのみリンクできます
Object
およびList<Object>
プロパティは、Swift SDK バージョン 10.42.3 以前ではサポートされていません。 Swift SDK バージョン 10.42.4 以降では、非対称オブジェクトは非埋め込みオブジェクトにリンクできます。EmbeddedObject
とList<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
要素のリストまたは辞書コレクションとして設定できます。 AnyRealmValue
はMutableSet
または埋め込みオブジェクトを表すことができないことに注意してください。
Tip
型が不明であるが、各値には一意の識別子が付けられる場合は、混合データ型のマップを使用します。
型が不明であるが、オブジェクトの順序に意味がある場合は、混合データ型のリストを使用します。