React変更に する -SwiftUI
オブジェクトの観察
Swift SDK は、監視対象オブジェクトが変更されたときにビューを無効にする @ObservedRealmObjectプロパティ ラッパーを提供します。 このプロパティ ラッパーを使用して、監視されたオブジェクトが変更されたときに自動的に更新されるビューを作成できます。
struct DogDetailView: View { var dog: Dog var body: some View { VStack { Text(dog.name) .font(.title2) Text("\(dog.name) is a \(dog.breed)") AsyncImage(url: dog.profileImageUrl) { image in image.resizable() } placeholder: { ProgressView() } .aspectRatio(contentMode: .fit) .frame(width: 150, height: 150) Text("Favorite toy: \(dog.favoriteToy)") } } }
クエリ結果の観察
Swift SDK は、クエリ結果のコレクションを観察できる@ObservedResultsプロパティ ラッパーを提供します。 ObservedResults コレクションへの簡単な書き込みを実行でき、観察されたクエリが変更されるとビューは自動的に更新されます。 たとえば、 onDelete
を使用して、監視対象の犬リストから犬を排除できます。
注意
@ObservedResults
プロパティ ラッパーは SwiftUI ビューで使用するためのものです。 ビューモデルで結果を観察するには、変更リスナーを登録します。
struct DogsView: View { Dog.self) var dogs ( /// The button to be displayed on the top left. var leadingBarButton: AnyView? var body: some View { NavigationView { VStack { // The list shows the dogs in the realm. // The ``@ObservedResults`` above implicitly opens a realm and retrieves // all the Dog objects. We can then pass those objects to views further down the // hierarchy. List { ForEach(dogs) { dog in DogRow(dog: dog) }.onDelete(perform: $dogs.remove) }.listStyle(GroupedListStyle()) .navigationBarTitle("Dogs", displayMode: .large) .navigationBarBackButtonHidden(true) .navigationBarItems( leading: self.leadingBarButton, // Edit button on the right to enable rearranging items trailing: EditButton()) }.padding() } } }
Tip
以下も参照してください。
Realm がサポートするクエリ構文とクエリのタイプの詳細については、「読み取り - Swift SDK 」および「データのフィルタリング - Swift SDK 」を参照してください。
観察された結果のソート
@ObservedResultsプロパティ ラッパーは、クエリ結果をソートするためにSortDescriptorパラメーターを受け取ることができます。
struct SortedDogsView: View { Dog.self, ( sortDescriptor: SortDescriptor(keyPath: "name", ascending: true)) var dogs var body: some View { NavigationView { // The list shows the dogs in the realm, sorted by name List(dogs) { dog in DogRow(dog: dog) } } } }
Tip
計算プロパティを@ObservedResults
のSortDescriptor
として使用することはできません。
セクション化された結果の観察
バージョン 10.29.0 の新機能。
オブジェクトのプロパティから生成されたキーによってセクションに分割された結果セットを確認できます。 永続的ではないモデルに計算された変数を追加しました。これは結果セットをセクションで使用するだけです。
var firstLetter: String { guard let char = name.first else { return "" } return String(char) }
次に、 @ObservedSectionedResultsプロパティ ラッパーを使用して、計算された変数キーに基づいてセクションに分割された結果セットを確認できます。
Dog.self, ( sectionKeyPath: \.firstLetter) var dogs
これらの観察されたセクション化された結果を使用して、セクションごとに分割されたリスト ビューを入力できます。
struct SectionedDogsView: View { Dog.self, ( sectionKeyPath: \.firstLetter) var dogs /// The button to be displayed on the top left. var leadingBarButton: AnyView? var body: some View { NavigationView { VStack { // The list shows the dogs in the realm, split into sections according to the keypath. List { ForEach(dogs) { section in Section(header: Text(section.key)) { ForEach(section) { dog in DogRow(dog: dog) } } } } .listStyle(GroupedListStyle()) .navigationBarTitle("Dogs", displayMode: .large) .navigationBarBackButtonHidden(true) .navigationBarItems( leading: self.leadingBarButton, // Edit button on the right to enable rearranging items trailing: EditButton()) }.padding() } } }
アプリの状態の監視
アプリでAtlas Device Syncを使用している場合は、アプリオブジェクトがReact状態の変更に対応するかどうかを確認できます。 これにより、アプリはapp.currentUser
がある間で操作を実行し、 app.currentUser
がない場合はユーザーにログインするように指示します。
Realm はユーザー認証情報をデバイス上のキャッシュにキャッシュするため、アプリはapp.currentUser
の間でもオフラインで動作できます。
/// This view observes the Realm app object. /// Either direct the user to login, or open a realm /// with a logged-in user. struct FlexibleSyncContentView: View { // Observe the Realm app object in order to react to login state changes. var app: RealmSwift.App var body: some View { if let user = app.currentUser { // Create a `flexibleSyncConfiguration` with `initialSubscriptions`. // We'll inject this configuration as an environment value to use when opening the realm // in the next view, and the realm will open with these initial subscriptions. let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in let peopleSubscriptionExists = subs.first(named: "people") let dogSubscriptionExists = subs.first(named: "dogs") // Check whether the subscription already exists. Adding it more // than once causes an error. if (peopleSubscriptionExists != nil) && (dogSubscriptionExists != nil) { // Existing subscriptions found - do nothing return } else { // Add queries for any objects you want to use in the app // Linked objects do not automatically get queried, so you // must explicitly query for all linked objects you want to include. subs.append(QuerySubscription<Person>(name: "people")) subs.append(QuerySubscription<Dog>(name: "dogs")) } }) OpenFlexibleSyncRealmView() .environment(\.realmConfiguration, config) } else { // If there is no user logged in, show the login view. LoginView() } } }