Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Kit de desarrollo de software de Swift

React to Changes - Swift SDK

All Realm objects are live objects, which means they automatically update whenever they're modified. Realm emits a notification event whenever any property changes. You can register a notification handler to listen for these notification events, and update your UI with the latest data.

This page shows how to manually register notification listeners in Swift. Atlas Device SDK for Swift offers SwiftUI property wrappers to make it easy to automatically update the UI when data changes. For more about how to use the SwiftUI property wrappers to react to changes, refer to Observe an Object.

You can register a notification handler on an entire realm. Realm calls the notification handler whenever any write transaction involving that Realm is committed. The handler receives no information about the change.

RLMRealm *realm = [RLMRealm defaultRealm];
// Observe realm notifications. Keep a strong reference to the notification token
// or the observation will stop.
RLMNotificationToken *token = [realm addNotificationBlock:^(RLMNotification _Nonnull notification, RLMRealm * _Nonnull realm) {
// `notification` is an enum specifying what kind of notification was emitted.
// ... update UI ...
}];
// ...
// Later, explicitly stop observing.
[token invalidate];
let realm = try! Realm()
// Observe realm notifications. Keep a strong reference to the notification token
// or the observation will stop.
let token = realm.observe { notification, realm in
// `notification` is an enum specifying what kind of notification was emitted
viewController.updateUI()
}
// ...
// Later, explicitly stop observing.
token.invalidate()

You can register a notification handler on a collection within a realm.

Realm notifies your handler:

  • Después de recuperar primero la colección.

  • Whenever a write transaction adds, changes, or removes objects in the collection.

Las notificaciones describen los cambios desde la notificación anterior con tres listas de índices: los índices de los objetos que se eliminaron, insertaron o modificaron.

Importante

El orden importa

En los controladores de notificaciones de colecciones, aplique siempre los cambios en el siguiente orden: eliminaciones, inserciones y modificaciones. Gestionar las inserciones antes de las eliminaciones puede provocar un comportamiento inesperado.

Las notificaciones de cobro proporcionan una change parámetro que informa qué objetos se eliminan, agregan o modifican durante la transacción de escritura. Este RealmCollectionChange se resuelve en una matriz de rutas de índice que puede pasar a los UITableView métodos de actualización por lotes de un.

Importante

High-frequency updates

This example of a collection change listener does not support high-frequency updates. Under an intense workload, this collection change listener may cause the app to throw an exception.

@interface CollectionNotificationExampleViewController : UITableViewController
@end
@implementation CollectionNotificationExampleViewController {
RLMNotificationToken *_notificationToken;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Observe RLMResults Notifications
__weak typeof(self) weakSelf = self;
_notificationToken = [[Dog objectsWhere:@"age > 5"]
addNotificationBlock:^(RLMResults<Dog *> *results, RLMCollectionChange *changes, NSError *error) {
if (error) {
NSLog(@"Failed to open realm on background worker: %@", error);
return;
}
UITableView *tableView = weakSelf.tableView;
// Initial run of the query will pass nil for the change information
if (!changes) {
[tableView reloadData];
return;
}
// Query results have changed, so apply them to the UITableView
[tableView performBatchUpdates:^{
// Always apply updates in the following order: deletions, insertions, then modifications.
// Handling insertions before deletions may result in unexpected behavior.
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
} completion:^(BOOL finished) {
// ...
}];
}];
}
@end
class CollectionNotificationExampleViewController: UITableViewController {
var notificationToken: NotificationToken?
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
let results = realm.objects(Dog.self)
// Observe collection notifications. Keep a strong
// reference to the notification token or the
// observation will stop.
notificationToken = results.observe { [weak self] (changes: RealmCollectionChange) in
guard let tableView = self?.tableView else { return }
switch changes {
case .initial:
// Results are now populated and can be accessed without blocking the UI
tableView.reloadData()
case .update(_, let deletions, let insertions, let modifications):
// Query results have changed, so apply them to the UITableView
tableView.performBatchUpdates({
// Always apply updates in the following order: deletions, insertions, then modifications.
// Handling insertions before deletions may result in unexpected behavior.
tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
with: .automatic)
tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
}, completion: { finished in
// ...
})
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
}
}
}
}

