コレクションのタイプ
Realm にはオブジェクトのグループを表すいくつかのタイプがあります。これをコレクションと呼びます。 コレクションは、1 つのRealm タイプの 0 個以上のインスタンスを含むオブジェクトです。 Realm コレクションは同種です。つまり、コレクション内のすべてのオブジェクトは同じタイプです。
Realm のクエリ エンジンを使用して、任意のコレクションをフィルタリングおよびソートできます。 コレクションはライブであるため、現在のスレッド上の Realm インスタンスの現在の状態を常に反映します。 コレクション通知をサブスクライブして、コレクションの変更をリッスンすることもできます。
すべてのコレクションタイプは、 RealmCollectionプロトコルに準拠しています。このプロトコルはCollectionType から継承されるため、 Realmコレクションは他の標準ライブラリ コレクションと同様に使用できます。
RealmCollection プロトコルを使用すると、任意の Realm コレクションで操作できるジェネリック コードを記述できます。
func operateOn<C: RealmCollection>(collection: C) { // Collection could be either Results or List print("operating on collection containing \(collection.count) objects") }
結果とセクション化された結果
Swift SDK結果コレクションは、クエリから検索されたオブジェクトを表すクラスです。 結果コレクションは、クエリ操作の遅延評価された結果を表します。 結果は不変です。結果コレクションに要素を追加したり、結果コレクションから要素を追加したり、削除したりすることはできません。 結果には、その内容を決定する関連付けられたクエリがあります。
Swift SDK は、 ResultsSectionを要素として保持する型セーフなコレクションであるSessionedResultsも提供します。 各ResultSectionは、特定のセクション キーに属するオブジェクトのみを含む結果のコレクションです。
たとえば、連絡先リストを含むアプリでは、 SessionedResults を使用して、セクションに分割された連絡先のリストを表示できます。各セクションには、特定の文字で始まるすべての連絡先が含まれています。 キーが「L」であるResultsSectionには、「Larry」、「Liam」、「LiSA」が含まれます。
Tip
プロパティとしてのコレクション
Swift SDK は、データモデルのプロパティとして使用できるいくつかの コレクション タイプ も提供しています。
LinkingObjectsは、モデル内で逆の関係を表すクラスです。
マップは、一意のキーを持つキーと値のペアの連想配列を表すクラスです。
AnyRealmCollection は、結果、リスト、またはリンクオブジェクトなどの具体的なRealmコレクションへの呼び出しを転送できる型消去クラス。
コレクションはライブ
ライブ オブジェクトと同様に、Realm コレクションは通常ライブ されます。
ライブ結果のコレクションには、関連付けられているクエリの現在の結果が常に反映されます。
ライブ リストには、Realm インスタンス上の関係の現在の状態が常に反映されます。
コレクションがライブでない場合は、次の 2 つのケースがあります。
コレクションは管理されていません。 たとえば、Realm にまだ追加されていない Realm オブジェクトの List プロパティは、Realm からコピーされたものではありません。
コレクションは固定されています。
コレクション通知と組み合わせると、ライブ コレクションによりクリーンでリアクティブなコードが可能になります。 たとえば、ビューにクエリの結果が表示されるとします。 ビュー クラスで結果コレクションへの参照を保持すると、結果コレクションを更新したり最新であることを検証したりすることなく、必要に応じて結果コレクションを読み取ることができます。
重要
結果インデックスは変更される可能性があります
結果は自動的に更新されるため、 コレクション内のオブジェクトの位置インデックスやコレクション内のオブジェクトの数を保存しないでください。 保存されたインデックスやカウント値は、使用する時間によって期限切れになる可能性があります。
サポートされているプロパティの型
オブジェクトモデルのプロパティを定義するには、次のタイプを使用できます。
App Services スキーマで特定のデータ型が にどのようにマッピングされるかについては、BSON types ドキュメントの「 データモデル マッピングAtlas App Services 」 を参照してください。
「 Device Sync によるデータのモデル化 - Swift SDK 」も参照してください。
プロパティ チャート シート
バージョン 10.10.0 での変更: @Persistedプロパティ宣言の構文
タイプ | 必須 | 任意 | ||
|---|---|---|---|---|
ブール | | | ||
Int, Int8, Int16, Int32, Int64 | | | ||
Float | | | ||
Double | | | ||
文字列 | | | ||
データ | | | ||
日付 | | | ||
Decimal128 | | | ||
| | |||
| | |||
| 該当なし | |||
| 該当なし | |||
| 該当なし | |||
| 該当なし | |||
ユーザー定義オブジェクト | 該当なし | | ||
ユーザー定義の埋め込みオブジェクト | 該当なし | | ||
ユーザー定義の列挙 | | |
CGFloat プロパティは、このタイプがプラットフォームに独立していないため、推奨されません。
@Persisted構文でユーザー定義のオブジェクトでキーと値のコーディングを使用するには、 @objc属性を追加します: @Persisted @objc var myObject: MyClass?
デフォルト値の設定
@Persistedプロパティ宣言の構文では、次のデフォルト値を設定するとパフォーマンスに影響が出る可能性があります。
ListMutableSetDictionaryDecimal128UUIDObjectId
@Persisted var listProperty: List<Int> と@Persisted var
listProperty = List<Int>()は両方とも有効であり、機能的に同等です。 ただし、2 番目の宣言ではパフォーマンスが低下します。
これは、リストが必要に応じて遅延してではなく、親オブジェクトの作成時に作成されるためです。 ほとんどのタイプでは、これは測定できないほど小さい差です。 ここにリストされている型の場合、2 番目の宣言形式を使用するとパフォーマンスに影響が出る可能性があります。
タイプ | 必須 | 任意 | ||
|---|---|---|---|---|
ブール値 | | | ||
整数 | | | ||
Float | | | ||
Double | | | ||
文字列 | | | ||
データ | | | ||
日付 | | | ||
Decimal128 | | | ||
NSUUID | | | ||
| | |||
| 該当なし | |||
| 該当なし | |||
| 該当なし | |||
ユーザー定義RMObject | 該当なし | | ||
ユーザー定義RRM 埋め込みオブジェクト | 該当なし | |
さらに、
整数型
int、NSInteger、long、long long
CGFloat プロパティは、このタイプがプラットフォームに独立していないため、推奨されません。
バージョン 10.8.0 での変更: RealmPropertyがRealmOptionalに置き換え
タイプ | 必須 | 任意 | ||
|---|---|---|---|---|
ブール | | | ||
Int, Int8, Int16, Int32, Int64 | | | ||
Float | | | ||
Double | | | ||
文字列 | | | ||
データ | | | ||
日付 | | | ||
Decimal128 | | | ||
| | |||
| | |||
| ||||
| ||||
| ||||
| 該当なし | |||
ユーザー定義オブジェクト | 該当なし | |
さらに、
任意として、 RealmProperty <T?>を使用して整数、double 型、その他の型を表すことができます。
CGFloat プロパティは、このタイプがプラットフォームに独立していないため、推奨されません。
Unique Identifiers
バージョン 10.8.0 の新機能: UUIDタイプ
ObjectId は、MongoDB 固有の 12 バイトの一意の値です。 UUIDは 16 バイトのグローバル一意の値です。 両方のタイプのインデックスを作成し、いずれかをプライマリキーとして使用します。
注意
@Persisted UUID または ObjectId プロパティ属性のデフォルト値を宣言する場合、これらの構文タイプはどちらも有効です。
@Persisted var value: UUID@Persisted var value = UUID()
ただし、2 番目の ではパフォーマンスが低下します。 これは、オブジェクトが Realm から読み取られるたびに使用されない新しい識別子を後者では作成されるのに対し、前者では必要な場合にのみそれらが作成されるためです。
@Persisted var id: ObjectId は@objc dynamic
var _id = ObjectId.generate()と同等の動作をします。 どちらもランダムな ObjectId を作成します。
@Persisted var _id = ObjectId() は@objc
dynamic var _id = ObjectId()と同等の動作をします。 どちらも 0 から初期化された ObjectId を作成します。
サイズ制限
データおよび string プロパティは 16 MB を超える値を保持できません。 大量のデータを保存するには、次のいずれかを実行します。
データを 16MB のチャンクに分割します。または、
ファイル システムにデータを直接保存し、ファイルへのパスを Realm 内のファイルに保存します。
アプリが 1 つのプロパティに 16 MB を超える保存を試みる場合、Realm は実行時例外をスローします。
サイズの制限やパフォーマンスへの影響を避けるためには、画像ファイルやビデオ ファイルなどの大きな API を Realm に直接保存しないことをお勧めします。 代わりに、ファイルをファイルストアに保存し、ファイルの場所と関連するメタデータのみを Realm 内に保持します。
AnyRealmCollection
具体的なコレクション型を知っていなくても、コレクションをプロパティまたは変数として保存するには、Swift の型システムに「AnyRealmCollection」のような型消去されたラッパーが必要です。
class ViewController { // let collection: RealmCollection // ^ // error: protocol 'RealmCollection' can only be used // as a generic constraint because it has Self or // associated type requirements // // init<C: RealmCollection>(collection: C) where C.ElementType == MyModel { // self.collection = collection // } let collection: AnyRealmCollection<MyModel> init<C: RealmCollection & _ObjcBridgeable>(collection: C) where C.ElementType == MyModel { self.collection = AnyRealmCollection(collection) } }
可変セット
バージョン10.8.0の新機能。
MutableSetコレクションは、個別の値を含む対多の関係を表します。 MutableSetは次のタイプ(およびそれらの任意のバージョン)をサポートしています。
ブール
データ
日付
Decimal128
Double
Float
Int
Int8
Int16
Int32
Int64
オブジェクト
ObjectId
文字列
UUID
Swift の Set と同様に、MutableSet は、保存する型をパラメータ化するジェネリック型です。ネイティブSwiftコレクション と違い、 Realm可変セットは参照型であり、値型(構造体)とは対照的です。
MutableSetsミューテーション メソッドは、書込みトランザクション中にのみ呼び出せます。 その結果、管理Realmを読み取り専用のRealmとして開くと、 MutableSetsは不変になります。
結果 と同じ述語 を持つMutableSet をフィルタリングして並べ替えることができます。他の Realm コレクションと同様に、 MutableSetで変更リスナーを登録できます。
たとえば、 DogクラスモデルにはcitiesVisitedのMutableSetが含まれる場合があります。
class Dog: Object { var name = "" var currentCity = "" var citiesVisited: MutableSet<String> }
注意
@Persisted MutableSet プロパティ属性のデフォルト値を宣言する場合、これらの構文タイプは両方とも有効です。
@Persisted var value: MutableSet<String>@Persisted var value = MutableSet<String>()
ただし、2 番目の ではパフォーマンスが大幅に低下します。 これは、MutableSet が必要に応じて遅延してではなく、親オブジェクトの作成時に作成されるためです。
マップ/辞書
バージョン10.8.0の新機能。
マップは、一意のキーを持つキーと値のペアを含む連想配列です。
Swift の 辞書 と同様に、Map は、キーと値の型がパラメータ化されるジェネリック型です。ネイティブSwiftコレクション と違い、 Realmマップは参照型(クラス)であり、値型(構造体)ではありません。
マップはオブジェクトのプロパティとして宣言できます。
class Dog: Object { var name = "" var currentCity = "" // Map of city name -> favorite park in that city var favoriteParksByCity: Map<String, String> }
Realm では、マップキーに.または$文字を使用できません。 パーセント エンコーディングとデコーディング を使用して、これらの許可されていない文字の 1 つを含むマップキーを保存できます。
// Percent encode . or $ characters to use them in map keys let mapKey = "New York.Brooklyn" let encodedMapKey = "New York%2EBrooklyn"
注意
@Persistedマップ プロパティ属性のデフォルト値を宣言する場合、これらの構文タイプは両方とも有効です。
@Persisted var value: Map<String, String>@Persisted var value = Map<String, String>()
ただし、2 番目の ではパフォーマンスが大幅に低下します。 これは、マップが必要に応じて遅延するのではなく、親オブジェクトの作成時に作成されるためです。
AnyRealmValue
バージョン10.51.0での変更: AnyRealmValueプロパティは、混合データのリストまたはマップを保持できます。
バージョン10.8.0の新機能。
AnyRealmValue は、さまざまなデータ型を保持できる Realm プロパティ型です。 サポートされているAnyRealmValueデータ型は次のとおりです。
Int
Float
Double
Decimal128
ObjectID
UUID
ブール
日付
データ
文字列
リスト
Map
オブジェクト
AnyRealmValue MutableSetまたは埋め込みオブジェクトを保持できません。
この混合データ型はインデックス可能ですが、プライマリキーとして使用することはできません。 nullは許可値であるため、 AnyRealmValueを任意として宣言することはできません。
class Dog: Object { var name = "" var currentCity = "" var companion: AnyRealmValue }
混合としてのコレクション
バージョン10.51.0以降では、 AnyRealmValueデータ型にAnyRealmValue要素のコレクション(リストまたはマップであるが、セットではない)を含めることができます。 混合コレクションを使用して、非構造化データまたは変数データをモデル化できます。 詳細については、「非構造化データの定義 」を参照してください。
混合コレクションは最大100レベルまでネストできます。
通常のコレクションと同様に、混合コレクション プロパティをクエリし、 変更のリスナーを登録できます。
混合コレクション要素を個別に検索して更新できます
セットまたは埋め込みオブジェクトを混合コレクションに保存することはできません。
アプリで混合コレクションを使用するには、データモデルでAnyRealmValue型のプロパティを定義します。 次に、他の混合データ値と同様に、リストやマップのコレクションを作成できます。
地理空間データ
バージョン 10.47.0 の新機能。
地理空間データ(「geodata」)では、地表の点と幾何学的オブジェクトを指定します。
地理空間データを永続化する場合は、 GeoJSON 仕様 に準拠する必要があります。
Swift SDK で地理空間データを永続化するには、データモデルで使用できる GeoJSON 互換の埋め込みクラスを作成します。
カスタム埋め込みオブジェクトには、GeoJSON 仕様に必要な 2 つのフィールドが含まれている必要があります。
"Point"の値を持つtypeプロパティにマッピングするStringプロパティのフィールド:@Persisted var type: String = "Point"緯度と経度のペアを含む
coordinatesプロパティにマッピングするList<Double>タイプのフィールド:@Persisted private var coordinates: List<Double>
class CustomGeoPoint: EmbeddedObject { private var type: String = "Point" private var coordinates: List<Double> public var latitude: Double { return coordinates[1] } public var longitude: Double { return coordinates[0] } convenience init(_ latitude: Double, _ longitude: Double) { self.init() // Longitude comes first in the coordinates array of a GeoJson document coordinates.append(objectsIn: [longitude, latitude]) } }
サポートされていないタイプをサポートされているタイプにマッピングする
バージョン 10.20.0 の新機能。
タイププロジェクション を使用して、サポートされていないタイプを Realm でサポートされているタイプとして永続化できます。 これにより、Realm がサポートしていない Swift 型を使用していても、Realm がサポートする型として保存できます。 たとえば、URL をStringとして保存できますが、Realm から読み取って、URL とみなしてアプリケーション内で使用できます。
型プロジェクションの宣言
Realm で 型プロジェクション を使用するには、次の手順に従います。
Realm のカスタム型プロトコルの 1 つを使用して、サポートされていないデータ型を Realm がサポートする型にマッピングします。
Realm オブジェクトモデルでプロジェクションされた型を @Perlisted プロパティとして使用する
型プロジェクション プロトコルに準拠する
Realm タイプのプロジェクション プロトコルの 1 つを使用して、サポートされていないデータ型を Realm がサポートするタイプにマッピングできます。
Swift SDK は 2 つのタイプのプロジェクション プロトコルを提供します。
CustomPersistable
FailableCustomPersistable
変換が失敗する可能性がない場合は、 CustomPersistableを使用します。
変換が失敗する可能性がある場合は、 FailablecustomPersistableを使用します。
// Extend a type as a CustomPersistable if if is impossible for // conversion between the mapped type and the persisted type to fail. extension CLLocationCoordinate2D: CustomPersistable { // Define the storage object that is persisted to the database. // The `PersistedType` must be a type that Realm supports. // In this example, the PersistedType is an embedded object. public typealias PersistedType = Location // Construct an instance of the mapped type from the persisted type. // When reading from the database, this converts the persisted type to the mapped type. public init(persistedValue: PersistedType) { self.init(latitude: persistedValue.latitude, longitude: persistedValue.longitude) } // Construct an instance of the persisted type from the mapped type. // When writing to the database, this converts the mapped type to a persistable type. public var persistableValue: PersistedType { Location(value: [self.latitude, self.longitude]) } } // Extend a type as a FailableCustomPersistable if it is possible for // conversion between the mapped type and the persisted type to fail. // This returns nil on read if the underlying column contains nil or // something that can't be converted to the specified type. extension URL: FailableCustomPersistable { // Define the storage object that is persisted to the database. // The `PersistedType` must be a type that Realm supports. public typealias PersistedType = String // Construct an instance of the mapped type from the persisted type. // When reading from the database, this converts the persisted type to the mapped type. // This must be a failable initilizer when the conversion may fail. public init?(persistedValue: String) { self.init(string: persistedValue) } // Construct an instance of the persisted type from the mapped type. // When writing to the database, this converts the mapped type to a persistable type. public var persistableValue: String { self.absoluteString } }
Tip
これらは、Swift の組み込みRawRepresentableをモデル化したプロトコルです。
サポートされている永続的なタイプ
PersistedTypeは、 Swift SDK がサポートする任意のプリミティブタイプを使用できます。 埋め込みオブジェクトにすることもできます。
PersistedType は、任意またはコレクションにはできません。 ただし、マップされた型は、オブジェクトモデルで任意またはコレクションのプロパティとして使用できます。
extension URL: FailableCustomPersistable { // The `PersistedType` cannot be an optional, so this is not a valid // conformance to the FailableCustomPersistable protocol. public typealias PersistedType = String? ... } class Club: Object { var id: ObjectId var name: String // Although the `PersistedType` cannot be optional, you can use the // custom-mapped type as an optional in your object model. var url: URL? }
モデルでの型プロジェクションの使用
タイプ プロジェクション プロトコルの 1 つに準拠するタイプは、Swift SDK バージョン 10.10.0 で導入された@Persistedプロパティ宣言構文で使用できます。 @objc dynamic構文では機能しません。
プロジェクションされたタイプは、以下に使用できます。
最上位の型
タイプの任意のバージョン
コレクションの 型
FailableCustomPersistableをプロパティとして使用する場合は、任意のプロパティとして定義します。 任意の場合、 FailableCustomPersistableプロトコルは無効な値をnilにマッピングします。 必須 プロパティの場合は、強制的にラップ解除されます。 プロジェクションの型に変換できない値がある場合、そのプロパティを読み取るとラップされていない失敗の例外がスローされます。
class Club: Object { var id: ObjectId var name: String // Since we declared the URL as a FailableCustomPersistable, // it must be optional. var url: URL? // Here, the `location` property maps to an embedded object. // We can declare the property as required. // If the underlying field contains nil, this becomes // a default-constructed instance of CLLocationCoordinate // with field values of `0`. var location: CLLocationCoordinate2D } public class Location: EmbeddedObject { var latitude: Double var longitude: Double }
モデルにプロジェクションされたタイプが含まれている場合は、永続化されたタイプを使用するか、プロジェクションされたタイプを使用して初期化されたオブジェクトのフィールド プロパティを割り当てることで、 値を持つオブジェクトを作成できます。
// Initialize objects and assign values let club = Club(value: ["name": "American Kennel Club", "url": "https://akc.org"]) let club2 = Club() club2.name = "Continental Kennel Club" // When assigning the value to a type-projected property, type safety // checks for the mapped type - not the persisted type. club2.url = URL(string: "https://ckcusa.com/")! club2.location = CLLocationCoordinate2D(latitude: 40.7509, longitude: 73.9777)
スキーマにおける型プロジェクション
型を型プロジェクション プロトコルに準拠していると宣言するときは、Realm に永続化する必要がある型を指定します。 たとえば、カスタムタイプURLを永続タイプStringにマッピングすると、 URLプロパティはスキーマにStringとして表示され、プロパティへの動的アクセスは string に操作されます。
スキーマは、マップされた型を直接表すものではありません。 プロパティを永続化された型からマッピングされた型に、またはその逆に変更する場合、移行は必要ありません。
