Docs Menu

Handle Sync Errors - Swift SDK

On this page

  • Handle Sync Errors
  • Client Reset
  • Discard Local Changes
  • Manual Client Reset

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.

When using Device 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.

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.

You Still Need a Manual Client Reset Handler

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_APP_SERVICES_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)")

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 Atlas App Services App. 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.

←  Manage Flexible Sync Subscriptions - Swift SDKSync Data in the Background - Swift SDK →
Give Feedback
© 2022 MongoDB, Inc.


  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.