In one of my Simperium powered apps, I'm currently trying to implement a clean experience for users when signing out from their sync account, signing in to a sync account with existing data, switching accounts etc.
What I want to achieve is the following (suggestions welcome, if that doesn't make any sense):
- When signing out of a sync account, I don't want to delete anything locally, so the user can continue using the data (which is also important because syncing is a premium feature and the user might cancel it).
- When creating a new sync account (which obviously doesn't contain any data), I want to retain the local data and sync it up to the new account (which makes sense if someone starts using the app without sync and then activates sync later).
- However, when signing in to an existing sync account with existing data, I need to prevent merging hell between the local and the remote data (imagine someone switching accounts!). I think that completely overwriting the local data with the remote data is what makes most sense here.
Simperium does not seem to directly support my approach, but rather only offers to delete the data upon sign out. While trying to bend Simperium to my needs, I'm currently facing two issues/questions:
What is the preferred way to delete all local data (including all Simperium meta data, including that in user defaults)? NB: I need to do this while the user is NOT logged in to Simperium, so I can't use
signOutAndRemoveLocalData:YES. I guess I need to do something like[self.buckets.allValues makeObjectsPerformSelector:@selector(deleteAllObjects)];(which is done in the sign out completion handler), but I can't find any public interface for this. Would it be save to just delete all objects directly via CoreData, or would that leave anything in user defaults that could cause issues later, for example?I noticed that Simperium leaves its ghost data intact after signing out. This causes massive issues when signing in to another (in my case new) account, because it doesn't treat the objects as new objects to be synced up, but rather deletes all local objects (presumably because it can't find it on the remote)!
- Is this really the intended behavior? I'd expect Simperium to get rid of all sync metadata after signing out, even if the data itself is not removed. Even more so in the case of the ghost data, because this data is tied directly to the sync account - it represents the remote state of the object, and I'd argue that after signing out there is no remote state anymore (because there is no "remote").
- Anyways, what's the best way for me to reset the ghost data back to the initial clean state (that is, probably something like
{ "key" : "...", "version" : "0" })? I could do that manually, but that feels like massively interfering with the internals of Simperium.
Sorry for this lengthy question.. Any help/pointers very much appreciated, thanks!
Update/clarification
My goal is really not so much to carry data on from one account to another. Actually, as I said, my plan was to delete all local data before signing into an exising account, which should prevent any problems like duplicates - the client just discards its local state completely and uses whatever is currently stored in the remote sync account. The only case where the retained ghost data causes me problems is this:
- App currently syncing with Account A.
- User signs out from Account A (using
signOutAndRemoveLocalData:NO completion:). - User happily continues to use the app (perhaps for quite a while)
- User creates a new sync account B (that is, one that does not contain any data on the server). Now, with the default behavior, Simperium will delete all local objects that contain ghost data with version > 0 (but will leave any objects that have been created while not signed in to any sync account, thus leaving the database in a potentially invalid state with broken relationships etc.).
I just don't think that this is the behavior that the user would expect and I'm sure it will lead to many support inqueries...
My authentication flow looks exactly like you suggested: I have my own backend that manages subscriptions and generates the auth token via the Simperium Auth API and sends it to the client. But I don't really see how this solves my problems. I completely agree that it's not a common use case that users switch sync accounts (although the situation is a bit different than for mail accounts, because you can use it without sync), and I definitely don't want to encourage users to do that. My problem is that, even if it's something that happens only rarely, it should not break the app. And I don't know how I could prevent users from doing it, because they can always freely decide to signout and sign up/in again.
What behavior would you suggest to ensure a good UX? Always delete local data upon sign out?