You can register a notification handler on a specific object within a realm. Realm notifies your handler:

  • Cuando el objeto se borra.

  • When any of the object's properties change.

The handler receives information about what fields changed and whether the object was deleted.

@interface Dog : RLMObject
@property NSString *name;
@property int age;
@end
@implementation Dog
@end
RLMNotificationToken *objectNotificationToken = nil;
void objectNotificationExample() {
Dog *dog = [[Dog alloc] init];
dog.name = @"Max";
dog.age = 3;
// Open the default realm
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addObject:dog];
}];
// Observe object notifications. Keep a strong reference to the notification token
// or the observation will stop. Invalidate the token when done observing.
objectNotificationToken = [dog addNotificationBlock:^(BOOL deleted, NSArray<RLMPropertyChange *> * _Nullable changes, NSError * _Nullable error) {
if (error != nil) {
NSLog(@"An error occurred: %@", [error localizedDescription]);
return;
}
if (deleted) {
NSLog(@"The object was deleted.");
return;
}
NSLog(@"Property %@ changed to '%@'",
changes[0].name,
changes[0].value);
}];
// Now update to trigger the notification
[realm transactionWithBlock:^{
dog.name = @"Wolfie";
}];
}
// Define the dog class.
class Dog: Object {
@Persisted var name = ""
}
var objectNotificationToken: NotificationToken?
func objectNotificationExample() {
let dog = Dog()
dog.name = "Max"
// Open the default realm.
let realm = try! Realm()
try! realm.write {
realm.add(dog)
}
// Observe object notifications. Keep a strong reference to the notification token
// or the observation will stop. Invalidate the token when done observing.
objectNotificationToken = dog.observe { change in
switch change {
case .change(let object, let properties):
for property in properties {
print("Property '\(property.name)' of object \(object) changed to '\(property.newValue!)'")
}
case .error(let error):
print("An error occurred: \(error)")
case .deleted:
print("The object was deleted.")
}
}
// Now update to trigger the notification
try! realm.write {
dog.name = "Wolfie"
}
}

New in version 10.12.0.

In addition to registering a notification handler on an object or collection, you can pass an optional string keyPaths parameter to specify the key path or key paths to watch.

Ejemplo

// Define the dog class.
class Dog: Object {
@Persisted var name = ""
@Persisted var favoriteToy = ""
@Persisted var age: Int?
}
var objectNotificationToken: NotificationToken?
func objectNotificationExample() {
let dog = Dog()
dog.name = "Max"
dog.favoriteToy = "Ball"
dog.age = 2
// Open the default realm.
let realm = try! Realm()
try! realm.write {
realm.add(dog)
}
// Observe notifications on some of the object's key paths. Keep a strong
// reference to the notification token or the observation will stop.
// Invalidate the token when done observing.
objectNotificationToken = dog.observe(keyPaths: ["favoriteToy", "age"], { change in
switch change {
case .change(let object, let properties):
for property in properties {
print("Property '\(property.name)' of object \(object) changed to '\(property.newValue!)'")
}
case .error(let error):
print("An error occurred: \(error)")
case .deleted:
print("The object was deleted.")
}
})
// Now update to trigger the notification
try! realm.write {
dog.favoriteToy = "Frisbee"
}
// When you specify one or more key paths, changes to other properties
// do not trigger notifications. In this example, changing the "name"
// property does not trigger a notification.
try! realm.write {
dog.name = "Maxamillion"
}
}

New in version 10.14.0.

Puede observar un PartialKeyPath parcialmente borrado de tipoen objetos o colecciones de reinos.

