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
/ /
Sync Data

Gestionar sesiones de sincronización: Swift SDK

Al abrir un reino sincronizado se inicia un Sesión de sincronización para ese dominio. El SDK de Swift para dominios proporciona métodos para pausar y reanudar manualmente una sesión de sincronización.

New in version 10.41.0.

En la versión 10.41.0 y posteriores del SDK de Realm Swift, App Services comparte una única conexión al servidor de forma predeterminada para todos los reinos sincronizados abiertos. Esto supone un cambio respecto a versiones anteriores, donde al abrir más de un reino sincronizado se abrían conexiones adicionales al servidor. La conexión al servidor es independiente de... SyncSession, y se basa en el usuario de App Services.

You can change this behavior from the App client configuration.

Tip

Realm's offline-first design means that you generally don't need to check the current network connection state. That said, the connectionState property is available if your app calls for some indication of connection state.

To check the connection state, you can read the synced realm's RLMSyncSession instance's connectionState property directly.

Esta propiedad cumple con la normativa KVOPara que puedas observar los cambios usando KVO. El siguiente ejemplo muestra cómo implementar una clase observadora:

@interface MySyncSessionObserver: NSObject
@end
@implementation MySyncSessionObserver
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (![object isKindOfClass:RLMSyncSession.class]) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if (![keyPath isEqualToString:@"connectionState"]) {
// Not interested in observing this keypath
return;
}
RLMSyncSession *syncSession = (RLMSyncSession *)object;
RLMSyncConnectionState connectionState = [syncSession connectionState];
switch (connectionState) {
case RLMSyncConnectionStateConnecting:
NSLog(@"Connecting...");
break;
case RLMSyncConnectionStateConnected:
NSLog(@"Connected");
break;
case RLMSyncConnectionStateDisconnected:
NSLog(@"Disconnected");
break;
}
}
@end

Luego puedes adjuntar una instancia de observador al objeto RLMSyncSession. Asegúrate de remover el observador cuando hayas terminado.

// Observe connectionState for changes using KVO
MySyncSessionObserver *observer = [[MySyncSessionObserver alloc] init];
[syncSession addObserver:observer
forKeyPath:@"connectionState"
options:NSKeyValueObservingOptionInitial
context:nil];
// Later, when done...
[syncSession removeObserver:observer
forKeyPath:@"connectionState"
context:nil];

To check the connection state, you can read the synced realm's SyncSession instance's connectionState property directly.

This property is KVO-compliant, so you can observe changes using KVO or even Combine.

// Observe connectionState for changes using KVO
let observer = syncSession.observe(\.connectionState, options: [.initial]) { (syncSession, change) in
switch syncSession.connectionState {
case .connecting:
print("Connecting...")
case .connected:
print("Connected")
case .disconnected:
print("Disconnected")
default:
break
}
}
// Observe using Combine
let cancellable = syncSession.publisher(for: \.connectionState)
.sink { connectionState in
switch connectionState {
case .connecting:
print("Connecting...")
case .connected:
print("Connected")
case .disconnected:
print("Disconnected")
default:
break
}
}

You can suspend and resume the sync session on the realm. Pausing a sync session only suspends that realm's sync session. If you have more than one open realm, suspend does not affect the sync sessions for other realms.

Puede suspender o reanudar una sesión de sincronización utilizando la instancia RLMSyncSession de un reino sincronizado.

RLMRealm *syncedRealm = [RLMRealm realmWithConfiguration:configuration error:nil];
RLMSyncSession *syncSession = [syncedRealm syncSession];
// Suspend synchronization
[syncSession suspend];
// Later, resume synchronization
[syncSession resume];

You can suspend or resume a sync session using the SyncSession instance of a synced realm.

let syncSession = syncedRealm.syncSession!
// Suspend synchronization
syncSession.suspend()
// Later, resume synchronization
syncSession.resume()

For most applications, there is no need to manually pause and resume a sync session. However, there are a few circumstances under which you may want to pause or suspend a sync session:

  • You only want to sync after the user takes a specific action

  • You only want to sync during a certain time of the day

  • No debes intentar sincronizar cuando hay una mala conectividad de red

  • You want to explicitly force a sync session to connect

In the case of poor network connectivity, continually trying to establish a network connection can drain the user's device battery.

The case of explicitly forcing a sync session to connect is most commonly related to being offline for some time. The sync client attempts to connect, and upon failure, goes into exponential backoff. After being offline for a long time, the client may not immediately reconnect. Pausing and resuming the sync session explicitly forces the connection.

When you do pause a sync session, keep these things in mind:

  • If the client may be offline longer than the client maximum offline time, the client will be unable to resume syncing and must perform a client reset.

  • Pausing a sync session pauses it in both directions. Changes that your app makes on the device do not sync with the backend, and changes to the data in the backend or on other devices do not sync to the device. There is no way to pause only uploads or pause only downloads.

  • No pause una sesión de sincronización si desea que un cliente deje de sincronizarse permanentemente con el backend. Para ello, copie el contenido del dominio sincronizado en uno no sincronizado y utilice este último en el cliente.

No pauses la sincronización para detener la sincronización por períodos de tiempo indefinidos o rangos de meses y años. La funcionalidad no está diseñada ni probada para estos casos de uso. Podrías encontrar un rango de problemas al usarlo de esta manera.

