Skip to content

MiDiccio: Sync Fixes and a New Take on Deletion

MiDiccio v1.4.0 and v1.4.1 rework how cloud sync and deletion work.

The first half summarizes what changed for users. The second half explains the mechanics for developers. Feel free to skip to the part you need.

MiDiccio is an offline vocabulary app where you build your own word list.

  • No sign-up, no ads
  • Your data is saved on your device first
  • To use it on multiple devices, sync through your own iCloud (iOS) or Google Drive (Android). There is no MiDiccio server.

→ Library / Support site

  • Words you haven’t edited keep their “updated” date. Before, on iOS, every sync overwrote it with the time of the sync.
  • Words restored from a backup now reach your other devices. Before, they stayed only on the device you restored them on. The first sync after updating re-uploads all of your words once.
  • The app now syncs when you open it. Words added on another device show up in the list right away.
  • You can restore deleted words. Open Trash from the Settings screen and restore words one at a time.
  • Words deleted on any device can be restored from another device’s Trash. Restored words sync to your other devices too (as long as all of them are on v1.4.1).
  • There is no way to permanently delete words from Trash yet. The reason is explained below.

From here on, it’s about how things work.

  • When the same word exists both on the device and in the cloud, the one with the newer updated time wins (last-write-wins).
  • Saving or deleting a word on the device marks it as “pending”, and the next sync uploads only pending words.

MiDiccio is a personal app, so editing the same word on two devices at the same moment is rare. Instead of asking users to resolve conflicts, we stick with this simple rule.

Bug 1: Unchanged words were treated as conflicts on every sync

Section titled “Bug 1: Unchanged words were treated as conflicts on every sync”

When a word had the same updated time on both sides, the app treated it as a conflict because it couldn’t tell which one was newer. On a conflict, it keeps the local copy, sets its updated time to now, and uploads it again. CloudKit (iCloud) then made things worse:

  • On the device, timestamps have microsecond precision.
  • CloudKit rounds timestamps to milliseconds when saving.
  • On iOS, after uploading, the app overwrites the local word with the saved record (with the rounded timestamp).
  • → On the next sync, the timestamps match again, another conflict occurs, and the updated time moves forward on every sync.

The fix

  • Compare updated times at millisecond precision.
  • If the times match and the content (word, meaning, notes, tags, etc.) is identical, treat it as already synced and do nothing.
  • Only treat it as a conflict when the times match but the content differs.

Bug 2: Restored words were not marked as pending

Section titled “Bug 2: Restored words were not marked as pending”

Loading a JSON backup reused the code path that imports words received from the cloud. Words from the cloud don’t need to be uploaded again, so that path doesn’t mark them as pending. But restored words had never reached the cloud.

The fix

  • Mark restored words as pending.
  • To catch words that were already restored before this fix, the first sync after updating uploads every word once.
  • This full upload runs after pulling changes from the cloud, so newer cloud data is never overwritten by older local data.

In MiDiccio, deleting a word has always just set a “deleted” flag instead of removing it (a soft delete). If one device actually removed the word, sync from another device would bring it back as a word that “exists only in the cloud”.

iOS, however, actually removed a word locally when it received a deleted word from another device. Android kept it with the flag.

What changed in v1.4.1

  • iOS now also keeps deleted words with the flag, so all devices hold the same state.
  • Restoring a word from Trash clears the flag and bumps its updated time → last-write-wins carries the change to other devices.

Because deletion was already treated as just another kind of edit, we could build Trash without adding any new sync rules.

Why there is no “Delete permanently” yet

Section titled “Why there is no “Delete permanently” yet”
  • Removing a word on one device doesn’t remove it from other devices or the cloud, so it comes back on the next sync.
  • Permanent deletion needs a separate way to tell every device and the cloud that a word is gone for good.
  • We also need to handle devices still running older versions of the app.

At personal scale, keeping deleted words around has almost no effect on storage or speed. For now, we chose to prioritize being able to restore words.

  • Undo a restore: If you restore from the wrong backup file, you’ll be able to go back to the state just before the restore (one step).
  • Cleaning up Trash: We’re considering either hiding old deleted words from the Trash list, or building a way to delete them permanently from all devices.

v1.4.1 is available on the App Store and Google Play.

Last updated: