Manejar errores de sincronización
While developing an application that uses Device Sync, you should set an error handler. This error handler will detect and respond to any failed sync-related API calls.
Tip
Para obtener una lista de errores comunes de sincronización de dispositivos y cómo solucionarlos, consulte Errores de sincronización en la documentación de sincronización de dispositivos de App Services.
Establezca un controlador de errores en el singleton RLMSyncManager. Cuando se produce un error, el SDK de Swift llama al controlador de errores con el objeto de error y la sesión RLMSyncSession donde se produjo el error.
Nota
Realm representa los errores de sincronización mediante objetos NSError cuyo dominio es RLMSyncErrorDomain. Para aprender más sobre los códigos de error, consulta las definiciones de RLMSyncError y RLMSyncAuthError.
RLMApp *app = [RLMApp appWithId:YOUR_APP_ID]; // Access the sync manager for the app RLMSyncManager *syncManager = [app syncManager]; syncManager.errorHandler = ^(NSError *error, RLMSyncSession *session) { // handle error };
Set an error handler on the SyncManager singleton. Set an error handler on the SyncManager singleton. When an error occurs, the Swift SDK calls the error handler with the error object and the SyncSession that the error occurred on.
Nota
SyncError de Realm se ajusta al protocolo de errores de Swift
let app = App(id: YOUR_APP_SERVICES_APP_ID) app.syncManager.errorHandler = { error, session in // handle error }
Tip
Para obtener información sobre cómo establecer un nivel de registro del cliente o personalizar el registrador, consulte Establecer el nivel de registro del cliente - Swift SDK.
Restablecimiento del cliente
Al usar la Sincronización de Dispositivos, el restablecimiento del cliente es una tarea de recuperación de errores que la aplicación cliente debe realizar cuando un dominio sincronizado en el servidor ya no puede sincronizarse con el dominio del cliente. En este caso, el cliente debe restablecer su dominio a un estado que coincida con el del servidor para poder restablecer la sincronización.
When this occurs, the unsyncable realm on the client may contain data that has not yet synced to the server. Realm SDKs can attempt to recover or discard that data during the client reset process.
Para obtener más información sobre qué podría provocar que se restablezca un cliente, vaya a Restablecimientos de cliente en la documentación de Servicios de aplicaciones.
Automatic vs. Manual Client Reset
Los SDK de Realm ofrecen modos de restablecimiento de cliente que gestionan automáticamente la mayoría de los errores de restablecimiento. Los modos de restablecimiento automático de cliente restauran el archivo local de Realm a un estado sincronizable sin cerrarlo ni perder notificaciones.
Todos los modos de reinicio del cliente excepto .manual Realizar un restablecimiento automático del cliente. Las diferencias entre los modos se basan en cómo gestionan los cambios en el dispositivo que aún no se han sincronizado con el backend.
Elige .recoverUnsyncedChanges para gestionar automáticamente la mayoría de los escenarios de restablecimiento del cliente. Esto intenta recuperar los cambios no sincronizados cuando ocurre un restablecimiento del cliente.
In some cases, you may want or need to set a manual client reset handler. You may want to do this if your app requires specific client reset logic that can't be handled automatically.
Specify a Client Reset Mode
Cambiado en la versión 10.32.0: Se agregó recuperación de cliente, se cambió el nombre de discardLocal
El SDK de Swift ofrece la opción de especificar un modo de restablecimiento de cliente en SyncConfiguration.Esta es la propiedad `.clientResetMode`.
// Specify the clientResetMode when you create the SyncConfiguration. // If you do not specify, this defaults to `.recoverUnsyncedChanges` mode. var configuration = user.flexibleSyncConfiguration(clientResetMode: .recoverUnsyncedChanges())
Esta propiedad toma una enumeración que representa los diferentes modos de reinicio del cliente:
.recoverUnsyncedChanges.recoverOrDiscardUnsyncedChanges.discardUnsyncedChanges.manual
Si no se especifica .clientResetMode en la configuración, el modo de restablecimiento del cliente predeterminado es a .recoverUnsyncedChanges.
You can specify a before and after block to execute during the automatic client reset process. You might use this to perform recovery logic that is important to your application.
// A block called after a client reset error is detected, but before the // client recovery process is executed. // This block could be used for any custom logic, reporting, debugging etc. // This is one example, but your usage may vary. let beforeClientResetBlock: (Realm) -> Void = { before in var recoveryConfig = Realm.Configuration() recoveryConfig.fileURL = myRecoveryPath do { try before.writeCopy(configuration: recoveryConfig) // The copied realm could be used later for recovery, debugging, reporting, etc. } catch { // handle error } } // A block called after the client recovery process has executed. // This block could be used for custom recovery, reporting, debugging etc. // This is one example, but your usage may vary. let afterClientResetBlock: (Realm, Realm) -> Void = { before, after in // let res = after.objects(myClass.self) // if (res.filter("primaryKey == %@", object.primaryKey).first != nil) { // // ...custom recovery logic... // } else { // // ...custom recovery logic... // } // } } do { let app = App(id: YOUR_APP_SERVICES_APP_ID) let user = try await app.login(credentials: Credentials.anonymous) var configuration = user.flexibleSyncConfiguration(clientResetMode: .recoverOrDiscardUnsyncedChanges( beforeReset: beforeClientResetBlock, afterReset: afterClientResetBlock)) } catch { print("Error logging in user: \(error.localizedDescription)") }
Si su aplicación tiene necesidades específicas de recuperación de clientes, puede especificar el .manual modo de restablecimiento de cliente y configurar un controlador manual de restablecimiento de cliente. Puede hacerlo si su aplicación debe ejecutar una lógica personalizada específica durante un restablecimiento de cliente o si las reglas de recuperación de cliente no funcionan.
Nota
Si su aplicación utiliza Swift SDK versión 10.24.2 o anterior, .clientResetMode no es una propiedad disponible en SyncConfiguration.
Handle Schema Changes
Client Recovery is a feature that is enabled by default when you configure Device Sync. When Client Recovery is enabled, Realm can automatically manage the client reset process in most cases. When you make schema changes:
The client can recover unsynced changes when there are no schema changes, or non-breaking schema changes.
Al realizar cambios de esquema disruptivos, los modos de restablecimiento automático del cliente recurren a un gestor de errores manual. Puede configurar un gestor de errores de restablecimiento manual del cliente para este caso. La recuperación automática del cliente no puede ocurrir cuando su aplicación realiza cambios de esquema disruptivos.
For information on breaking vs. non-breaking schema changes, see Breaking vs. Non-Breaking Change Quick Reference.
Recuperar cambios no sincronizados
Novedades en la versión 10.32.0.
Durante un restablecimiento de cliente, las aplicaciones cliente pueden intentar recuperar datos del dominio local que aún no se hayan sincronizado con el backend. Para recuperar los cambios no sincronizados, laRecuperación de Cliente debe estar habilitada en la aplicación de Servicios de Aplicaciones, como está predeterminado.
Si quieres que tu aplicación recupere cambios que aún no se han sincronizado, establece el .clientResetMode en la SyncConfiguration a uno de:
.recoverUnsyncedChanges: When you choose this mode, the client attempts to recover unsynced changes. Choose this mode when you do not want to fall through to discard unsynced changes..recoverOrDiscardUnsyncedChangesEl cliente primero intenta recuperar los cambios que aún no se han sincronizado. Si no puede recuperar los datos no sincronizados, descarta los cambios no sincronizados, pero continúa reiniciando el cliente automáticamente. Seleccione este modo si desea habilitar la recuperación automática del cliente para descartar los cambios no sincronizados.
// Specify the clientResetMode when you create the SyncConfiguration. // If you do not specify, this defaults to `.recoverUnsyncedChanges` mode. var configuration = user.flexibleSyncConfiguration(clientResetMode: .recoverUnsyncedChanges())
Es posible que, en ocasiones, la operación de restablecimiento del cliente no pueda completarse en el modo de recuperación de cambios no sincronizados, como cuando hay cambios de esquema importantes o la recuperación del cliente está deshabilitada en la configuración de sincronización de dispositivos. Para solucionar este problema, la aplicación puede implementar una alternativa de restablecimiento manual del cliente.
Client Recovery Rules
Cuando la Recuperación de Cliente está habilitada, estas reglas determinan cómo se integran los objetos, incluyendo la resolución de conflictos cuando tanto el backend como el cliente realizan cambios en el mismo objeto:
Objects created locally that were not synced before client reset are synced.
Si se elimina un objeto en el servidor, pero se modifica en el cliente en recuperación, la eliminación tiene prioridad y el cliente descarta la actualización.
If an object is deleted on the recovering client, but not the server, then the client applies the server's delete instruction.
En el caso de actualizaciones conflictivas en el mismo campo, se aplica la actualización del cliente.
Descartar cambios no sincronizados
Changed in version 10.32.0: .discardLocal changed to .discardUnsyncedChanges
The discard unsynced changes client reset mode permanently deletes all local unsynced changes made since the last successful sync. You might use this mode when your app requires client recovery logic that is not consistent with the Device Sync Client Recovery Rules, or when you don't want to recover unsynced data.
Do not use discard unsynced changes mode if your application cannot lose local data that has not yet synced to the backend.
Para realizar un restablecimiento automático del cliente que descarte cambios no sincronizados, establece el .clientResetMode en el SyncConfiguration a .discardUnsyncedChanges.
do { let app = App(id: APP_ID) let user = try await app.login(credentials: Credentials.anonymous) var config = user.flexibleSyncConfiguration(clientResetMode: .discardUnsyncedChanges()) } catch { print("Error logging in user: \(error.localizedDescription)") }
Nota
Descartar con Recuperación
If you'd like to attempt to recover unsynced changes, but discard any changes that cannot be recovered, refer to the .recoverOrDiscardUnsyncedChanges documentation in Recover Unsynced Changes.
Puede haber ocasiones en las que la operación de restablecimiento del cliente no se pueda completar en modo de descartar cambios no sincronizados, como cuando hay cambios de esquema incompatibles. Para manejar este caso, tu aplicación puede implementar un restablecimiento del cliente manual como alternativa.
Modo de restablecimiento manual del cliente
Cuando especifique .manual para .clientResetMode, se debe implementar un gestor de restablecimiento manual del cliente.
En modo .manual, defines tu propio gestor de restablecimiento del cliente. El controlador puede aceptar un ErrorReportingBlock. Se recomienda usar los modos automáticos de recuperación de clientes cuando sea posible, y elegir el modo .manual solo si la lógica de recuperación automática no es adecuada para tu aplicación.
do { let app = App(id: APP_ID) let user = try await app.login(credentials: Credentials.anonymous) var config = user.flexibleSyncConfiguration(clientResetMode: .manual()) } catch { print("Error logging in user: \(error.localizedDescription)") }
Tip
Si está utilizando una versión anterior del SDK y desea ver un ejemplo de cómo podría recuperar cambios de forma manual en un restablecimiento manual del cliente, consulte este ejemplo en GitHub.
Manual Client Reset Fallback
Si la operación de restablecimiento del cliente no puede completarse automáticamente, como cuando se producen cambios drásticos en el esquema, el proceso de restablecimiento del cliente pasa a un manejador de errores manual. Esto puede ocurrir en cualquiera de estos modos automáticos de restablecimiento del cliente:
.recoverUnsyncedChanges.recoverOrDiscardUnsyncedChanges.discardUnsyncedChanges
Puede configurar un controlador de errores para este caso de respaldo mediante la instancia de RLMSyncManager en su RLMApp. Recomendamos usar el controlador manual como herramienta para situaciones de recuperación de errores fatales en las que se recomienda a los usuarios actualizar la aplicación o realizar alguna otra acción.
RLMApp *app = [RLMApp appWithId:YOUR_APP_ID]; [[app syncManager] setErrorHandler:^(NSError *error, RLMSyncSession *session) { if (error.code == RLMSyncErrorClientResetError) { // TODO: Invalidate all open realm instances // TODO: Restore the local changes backed up at [error rlmSync_clientResetBackedUpRealmPath] [RLMSyncSession immediatelyHandleError:[error rlmSync_errorActionToken] syncManager:[app syncManager]]; return; } // Handle other errors... }];
You can set an error handler for this fallback case via the SyncManager. We recommend treating the manual handler as a tool for fatal error recovery situations where you advise users to update the app or perform some other action.
func handleClientReset() { // Report the client reset error to the user, or do some custom logic. } do { let app = App(id: APP_ID) let user = try await app.login(credentials: Credentials.anonymous) var config = user.flexibleSyncConfiguration(clientResetMode: .recoverOrDiscardUnsyncedChanges()) // If client recovery fails, app.syncManager.errorHandler = { error, session in guard let syncError = error as? SyncError else { fatalError("Unexpected error type passed to sync error handler! \(error)") } switch syncError.code { case .clientResetError: if let (path, clientResetToken) = syncError.clientResetInfo() { handleClientReset() SyncSession.immediatelyHandleError(clientResetToken, syncManager: app.syncManager) } default: // Handle other errors... () } } } catch { print("Error: \(error.localizedDescription)") }
Test Client Reset Handling
Puede probar manualmente el manejo de restablecimiento del cliente de su aplicación finalizando y volviendo a habilitar la sincronización del dispositivo.
When you terminate and re-enable Sync, clients that have previously connected with Sync are unable to connect until after they perform a client reset. Terminating Sync deletes the metadata from the server that allows the client to synchronize. The client must download a new copy of the realm from the server. The server sends a client reset error to these clients. So, when you terminate Sync, you trigger the client reset condition.
To test client reset handling:
Write data from a client application and wait for it to synchronize.
Termina y vuelve a habilitar Device Sync.
Ejecuta la aplicación cliente nuevamente. La aplicación debería obtener un error de restablecimiento del cliente cuando intente conectarse al servidor.
Advertencia
Mientras itera sobre la gestión del restablecimiento de clientes en su aplicación cliente, es posible que tenga que finalizar y volver a habilitar la sincronización repetidamente. Esto impide que todos los clientes existentes puedan sincronizar hasta después de completar un restablecimiento. Para evitar esto en producción, pruebe la gestión del restablecimiento de clientes en un entorno de desarrollo.