How to handle Realm Sync client reset in complex app

I’m trying to implement Client Reset for Realm Sync, using this popular example.

During this process, from what I understand, we must follow these steps:

  1. Invalidate and remove all references to realms, realm objects, etc…
  2. Call Realm.deleteFiles(for:) to delete the files
  3. Call SyncSession.immediatelyHandleError(clientResetToken, syncManager: app.syncManager). I have no idea what that does. In the example, it is said that this “clears the old realm files and makes a backup in recovered-realms”. But shouldn’t the previous step delete realm files already?
  4. Copy the automatically generated backup to a safe and known location

Now, I’m struggling with the first step. In the example, there is only one view controller, and few realm references, so it can remove them manually. But in my app, and in many production apps I believe, the situation is way more complex, because:

  • The realm is opened in different view controllers (at the same time, if there is a tab bar structure)
  • References to the realm objects are kept in a lot of places. For instance, if you have a UITableView or a UICollectionView, it keeps references to a lot of objects.
  • The sync error handler callback is not called directly, so the app has time to load plenty of references to Realm.

So it’s basically very complicated to remove all references to realm. It is in fact stated in the docs that:

In practice, there are two safe times to delete the realm file:

  1. On application startup before ever opening the realm.
  2. After only having opened the realm within an explicit autorelease pool, which ensures deallocation of all of objects within it.

So I believe a better way to handle client reset would be to store all data needed for a client reset, ask the user to restart the app, and perform the client reset at startup, before any reference to realm is made. But I don’t know how to store the clientResetToken that is needed in step 3.

Does anybody have a good example of client reset that is actually usable for a complex app?

Hi Jean-Baptiste_Beau,

Your summary is only partially correct: step 2 isn’t needed (in fact, the sample code calls realmCleanup() with a default delete set to false), and is actually wrong, files don’t need to be deleted, quite the contrary!

SyncSession.immediatelyHandleError(…) does indeed what’s in the description: the purpose is to make a backup file that can be later opened as a local realm, in order to proceed with the restore. Obviously, if you don’t care about changes that may have happened locally, you can skip this step, and delete the backup, but only after it’s been processed.

It’s correct that probably in many cases it will be difficult to close all references to realms properly (albeit probably using weak references might help - if you’ve strong references everywhere, it’s easy to forget about ownership, and end up with memory leaks!), still the SyncSession.immediatelyHandleError(…) must be called ASAP, as it’s critical to ensure data is not lost.

1 Like

Hi @Paolo_Manna,

Thank you for your answer and for the clarifications.

So if I understand correctly, there is no other solution that invalidating all the references in the app and call the SyncSession method? It’s not possible to move the cleanup and backup code to the next time the app is opened?

This makes me wonder if I shouldn’t have only one static reference to the realm in the whole app. Are there any problem with doing this? This would make it easy to delete the reference.

So if I understand correctly, there is no other solution that invalidating all the references in the app and call the SyncSession method?

Clearing all the references is needed if you want to re-open the same realm immediately, but, if you try to comment out the realmCleanup() call right before SyncSession.immediatelyHandleError(…) in the sample code, you’ll see that most of the rest is still working, it just hangs when calling openRealm(), quite understandably because references weren’t cleared. I personally haven’t experimented to force the user to exit the app, you may want to have a go at it.

This makes me wonder if I shouldn’t have only one static reference to the realm in the whole app.

It can certainly work, providing however that you handle the threading properly.

1 Like

Got it, thank you for your answers.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.