New in version 10.45.0.

To wait for all changes to upload or download from your synced realm, call realm.syncSession?.wait(for: ).

Este método toma un argumento ProgressDirection para especificar si se debe realizar un seguimiento del progreso de carga o descarga.

You can use these methods with Swift's async/await syntax, or with the callback syntax. The callback version, realm.syncSession?.wait(for:queue:block:), can take a queue to dispatch the callback onto, and a block to invoke when waiting is complete.

// Wait to download all pending changes from Atlas
try await realm.syncSession?.wait(for: .download)
// Add data locally
try realm.write {
realm.create(Task.self, value: [
"taskName": "Review proposal",
"assignee": "Emma",
"completed": false,
"progressMinutes": 0,
"dueDate": date
])
}
// Wait for local changes to be uploaded to Atlas
try await realm.syncSession?.wait(for: .upload)
// Wait to download all pending changes from Atlas
realm.syncSession?.wait(for: .download, block: { _ in
// You can provide a block to execute
// after waiting for download to complete
})
// Add data locally
do {
try realm.write {
realm.create(Task.self, value: [
"taskName": "Review proposal",
"assignee": "Emma",
"completed": false,
"progressMinutes": 0,
"dueDate": date
])
}
} catch {
print("There was an error writing to realm: \(error.localizedDescription)")
}
// Wait for local changes to be uploaded to Atlas
realm.syncSession?.wait(for: .upload, block: { _ in
// You can provide a block to execute after
// waiting for upload to complete
})

Cambiado en la 10.50.0 versión: transferredBytes y quedaron transferrableBytes obsoletos en favor de progressEstimate

Puedes comprobar el progreso de las cargas y descargas registrando un token que proporcione una progressEstimate para una carga o descarga específica y el ámbito del trabajo. Puedes establecer un ProgressMode para determinar el ámbito del trabajo: observar indefinidamente o anular el registro del bloque después de que se haya completado el elemento de trabajo actual.

El valor progressEstimate proporcionado por el token es un valor doble cuyo valor oscila entre 0.0 y 1.0. En 1.0, la carga o descarga se completa. Puede usar este progressEstimate para mostrar un indicador de progreso o un porcentaje estimado de transferencia de datos.

Changed in version 10.50.0: addProgressNotificationForDirection deprecated in favor of addSyncProgressNotificationForDirection

Puede añadir una notificación de progreso usando la instancia RLMSyncSession del realm sincronizado con el método [--addSyncProgressNotificationForDirection:moda:block:].

This method returns a token that you should retain until you wish to stop observing upload or download progress. Note that if you keep the token in a local variable, observation will stop when the local variable goes out of scope.

RLMSyncSession *syncSession = [syncedRealm syncSession];
RLMProgressNotificationToken *token = [syncSession
addSyncProgressNotificationForDirection:RLMSyncProgressDirectionUpload
mode:RLMSyncProgressModeForCurrentlyOutstandingWork
block:^(RLMSyncProgress syncProgress) {
NSLog(@"Uploaded %fB", (double)syncProgress.progressEstimate);
}];
// Upload something
[syncedRealm transactionWithBlock:^{
[syncedRealm addObject:[[Task alloc] init]];
}];

You can add a progress notification using the synced realm's SyncSession instance's addProgressNotification(for:mode:block:) method.

This method returns a token that you should retain until you wish to stop observing upload or download progress. Note that if you keep the token in a local variable, observation will stop when the local variable goes out of scope.

let syncSession = realm.syncSession!
let token = syncSession.addProgressNotification(
for: .upload, mode: .forCurrentlyOutstandingWork) { (progress) in
let progressEstimate = progress.progressEstimate
let transferPercent = progressEstimate * 100
print("Uploaded (\(transferPercent)%)")
}

New in version 10.44.0.

Realm automatically detects when a device regains connectivity after being offline and attempts to reconnect using an incremental backoff strategy. For example, on Apple platforms, Realm listens for network change notifications and automatically triggers a reconnect immediately after receiving one.

En la versión 10.44.0 y posteriores del SDK de Swift, puedes elegir activar manualmente un intento de reconexión con SyncSession.reconnect() en vez de esperar la duración de la retroceso incremental. Esto es útil si tienes una comprensión más precisa de las condiciones de la red y no deseas depender de la detección automática de reconexión de Realm.

let syncSession = realm.syncSession!
// Work with the realm. When you need to force the sync session to reconnect...
syncSession.reconnect()

When you call this method, the SDK forces all sync sessions to attempt to reconnect immediately. This resets any timers used for incremental backoff.

Calling this method does not guarantee the device can reconnect. If the SDK gets a fatal error, or if the device is already connected or is trying to connect, calling this method has no effect.

Importante

Cannot Reconnect Within Socket Read Timeout Duration

Realm tiene un tiempo de espera interno por defecto para la lectura de socket de 2 minutos; Realm dará tiempo de espera si una operación de lectura no recibe ningún dato dentro de una ventana de 2 minutos. Si llamas a SyncSession.reconnect() dentro de esa ventana, el SDK de Swift no intentará reconectar.

Volver

Sync Data in the Background

En esta página