Core Data Sync - Remote Object Tracking

I am setting up a basic synchronization service for the iPad application that I am developing. The goal is to ensure that the data is consistent across multiple instances of the iPad application and also has a read-only version of the data on the Internet, therefore, the user solution is scanned.

The current thread is as follows:

  • Each object has a "created", "modified" and "UUID" field, which is automatically updated using Core Data li>
  • During synchronization, each object with a created or changed date after the last synchronization date is serialized in JSON and sent to the server
  • The server saves any changes to the MySQL database using client UUIDs in the form of PK (if there is a conflict, it simply uses the last modified object as the “true” version, nothing unusual there) and sends back any updated objects for the client
  • The client then merges these changes into its base data DB

It all works fine. My problem is how to track deleted objects using this method? I assume that I can add a “remote” flag for each object and set it every time the client deletes something, then I can push this change to the server with the rest of the synchronization data. Once synchronization is complete, the client can actually delete these objects. My questions:

  • Can I override the master data deletion methods to automatically set this flag?
  • Will it require endless storage of all deleted objects on the server? We will not know when each client synchronized and actually deleted each object (I do not currently track client instances)
  • Is there a better way to do this?
+6
source share
5 answers

How about you save a delta history table with a UUID and create / update / delete a field, possibly with a revision number for each update? This way you keep a small checklist of changes since the last successful synchronization.

Thus, if you delete an object, you can add an entry to the delta history table with the removed UUID and mark it deleted. The same thing with created and updated objects, you only need to check the delta table to see which items you need to delete, update, create, etc. You can even save each revision on the server to support a return to a previous version in the Future, if you so wish.

I think the version number is better than relying on client watches, which could potentially be changed manually.

You can use the NSManagedObjectContext insertObjects, updatedObjects, deletedObjects methods to create delta objects before each save procedure :)

My 2 cents

+5
source

Regarding your second question: you can design it so that the server does not need to delete deleted records if you want. Let each application know whether a given piece of data is stored on this server (based on its UUID) (for example, add the existOnServer or similar property). This starts with false when a new item is created in the application, but set to true as soon as it was synchronized with the server for the first time. Thus, if the application tries to synchronize later, but the UUID is not found, you can distinguish between two cases: If existsOnServer is false, then this element will be created and must be synchronized with the server, but if it is true then this may mean that it Already been on the server before, but now deleted, so you can also delete it in the application.

I would probably object to this approach, since it seems to me that it seems more prone to errors (I believe that a database or connection error that is incorrectly interpreted as deleting) and maintaining records on your server will usually not be a big problem. but it is possible. The “delta approach” proposed by dzeikei can be used simultaneously, therefore updating an entry that does not exist on the server means that it has been deleted and there is no insertion.

+1
source

Whether you need to save remote objects on the server or not completely depends on your needs. You will need a remote flag locally to mark it as remote for synchronization, possibly also on the server, depending on your desire to rollback.

I already took a little care of this problem. Here is one of the possibilities:

When a client deletes something, simply mark it so that it is deleted locally and deleted from the server during synchronization (at this point you can clear the kernel data). When other clients request access to this data, send HTTP 404 because you no longer have the object. At this point, the client can delete the object locally. Now, if the client requests a list of things and this object has been deleted, it will simply be absent from the list of things that it receives so that you can detect it and delete it. I do this in the client, creating an array of object identifiers when I get a response from the server and delete any local objects that do not have these identifiers.

We have a remote field on the server, but just to be able to roll back in case something is accidentally deleted.

Of course, you can return the deleted objects to the client so that they know what to delete, but if you do not want to store a copy on the server, you will need to assume that all clients will be updated for a period of time, then you can collect garbage after this expires time interval.

I really don't like this solution. If your data is too heavy to request all objects for complete synchronization, you can use your current merge strategy to create and update, and then run a separate call to check for deleted items. This call can simply request all the identifiers that the client must have on the device. It can remove those that do not exist. OR he can send all identifiers on the client and return a list of identifiers for deletion.

I think you need to provide more detailed information about the nature of the data if you want a more stubborn offer.

+1
source

You can take a look at Dan Grover 's cross-platform data synchronization if you haven’t. This is a very well written article about synchronization and iOS.

About your questions:

  • You can avoid deleting the file in Core Data and set the “remote flag”: just update the file, not delete it. You can create your own delete method, which actually calls and updates the flag in the record.

  • Always save last_sync and last_updated for each record on the server and on each client. Thus, you will always know when someone changed something, and if this change was synchronized or not against the “truth database”.

  • Keeping track of deleted files is a difficult task, I think the best way to do this is to keep track of the synchronization history for each table, but it is a difficult task. The easiest way to use this “truth database” configuration is to specify the files, so yes, you must store the data both on the server and on the client.

+1
source

during data synchronization between the towing table, some records are either deleted when the table rows are the same. and when the lines differ correctly synchronized, I used this code by clicking here on the image

enter image description here

-3
source

Source: https://habr.com/ru/post/906917/


All Articles