Client Resets - Swift SDK
On this page
When using Realm Sync, a client reset is a serious error recovery task that your client app must perform in the following situation:
- The given synced realm on the server was restored from a backup. For example, due to a Realm server crash.
- The client app made changes to that realm since the backup was made, but did not sync those changes back to the server before the server was restored.
In other words, the client app must carry out a client reset on a given synced realm if the server is restored to a version older than the version on the client.
A client reset discards local data and reverts to the data stored in MongoDB Atlas. Performing a client reset loses all local changes made since the client last successfully synced, unless manually recovered by the developer.
New in version 10.25.0.
Starting in 10.25.0, the Swift SDK provides the option to specify a client reset strategy in your SyncConfiguration. This is the .clientResetMode property.
// Specify the clientResetMode when you create the SyncConfiguration. // If you do not specify, this defaults to `.manual` mode. var configuration = user.configuration(partitionValue: "myPartition", clientResetMode: .discardLocal(beforeClientResetBlock, afterClientResetBlock))
This property takes an enum representing the different client reset strategies:
.discardLocal
.manual
If you do not specify .clientResetMode
in your configuration, it
defaults to .manual
.
Discard Local Changes
When you specify .discardLocal
for .clientResetMode
, Realm
automatically performs a client reset with minimal code and minimal disruption
to your application workflow. This client reset mode restores your local
realm file to a syncable state without closing the realm or missing
notifications.
Be aware: this strategy permanently deletes all local unsynced changes
made since the last successful sync. To incorporate changes, you must
recover them manually with a client reset handler. Do not use .discardLocal
mode if
your application cannot lose local data that has not yet synced to the backend.
If the client reset operation cannot complete in discard local changes mode, the client reset process reverts to manual mode.
The .discardLocal version of client reset mode can take a before and after block. This gives you the option to specify additional logic to execute before or after a client reset occurs. You might use these blocks to send reporting or perform custom recovery logic, such as copying the realm to a local directory and using your own logic to apply local changes.
Some conditions, such as breaking or destructive schema changes, may cause .discardLocal
client reset mode to fail. When Realm cannot perform the discard local
client reset operation, the process reverts to manual mode. For this
reason, you should continue to provide a manual client reset
handler even if you prefer to use
.discardLocal
mode.
You can specify a before and after block to execute during the client reset process. You might use this to perform recovery logic that is important to your application.
let beforeClientResetBlock: (Realm) -> Void = { before in // This block could be used to back-up a realm file, send reporting, etc. } let afterClientResetBlock: (Realm, Realm) -> Void = { before, after in // This block could be used to add custom recovery logic, send reporting, etc. } do { let app = App(id: YOUR_REALM_APP_ID) let user = try await app.login(credentials: Credentials.anonymous) // Specify the clientResetMode when you create the SyncConfiguration. // If you do not specify, this defaults to `.manual` mode. var configuration = user.configuration(partitionValue: "myPartition", clientResetMode: .discardLocal(beforeClientResetBlock, afterClientResetBlock)) } catch { print("Error logging in user: \(error.localizedDescription)") }
Manual Client Reset
When you specify .manual
for .clientResetMode
, or if you do not
specify a client reset mode, you should implement your own client reset handler.
If your app uses 10.24.2 or earlier, .clientResetMode
is not an
available property on the SyncConfiguration. Older SDK versions use the manual
client reset handler.
In .manual
mode, the SDK copies the local realm file into a recovery
directory, and deletes the original. The next time your app opens the realm
for that partition, the SDK downloads a new copy of the realm. This new realm
contains all of the data from the backend, and synchronizes as normal.
You can choose to write a handler to incorporate any local changes that exist
in the old copied realm file into the newly downloaded realm.
The SDK performs client resets automatically on startup when instructed to do so by the server. When a client reset occurs, the SDK creates a backup of local data. By default, the SDK makes no effort to recover lost local changes from this backup. However, you can manually override the client reset handler to transfer data from the backup copy to the new realm.
If you override the client reset handler, you can access this backup copy through the path stored in the SyncError to manually transfer data from the backup copy to the newly created realm.
To see how to recover unsynced local changes in a client reset, check out this example on GitHub.