Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

React para alterações - SwiftUI

Nesta página

  • Observar um objeto
  • Observar resultados da query
  • Classificar resultados observados
  • Observe os resultados seccionados
  • Observe o estado do aplicativo

O Swift SDK fornece o wrapper da propriedade @ObservedRealmObject que invalida uma visualização quando um objeto observado é alterado. Você pode usar esse wrapper de propriedade para criar uma visualização que se atualiza automaticamente quando o objeto observado muda.

struct DogDetailView: View {
@ObservedRealmObject 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)")
}
}
}

O Swift SDK fornece o wrapper da propriedade @ObservedResults que permite observar uma coleção de resultados de query. Você pode fazer uma gravação rápida em uma collection ObservedResults, e a visualização se atualiza automaticamente quando a query observada é alterada. Por exemplo, você pode remover um cão de uma lista de cães observados utilizando onDelete.

Observação

O invólucro de propriedades @ObservedResults deve ser usado em uma visualização SwiftUI. Se você quiser observar os resultados em um modelo de exibição, registre um ouvinte de alterações.

struct DogsView: View {
@ObservedResults(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()
}
}
}

Dica

Veja também:

Para obter mais informações sobre a sintaxe de query e os tipos de query compatíveis com o Realm, consulte: Ler - Swift SDK e Filtrar dados - Swift SDK.

O wrapper da propriedade @ObservedResults pode utilizar um parâmetro SortDescriptor para classificar os resultados da consulta.

struct SortedDogsView: View {
@ObservedResults(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)
}
}
}
}

Dica

Você não pode utilizar uma propriedade computada como SortDescriptor para @ObservedResults.

Novidades na versão 10,29,0.

Você pode observar um conjunto de resultados dividido em seções por uma chave gerada a partir de uma propriedade no objeto. Adicionamos uma variável computada ao modelo que não persistimos; nós apenas usamos isso para seccionar o conjunto de resultados.

var firstLetter: String {
guard let char = name.first else {
return ""
}
return String(char)
}

Em seguida, podemos usar o wrapper da propriedade @ObservedSectionedResults para observar o conjunto de resultados dividido em seções com base na chave da variável computada.

@ObservedSectionedResults(Dog.self,
sectionKeyPath: \.firstLetter) var dogs

Você pode usar esses resultados seccionados observados para preencher uma exibição de lista dividida por seções:

struct SectionedDogsView: View {
@ObservedSectionedResults(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()
}
}
}

Se seu aplicativo usa o Atlas Device Sync, você pode observar o objeto App React às mudanças no estado de login. Isso permite que seu aplicativo execute operações enquanto tiver um app.currentUser ou direcione o usuário para fazer login se não houver app.currentUser.

Como o Realm armazena credenciais de usuário em cache no dispositivo, seu aplicativo pode trabalhar offline enquanto ele tem um 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.
@ObservedObject 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()
}
}
}

Voltar

Configurar e abrir um Realm