objectNotificationToken = dog.observe(keyPaths: [\Dog.favoriteToy, \Dog.age], { change in

Al keyPaths especificar, solo los cambios en esos keyPaths activan bloques de notificación. Los demás cambios no activan bloques de notificación.

Ejemplo

Consider a Dog object where one of its properties is a list of siblings:

class Dog: Object {
@Persisted var name = ""
@Persisted var siblings: List<Dog>
@Persisted var age: Int?
}

If you pass siblings as a keyPath to observe, any insertion, deletion, or modification to the siblings list would trigger a notification. However, a change to someSibling.name would not trigger a notification, unless you explicitly observed ["siblings.name"].

Nota

Varios tokens de notificación en el mismo objeto que filtran por rutas de clave independientes no filtran de forma exclusiva. Si se cumple un cambio de ruta de clave para un token de notificación, se ejecutarán todos los bloques de tokens de notificación de ese objeto.

Cuando observas rutas clave en los distintos tipos de colecciones, puedes esperar estos comportamientos:

  • LinkingObjects:: Observing a property of the LinkingObject triggers a notification for a change to that property, but does not trigger notifications for changes to its other properties. Insertions or deletions to the list or the object that the list is on trigger a notification.

  • Listas: La observación de una propiedad del objeto de la lista activará una notificación por un cambio en esa propiedad, pero no activará notificaciones por cambios en sus otras propiedades. Las inserciones o eliminaciones en la lista o en el objeto donde se encuentra la lista activan una notificación.

  • Mapa: Observar una propiedad del objeto del mapa activa una notificación para cualquier cambio en dicha propiedad, pero no para cualquier cambio en las demás propiedades. Las inserciones o eliminaciones en el mapa o en el objeto donde se encuentra activan una notificación. El change parámetro indica, en forma de claves dentro del mapa, qué pares clave-valor se añaden, eliminan o modifican durante cada transacción de escritura.

  • MutableSet: Observar una propiedad de un objeto MutableSet activa una notificación de cambio para esa propiedad, pero no activará notificaciones para cambios en sus otras propiedades. Las inserciones o eliminaciones en el MutableSet o en el objeto en el que se encuentra el MutableSet desencadenan una notificación.

  • Results: Observing a property of the Result triggers a notification for a change to that property, but does not trigger notifications for changes to its other properties. Insertions or deletions to the Result trigger a notification.

Puedes guardar en un realm sin enviar una notificación a un observador específico al pasar el token de notificación del observador en un arreglo a realm.write(withoutNotifying:_:):

RLMRealm *realm = [RLMRealm defaultRealm];
// Observe realm notifications
RLMNotificationToken *token = [realm addNotificationBlock:^(RLMNotification _Nonnull notification, RLMRealm * _Nonnull realm) {
// ... handle update
}];
// Later, pass the token in an array to the realm's `-transactionWithoutNotifying:block:` method.
// Realm will _not_ notify the handler after this write.
[realm transactionWithoutNotifying:@[token] block:^{
// ... write to realm
}];
// Finally
[token invalidate];
let realm = try! Realm()
// Observe realm notifications
let token = realm.observe { notification, realm in
// ... handle update
}
// Later, pass the token in an array to the realm.write(withoutNotifying:)
// method to write without sending a notification to that observer.
try! realm.write(withoutNotifying: [token]) {
// ... write to realm
}
// Finally
token.invalidate()

Tip

Observation stops when the token returned by an observe call becomes invalid. You can explicitly invalidate a token by calling its invalidate() method.

Importante

Retener tokens tanto tiempo como quieras observar

Las notificaciones se detienen si el token está en una variable local que sale del ámbito.

RLMRealm *realm = [RLMRealm defaultRealm];
// Observe and obtain token
RLMNotificationToken *token = [realm addNotificationBlock:^(RLMNotification _Nonnull notification, RLMRealm * _Nonnull realm) {
/* ... */
}];
// Stop observing
[token invalidate];
let realm = try! Realm()
// Observe and obtain token
let token = realm.observe { notification, realm in /* ... */ }
// Stop observing
token.invalidate()

Realm objects are key-value observing (KVO) compliant for most properties:

  • Casi todas las propiedades gestionadas (no ignoradas) en subclases Object

  • The invalidated property on Object and List

You cannot observe LinkingObjects properties via Key-value observation.

Importante

No se puede agregar un objeto a un realm (con realm.add(obj) o métodos similares) mientras tenga cualquier observador registrado.

Observing the properties of unmanaged instances of Object subclasses works like any other dynamic property.

Observar las propiedades de los objetos gestionados funciona de manera diferente. Con objetos gestionados por Realm, el valor de una propiedad puede cambiar cuando:

  • You assign to it

  • El realm se actualiza, ya sea manualmente con realm.refresh() o automáticamente en un hilo de runloop.

  • You begin a write transaction after changes on another thread

Realm applies changes made in the write transaction(s) on other threads at once. Observers see Key-value observation notifications at once. Intermediate steps do not trigger KVO notifications.

Ejemplo

Say your app performs a write transaction that increments a property from 1 to 10. On the main thread, you get a single notification of a change directly from 1 to 10. You won't get notifications for every incremental change between 1 and 10.

Evitar modificar objetos Realm gestionados desde observeValueForKeyPath(_:ofObject:change:context:). Los valores de propiedad pueden cambiar cuando no se está en una transacción de escritura, o como parte de comenzar una transacción de escritura.

Observing changes made to Realm List properties is simpler than NSMutableArray properties:

  • You don't have to mark List properties as dynamic to observe them.

  • You can call modification methods on List directly. Anyone observing the property that stores it gets a notification.

No necesitas usar mutableArrayValueForKey(_:), aunque Realm sí permite esto para la compatibilidad de código.

Tip

Examples of using Realm with ReactiveCocoa from Objective-C, and ReactKit from Swift.

Puedes observar notificaciones en otro actor. Llamar await object.observe(on: Actor) o await collection.observe(on: Actor) registra un bloque para ser llamado cada vez que el objeto o colección cambie.

// Create a simple actor
actor BackgroundActor {
public func deleteTodo(tsrToTodo tsr: ThreadSafeReference<Todo>) throws {
let realm = try! Realm()
try realm.write {
// Resolve the thread safe reference on the Actor where you want to use it.
// Then, do something with the object.
let todoOnActor = realm.resolve(tsr)
realm.delete(todoOnActor!)
}
}
}
// Execute some code on a different actor - in this case, the MainActor
@MainActor
func mainThreadFunction() async throws {
let backgroundActor = BackgroundActor()
let realm = try! await Realm()
// Create a todo item so there is something to observe
try await realm.asyncWrite {
realm.create(Todo.self, value: [
"_id": ObjectId.generate(),
"name": "Arrive safely in Bree",
"owner": "Merry",
"status": "In Progress"
])
}
// Get the collection of todos on the current actor
let todoCollection = realm.objects(Todo.self)
// Register a notification token, providing the actor where you want to observe changes.
// This is only required if you want to observe on a different actor.
let token = await todoCollection.observe(on: backgroundActor, { actor, changes in
print("A change occurred on actor: \(actor)")
switch changes {
case .initial:
print("The initial value of the changed object was: \(changes)")
case .update(_, let deletions, let insertions, let modifications):
if !deletions.isEmpty {
print("An object was deleted: \(changes)")
} else if !insertions.isEmpty {
print("An object was inserted: \(changes)")
} else if !modifications.isEmpty {
print("An object was modified: \(changes)")
}
case .error(let error):
print("An error occurred: \(error.localizedDescription)")
}
})
// Update an object to trigger the notification.
// This example triggers a notification that the object is deleted.
// We can pass a thread-safe reference to an object to update it on a different actor.
let todo = todoCollection.where {
$0.name == "Arrive safely in Bree"
}.first!
let threadSafeReferenceToTodo = ThreadSafeReference(to: todo)
try await backgroundActor.deleteTodo(tsrToTodo: threadSafeReferenceToTodo)
// Invalidate the token when done observing
token.invalidate()
}

Para obtener más información sobre las notificaciones de cambios en otro actor, consulta Observar notificaciones en un actor diferente.

Al igual que otros objetos de dominio, puedes reaccionar a los cambios en una proyección de clase. Al registrar un detector de cambios de proyección de clase, verás notificaciones de los cambios realizados directamente a través del objeto de proyección de clase. También verás notificaciones de los cambios en las propiedades del objeto subyacente que se proyectan a través del objeto de proyección de clase.

Properties on the underlying object that are not @Projected in the class projection do not generate notifications.

Este bloque de notificación se activa por cambios en:

  • Person.firstName propiedad del objeto Person subyacente de la proyección de clase, pero no cambia a Person.lastName o Person.friends.

  • PersonProjection.firstName propiedad, pero no otra proyección de clase que use la misma propiedad del objeto subyacente.

let realm = try! Realm()
let projectedPerson = realm.objects(PersonProjection.self).first(where: { $0.firstName == "Jason" })!
let token = projectedPerson.observe(keyPaths: ["firstName"], { change in
switch change {
case .change(let object, let properties):
for property in properties {
print("Property '\(property.name)' of object \(object) changed to '\(property.newValue!)'")
}
case .error(let error):
print("An error occurred: \(error)")
case .deleted:
print("The object was deleted.")
}
})
// Now update to trigger the notification
try! realm.write {
projectedPerson.firstName = "David"
}

La entrega de notificaciones puede variar dependiendo de:

  • Si la notificación ocurre o no dentro de una transacción de escritura

  • Los hilos relativos de la guardar y la observación

When your application relies on the timing of notification delivery, such as when you use notifications to update a UITableView, it's important to understand the specific behaviors for your application code's context.

Reading an observed collection or object from inside a change notification always accurately tells you what has changed in the collection passed to the callback since the last time the callback was invoked.

Leer colecciones u objetos fuera de las notificaciones de cambio siempre te da exactamente los mismos valores que viste en la notificación de cambio más reciente para ese objeto.

Al leer objetos distintos del observado dentro de una notificación de cambio, se podría ver un valor distinto antes de que se hubiera entregado la notificación de ese cambio. Realm refresh trae todo el realm desde la 'antigua versión' a la 'última versión' en una sola operación. Sin embargo, puede que se hayan disparado varias notificaciones de cambio entre la 'versión antigua' y la 'versión más reciente'. Dentro de una función de retorno, puedes ver cambios que tengan notificaciones pendientes.

Writes on different threads eventually become visible on the observing thread. Explicitly calling refresh() blocks until the writes made on other threads are visible and the appropriate notifications have been sent. If you call refresh() within a notification callback, it's a no-op.

Al inicio de la transacción de escritura, todos los comportamientos anteriores se aplican a este contexto. Además, siempre puedes esperar ver la versión más reciente de los datos.

Inside a write transaction, the only changes you see are those you've made so far within the write transaction.

Entre la confirmación de una transacción de escritura y el envío del siguiente conjunto de notificaciones de cambio, puede ver los cambios realizados en la transacción de escritura, pero ningún otro cambio. Las escrituras realizadas en diferentes subprocesos no son visibles hasta que recibe el siguiente conjunto de notificaciones. Al realizar otra escritura en el mismo subproceso, se envían primero las notificaciones de la escritura anterior.

Al realizar guardados dentro de notificaciones, se observan muchos de los mismos comportamientos mencionados anteriormente, con algunas excepciones.

Las funciones de retorno invocadas antes de la que realizó un guardado se comportan normalmente. Aunque Realm invoca las funciones de retorno de cambio en un orden estable, este no es estrictamente el orden en que se agregaron las observaciones.

If beginning the write refreshes the realm, which can happen if another thread is making writes, this triggers recursive notifications. These nested notifications report the changes made since the last call to the callback. For callbacks before the one making the write, this means the inner notification reports only the changes made after the ones already reported in the outer notification. If the callback making the write tries to write again in the inner notification, Realm throws an exception. The callbacks after the one making the write get a single notification for both sets of changes.

Una vez que la devolución de llamada completa la escritura y retorna, Realm no invoca ninguna de las devoluciones de llamada posteriores, ya que ya no tienen cambios que reportar. Realm proporciona una notificación posterior de la escritura, como si esta se hubiera producido fuera de ella.

If beginning the write doesn't refresh the realm, the write happens as usual. However, Realm invokes the subsequent callbacks in an inconsistent state. They continue to report the original change information, but the observed object/collection now includes the changes from the write made in the previous callback.

If you try to perform manual checks and write handling to get more fine-grained notifications from within a write transaction, you can get notifications nested more than two levels deep. An example of a manual write handling is checking realm.isInWriteTransaction, and if so making changes, calling realm.commitWrite() and then realm.beginWrite(). The nested notifications and potential for error make this manual manipulation error-prone and difficult to debug.

You can use the writeAsync API to sidestep complexity if you don't need fine-grained change information from inside your write block. Observing an async write similar to this provides notifications even if the notification happens to be delivered inside a write transaction:

let token = dog.observe(keyPaths: [\Dog.age]) { change in
guard case let .change(dog, _) = change else { return }
dog.realm!.writeAsync {
dog.isPuppy = dog.age < 2
}
}

However, because the write is async the realm may have changed between the notification and when the write happens. In this case, the change information passed to the notification may no longer be applicable.

If you only update a UITableView via notifications, in the time between a write transaction and the next notification arriving, the TableView's state is out of sync with the data. The TableView could have a pending update scheduled, which can appear to cause delayed or inconsistent updates.

You can address these behaviors in a few ways.

The following examples use this very basic UITableViewController.

class TableViewController: UITableViewController {
let realm = try! Realm()
let results = try! Realm().objects(DemoObject.self).sorted(byKeyPath: "date")
var notificationToken: NotificationToken!
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
notificationToken = results.observe { (changes: RealmCollectionChange) in
switch changes {
case .initial:
self.tableView.reloadData()
case .update(_, let deletions, let insertions, let modifications):
// Always apply updates in the following order: deletions, insertions, then modifications.
// Handling insertions before deletions may result in unexpected behavior.
self.tableView.beginUpdates()
self.tableView.deleteRows(at: deletions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
self.tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
self.tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic)
self.tableView.endUpdates()
case .error(let err):
fatalError("\(err)")
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let object = results[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = object.title
return cell
}
func delete(at index: Int) throws {
try realm.write {
realm.delete(results[index])
}
}
}

Updating the UITableView directly without waiting for a notification provides the most responsive UI. This code updates the TableView immediately instead of requiring hops between threads, which add a small amount of lag to each update. The downside is that it requires frequent manual updates to the view.

func delete(at index: Int) throws {
try realm.write(withoutNotifying: [notificationToken]) {
realm.delete(results[index])
}
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}

Forcing a refresh() after a write provides the notifications from the write immediately rather than on a future run of the run loop. There's no window for the TableView to read out-of-sync values.

The downside is that this means things we recommend doing in the background, such as writing, rerunning the query and re-sorting the results, happen on the main thread. When these operations are computationally expensive, this can cause delays on the main thread.

func delete(at index: Int) throws {
try realm.write {
realm.delete(results[index])
}
realm.refresh()
}

Realizar una escritura en un hilo en segundo plano bloquea el hilo principal durante el menor tiempo posible. Sin embargo, el código para realizar una escritura en segundo plano requiere mayor familiaridad con el modelo de subprocesos de Realm y el uso de Swift DispatchQueue. Dado que la escritura no ocurre en el hilo principal, este nunca la ve antes de que lleguen las notificaciones.

func delete(at index: Int) throws {
func delete(at index: Int) throws {
@ThreadSafe var object = results[index]
DispatchQueue.global().async {
guard let object = object else { return }
let realm = object.realm!
try! realm.write {
if !object.isInvalidated {
realm.delete(object)
}
}
}
}
}

Changes in nested documents deeper than four levels down do not trigger change notifications.

If you have a data structure where you need to listen for changes five levels down or deeper, workarounds include:

  • Refactorice el esquema para reducir la anidación.

  • Add something like "push-to-refresh" to enable users to manually refresh data.

In the Swift SDK, you can also use key path filtering to work around this limitation. This feature is not available in the other SDKs.

Volver

Filtro de datos