Offline‑First Hintergrund‑Synchronisation mobiler Apps: Konflikte, Wiederholungen und UX
Plane die Offline‑First‑Hintergrundsynchronisation mobiler Apps mit klaren Konfliktregeln, Wiederholungslogik und einer einfachen UX für ausstehende Änderungen in nativen Kotlin‑ und SwiftUI‑Apps.

Das Problem: Nutzer bearbeiten offline und die Realität ändert sich
Jemand beginnt eine Aufgabe bei guter Verbindung und läuft dann in einen Fahrstuhl, eine Ecke im Lager oder einen U‑Bahn‑Tunnel. Die App läuft weiter, also arbeitet die Person weiter. Sie tippt auf Speichern, fügt eine Notiz hinzu, ändert einen Status oder erstellt vielleicht sogar einen neuen Datensatz. Auf dem Bildschirm sieht alles sofort korrekt aus.
Später kommt die Verbindung zurück und die App versucht im Hintergrund aufzuholen. Genau hier kann Hintergrund‑Sync die Leute überraschen.
Wenn die App nicht vorsichtig ist, kann dieselbe Aktion zweimal gesendet werden (Duplikate), oder eine neuere Änderung vom Server kann das überschreiben, was der Nutzer gerade getan hat (verlorene Änderungen). Manchmal zeigt die App verwirrende Zustände wie „Gespeichert“ und „Nicht gespeichert“ gleichzeitig, oder ein Datensatz erscheint, verschwindet und taucht nach der Synchronisation wieder auf.
Ein Konflikt ist simpel: zwei unterschiedliche Änderungen wurden an derselben Sache vorgenommen, bevor die App sie zusammengeführt hat. Zum Beispiel ändert eine Support‑Mitarbeiterin offline die Priorität eines Tickets auf Hoch, während ein Kollege online das Ticket schließt. Wenn das offline Gerät wieder verbindet, können beide Änderungen nicht ohne Regel sauber angewendet werden.
Das Ziel ist nicht, Offline perfekt wirken zu lassen. Das Ziel ist, es vorhersehbar zu machen:
- Menschen können weiterarbeiten, ohne Angst vor Datenverlust.
- Die Synchronisation passiert später ohne mysteriöse Duplikate.
- Wenn etwas Aufmerksamkeit braucht, sagt die App klar, was passiert ist und was zu tun ist.
Das gilt, egal ob du in Kotlin/SwiftUI hand‑codest oder native Apps mit einer No‑Code‑Plattform wie AppMaster baust. Die schwierige Frage ist nicht das UI‑Widget. Sie ist: Wie verhält sich die App, wenn sich die Welt ändert, während der Nutzer offline ist?
Ein einfaches Offline‑First‑Modell (ohne Fachchinesisch)
Eine Offline‑First‑App geht davon aus, dass das Telefon manchmal die Verbindung verliert; trotzdem soll die App nutzbar bleiben. Bildschirme sollten laden und Buttons funktionieren, auch wenn der Server nicht erreichbar ist.
Vier Begriffe decken das meiste ab:
- Lokaler Cache: auf dem Gerät gespeicherte Daten, damit die App sofort etwas anzeigen kann.
- Sync‑Warteschlange: eine Liste von Aktionen, die der Nutzer offline (oder bei schwacher Verbindung) durchgeführt hat.
- Server‑Wahrheit: die Version, die auf dem Backend liegt und die am Ende alle teilen.
- Konflikt: wenn die wartende Änderung des Nutzers nicht mehr sauber angewendet werden kann, weil sich die Server‑Version geändert hat.
Ein nützliches Denkmodell ist, Lesen und Schreiben zu trennen.
Lesen ist meist einfach: Zeige die bestmöglichen Daten (oft aus dem lokalen Cache) und aktualisiere ruhig, wenn das Netzwerk zurück ist.
Schreiben ist anders. Verlasse dich nicht darauf, "den ganzen Datensatz auf einmal zu speichern". Das bricht sofort, sobald du offline bist.
Stattdessen zeichne auf, was der Nutzer getan hat, als kleine Einträge in einem Änderungsprotokoll. Zum Beispiel: „Status auf Genehmigt setzen“, „Kommentar X hinzufügen“, „Menge von 2 auf 3 ändern“. Jeder Eintrag kommt mit Zeitstempel und ID in die Sync‑Warteschlange. Der Hintergrund‑Sync versucht dann, die Einträge zuzustellen.
Der Nutzer kann weiterarbeiten, während Änderungen von ausstehend zu synchronisiert wechseln.
Wenn du eine No‑Code‑Plattform wie AppMaster verwendest, brauchst du trotzdem dieselben Bausteine: gecachte Lesezugriffe für schnelle Bildschirme und eine klare Warteschlange von Nutzeraktionen, die erneut versucht, zusammengeführt oder bei Konflikt markiert werden kann.
Entscheide, was wirklich Offline‑Unterstützung braucht
Offline‑First kann sich anhören wie „alles funktioniert ohne Verbindung“, aber dieses Versprechen ist häufig der Punkt, an dem Apps Probleme bekommen. Wähle die Teile, die wirklich von Offline profitieren, und halte den Rest klar online‑only.
Denk in Nutzerabsicht: Was müssen Leute im Keller, im Flugzeug oder im Lager mit wechselndem Empfang tun? Eine gute Grundeinstellung ist, Aktionen zu unterstützen, die alltägliche Arbeit erstellen oder aktualisieren, und Aktionen zu blockieren, bei denen die „aktuelle Wahrheit“ wichtig ist.
Praktisch sind oft offline‑freundlich: Erstellen und Bearbeiten von Kern‑Datensätzen (Notizen, Aufgaben, Inspektionen, Tickets), Entwürfe von Kommentaren und Anhängen von Fotos (lokal gespeichert, später hochgeladen). Löschen kann auch funktionieren, aber sicherer als Soft‑Delete mit einer Rückgängig‑Zeit, bis der Server bestätigt.
Jetzt entscheide, was in Echtzeit bleiben muss, weil das Risiko zu groß ist. Zahlungen, Berechtigungsänderungen, Genehmigungen und alles mit sensiblen Daten sollten meist eine Verbindung erfordern. Wenn die Aktion ohne Serverprüfung nicht gültig ist, erlaube sie offline nicht. Zeige eine klare „Verbindung erforderlich“‑Hinweis, nicht eine mysteriöse Fehlermeldung.
Setze Erwartungen zur Aktualität. „Offline“ ist nicht binär. Definiere, wie alt Daten sein dürfen: Minuten, Stunden oder „nächster App‑Start“. Zeige diese Regel in der UI in klaren Worten, z. B. „Zuletzt aktualisiert vor 2 Stunden“ und „Synchronisiert, wenn online“.
Markiere schließlich daten mit hohem Konfliktrisiko früh. Inventarstände, geteilte Aufgaben und Team‑Nachrichten sind typische Konfliktmagneten, weil mehrere Leute schnell daran arbeiten. Für diese solltest du Offline‑Bearbeitungen auf Entwürfe beschränken oder Änderungen als separate Ereignisse erfassen, statt einen einzelnen Wert zu überschreiben.
Wenn du in AppMaster baust, hilft dir dieser Schritt, Daten und Geschäftsregeln so zu modellieren, dass die App sichere Entwürfe offline speichert, während riskante Aktionen online‑only bleiben.
Design der Sync‑Warteschlange: Was du für jede Änderung speicherst
Wenn ein Nutzer offline arbeitet, versuche nicht „die Datenbank zu synchronisieren“. Synchronisiere die Aktionen des Nutzers. Eine klare Aktionswarteschlange ist das Rückgrat des Hintergrund‑Sync und bleibt verständlich, wenn etwas schiefgeht.
Halte Aktionen klein und menschlich, passend zu dem, was der Nutzer tatsächlich getan hat:
- Einen Datensatz erstellen
- Bestimmte Feld(er) aktualisieren
- Status ändern (einreichen, genehmigen, archivieren)
- Löschen (vorzugsweise Soft‑Delete bis zur Bestätigung)
Kleine Aktionen sind leichter zu debuggen. Wenn der Support helfen muss, ist es viel einfacher zu lesen: „Status geändert Draft -> Submitted“ als einen riesigen Blob geänderter JSON‑Daten zu untersuchen.
Für jede wartende Aktion speichere genug Metadaten, um sie sicher erneut abzuspielen und Konflikte zu erkennen:
- Datensatz‑Identifier (und eine temporäre lokale ID für neu erstellte Datensätze)
- Aktions‑Zeitstempel und Geräte‑Identifier
- Erwartete Version (oder zuletzt bekannte Aktualisierungszeit) des Datensatzes
- Payload (die konkreten geänderten Felder, plus alter Wert wenn möglich)
- Idempotency‑Key (eine eindeutige Aktions‑ID, damit Retries keine Duplikate erzeugen)
Diese erwartete Version ist der Schlüssel zu ehrlicher Konfliktbehandlung. Wenn sich die Server‑Version bewegt hat, kannst du pausieren und um Entscheidung bitten, statt stillschweigend jemand anderen zu überschreiben.
Manche Aktionen müssen zusammen angewendet werden, weil der Nutzer sie als einen Schritt sieht. Zum Beispiel „Bestellung erstellen“ plus „drei Positionen hinzufügen“ sollten als Einheit gelingen oder ausstehen. Speicher eine Gruppen‑ID (oder Transaktions‑ID), damit die Sync‑Engine sie zusammen senden und entweder alle bestätigen oder alle pending lassen kann.
Egal ob händisch gebaut oder in AppMaster: Das Ziel ist das gleiche — jede Änderung wird einmal aufgezeichnet, sicher wiedergegeben und ist erklärbar, wenn etwas nicht passt.
Konfliktlösungsregeln, die du Nutzer:innen erklären kannst
Konflikte sind normal. Das Ziel ist nicht, sie unmöglich zu machen, sondern selten, sicher und leicht erklärbar zu halten, wenn sie auftreten.
Benenne den Moment, in dem ein Konflikt passiert: die App sendet eine Änderung, und der Server antwortet: „Dieser Datensatz ist nicht die Version, die du bearbeitet hast.“ Deshalb ist Versionierung wichtig.
Behalte zwei Werte bei jedem Datensatz:
- Server‑Version (die aktuelle Version auf dem Server)
- Erwartete Version (die Version, die das Telefon beim Bearbeiten gesehen hat)
Wenn die erwartete Version übereinstimmt, akzeptiere das Update und erhöhe die Server‑Version. Wenn nicht, wende deine Konfliktregel an.
Wähle pro Datentyp eine Regel (nicht eine Regel für alles)
Verschiedene Daten brauchen verschiedene Regeln. Ein Statusfeld ist nicht dasselbe wie eine lange Notiz.
Regeln, die Nutzer meist verstehen:
- Last write wins: okay für niedriges Risiko, z. B. Anzeige‑Einstellungen.
- Felder mergen: gut, wenn Felder unabhängig sind (Status vs Notizen).
- Nutzer fragen: am besten bei risikoreichen Änderungen wie Preis, Berechtigungen oder Summen.
- Server gewinnt, aber mit Kopie: behalte den Server‑Wert, speichere die Nutzeränderung als Entwurf, den sie wieder anwenden können.
In AppMaster lassen sich diese Regeln gut als visuelle Logik abbilden: Versionen prüfen, Felder vergleichen und dann den Pfad wählen.
Entscheide, wie Löschen sich verhält (sonst verlierst du Daten)
Löschen ist der knifflige Fall. Verwende ein Tombstone (ein „deleted“‑Marker) statt den Datensatz sofort zu entfernen. Dann entscheide, was passiert, wenn jemand einen Datensatz bearbeitet, der anderswo gelöscht wurde.
Eine klare Regel ist: „Deletes gewinnen, aber man kann wiederherstellen.“ Beispiel: Ein Verkäufer bearbeitet offline eine Kundennotiz, während ein Admin diesen Kunden löscht. Bei Sync zeigt die App: „Kunde wurde gelöscht. Wiederherstellen, um deine Notiz anzuwenden?“ So vermeidest du stillen Verlust und gibst Kontrolle an die Nutzerin zurück.
Wiederholungen und Fehlerzustände: mach es vorhersehbar
Wenn Sync fehlschlägt, kümmern sich die meisten Nutzer nicht um die Ursache. Sie wollen wissen, ob ihre Arbeit sicher ist und was als Nächstes passiert. Ein vorhersehbares Zustandsmodell verhindert Panik und Tickets beim Support.
Beginne mit einem kleinen, sichtbaren Statusmodell und nutze es konsistent auf allen Bildschirmen:
- Queued: auf dem Gerät gespeichert, wartet auf Netzwerk
- Syncing: wird gerade gesendet
- Sent: vom Server bestätigt
- Failed: konnte nicht gesendet werden, wird wiederholt oder braucht Aufmerksamkeit
- Needs review: gesendet, aber vom Server abgelehnt oder markiert
Retries sollten schonend für Akku und Daten sein. Verwende anfänglich schnelle Wiederholungen (für kurze Signalabbrüche), dann verlangsame sie. Ein einfacher Backoff wie 1 Min, 5 Min, 15 Min, dann stündlich ist leicht verständlich. Wiederhole außerdem nur, wenn es Sinn macht (versuche nicht, eine ungültige Änderung endlos zu senden).
Behandle Fehlerarten unterschiedlich, weil die nächste Aktion unterschiedlich ist:
- Offline / kein Netzwerk: bleibe in der Warteschlange, wiederhole bei Online
- Timeout / Server nicht verfügbar: markiere als fehlgeschlagen, automatische Wiederholung mit Backoff
- Auth abgelaufen: pausiere Sync und bitte den Nutzer, sich erneut anzumelden
- Validierung fehlgeschlagen (falsche Eingaben): braucht Überprüfung, zeige, was zu korrigieren ist
- Konflikt (Datensatz geändert): braucht Überprüfung, leite gemäß deiner Konfliktregeln
Idempotenz macht Retries sicher. Jede Änderung sollte eine eindeutige Aktions‑ID (oft eine UUID) haben, die mit der Anfrage gesendet wird. Wenn die App dieselbe Änderung erneut sendet, sollte der Server die ID erkennen und dasselbe Ergebnis zurückgeben, statt Duplikate zu erzeugen.
Beispiel: Ein Techniker speichert einen abgeschlossenen Auftrag offline und fährt dann in einen Aufzug. Die App sendet das Update, es time‑outet und wird später erneut versucht. Mit einer Aktions‑ID ist der zweite Send harmlos. Ohne sie erzeugst du vielleicht doppelte „abgeschlossen“‑Ereignisse.
In AppMaster behandle diese Zustände und Regeln als erstklassige Felder und Logik in deinem Sync‑Prozess, damit deine Kotlin‑ und SwiftUI‑Apps überall gleich reagieren.
UX für ausstehende Änderungen: was der Nutzer sieht und tun kann
Menschen sollen sich sicher fühlen, die App offline zu nutzen. Gute „Pending changes“‑UX ist ruhig und vorhersehbar: Sie bestätigt, dass Arbeit auf dem Gerät gespeichert ist, und macht den nächsten Schritt offensichtlich.
Ein dezenter Indikator ist besser als ein Warnbanner. Zeige z. B. ein kleines „Synchronisiere“‑Icon in der Kopfleiste oder ein unaufdringliches „3 ausstehend“‑Label auf dem Bildschirm, wo die Änderungen passieren. Spare auffällige Farben für echte Gefahren (z. B. „kann nicht hochgeladen werden, weil du abgemeldet bist").
Gib den Nutzern einen Ort, an dem sie alles verstehen können. Ein simples Outbox‑ oder Ausstehende‑Änderungen‑Fenster kann Einträge mit klarer Sprache auflisten wie „Kommentar zu Ticket 104 hinzugefügt“ oder „Profilfoto aktualisiert“. Diese Transparenz verhindert Panik und reduziert Support‑Anfragen.
Was Nutzer tun können
Die meisten Menschen brauchen nur wenige Aktionen, die überall konsistent sein sollten:
- Jetzt erneut versuchen
- Nochmals bearbeiten (erstellt eine neue Änderung)
- Lokale Änderung verwerfen
- Details kopieren (nützlich beim Melden eines Problems)
Halte Statuslabels einfach: Pending, Syncing, Failed. Wenn etwas fehlschlägt, erkläre es wie ein Mensch: „Konnte nicht hochladen. Kein Internet.“ oder „Abgelehnt, weil dieser Datensatz von jemand anderem geändert wurde.“ Vermeide Fehlercodes.
Blockiere nicht die ganze App
Blockiere nur Aktionen, die wirklich online sein müssen, wie „Mit Stripe bezahlen“ oder „neuen Nutzer einladen“. Alles andere sollte weiter funktionieren, inklusive dem Anzeigen kürzlich geladener Daten und dem Erstellen neuer Entwürfe.
Ein realistischer Ablauf: Ein Field‑Tech bearbeitet einen Bericht im Keller. Die App zeigt „1 ausstehend“ und lässt ihn weiterarbeiten. Später wechselt der Status zu „Synchronisiere“ und leert sich automatisch. Wenn es fehlschlägt, bleibt der Bericht verfügbar, markiert als „Fehlgeschlagen“, mit einem einzigen Button „Jetzt erneut“.
Wenn du in AppMaster baust, modelliere diese Zustände als Teil jedes Datensatzes (pending, failed, synced), damit die UI sie überall ohne Spezialfälle anzeigen kann.
Auth, Berechtigungen und Sicherheit im Offline‑Modus
Offline ändert dein Sicherheitsmodell. Ein Nutzer kann Aktionen tätigen, ohne Verbindung, aber dein Server bleibt die Quelle der Wahrheit. Behandle jede wartende Änderung als „angefordert“, nicht als „genehmigt“.
Ablauf der Anmeldung im Offline‑Zustand
Tokens laufen ab. Wenn das offline passiert, lass den Nutzer trotzdem Änderungen erstellen und speichere sie als ausstehend. Täusche nicht vor, dass Aktionen, die Serverbestätigung brauchen (Zahlungen, Admin‑Genehmigungen), abgeschlossen sind. Markiere sie als ausstehend, bis ein erfolgreicher Auth‑Refresh stattgefunden hat.
Wenn die App wieder online ist, versuche zuerst ein stilles Refresh. Wenn du den Nutzer zur Anmeldung auffordern musst, mache es einmal, dann setze den Sync automatisch fort.
Nach dem Re‑Login validiere jeden wartenden Eintrag nochmal, bevor du ihn sendest. Die Nutzeridentität kann sich geändert haben (gemeinsames Gerät) und alte Änderungen dürfen nicht unter dem falschen Konto synchronisiert werden.
Berechtigungsänderungen und verbotene Aktionen
Berechtigungen können sich ändern, während der Nutzer offline ist. Eine gestern erlaubte Änderung kann heute verboten sein. Behandle das ausdrücklich:
- Überprüfe serverseitig jede wartende Aktion auf Berechtigung
- Bei Verbot stoppe den Eintrag und zeige einen klaren Grund
- Bewahre die lokale Änderung, damit der Nutzer sie kopieren oder Zugriff anfragen kann
- Vermeide wiederholte Versuche bei „forbidden“‑Fehlern
Beispiel: Ein Support‑Agent bearbeitet offline eine Kundennotiz im Flugzeug. Über Nacht wird seine Rolle entfernt. Beim Sync lehnt der Server das Update ab. Die App sollte anzeigen: „Kann nicht hochgeladen werden: Du hast keinen Zugriff mehr“ und die Notiz als lokalen Entwurf behalten.
Sensible Daten offline speichern
Speichere nur das Minimum, das nötig ist, um Bildschirme darzustellen und die Warteschlange abzuspielen. Verschlüssele lokalen Speicher, meide das Cachen von Secrets und setze klare Regeln für Logout (z. B. lokale Daten löschen oder Entwürfe nur mit expliziter Zustimmung behalten). Wenn du mit AppMaster arbeitest, starte mit dessen Auth‑Modul und gestalte deine Warteschlange so, dass sie immer auf eine gültige Session wartet, bevor Änderungen gesendet werden.
Häufige Fallen, die Arbeit verloren gehen oder Duplikate erzeugen lassen
Die meisten Offline‑Bugs sind nicht spektakulär. Sie entstehen aus ein paar kleinen Entscheidungen, die harmlos wirken, wenn du mit perfektem WLAN testest, aber die reale Arbeit später kaputtmachen.
Ein häufiger Fehler sind stille Überschreibungen. Wenn die App eine ältere Version hochlädt und der Server sie ohne Prüfung akzeptiert, kannst du eine neuere Änderung einer anderen Person löschen, und niemand bemerkt es, bis es zu spät ist. Synchronisiere mit einer Versionsnummer (oder einem updatedAt‑Zeitstempel) und weigere dich zu überschreiben, wenn der Server weiter ist, sodass die Nutzerin eine klare Wahl bekommt.
Eine andere Falle ist ein Retry‑Sturm. Wenn ein Telefon wieder Verbindung bekommt, kann die App den Backend alle paar Sekunden zuspammen, Akku leeren und doppelte Writes erzeugen. Wiederholungen sollten ruhig sein: nach jedem Fehler langsamer werden und etwas Zufälligkeit einbauen, damit nicht tausende Geräte gleichzeitig erneut versuchen.
Die Fehler, die am häufigsten zu Datenverlust oder Duplikaten führen:
- Behandle jeden Fehler als „Netzwerk“: trenne permanente Fehler (ungültige Daten, fehlende Berechtigung) von temporären (Timeout).
- Verstecke Sync‑Fehler: wenn Leute nicht sehen, was fehlgeschlagen ist, machen sie die Aufgabe nochmal und erzeugen zwei Datensätze.
- Sende dieselbe Änderung zweimal ohne Schutz: hänge immer eine eindeutige Request‑ID an, damit der Server Duplikate erkennt und ignoriert.
- Textfelder automatisch mergen ohne Information: wenn du Änderungen automatisch kombinierst, lass Nutzer das Ergebnis überprüfen, wenn es wichtig ist.
- Datensätze offline ohne stabile ID erstellen: verwende eine temporäre lokale ID und mappe sie auf die Server‑ID nach dem Upload, damit spätere Änderungen nicht einen zweiten Datensatz erzeugen.
Ein schnelles Beispiel: Ein Field‑Tech erstellt offline einen neuen „Site Visit“ und bearbeitet ihn zweimal, bevor die Verbindung zurückkommt. Wenn der Create‑Call erneut versucht wird und zwei Server‑Datensätze erzeugt, hängen spätere Änderungen möglicherweise am falschen Eintrag. Stabile IDs und serverseitiges Deduping verhindern das.
Wenn du das mit AppMaster baust, ändern sich die Regeln nicht. Der Unterschied ist nur, wo du sie implementierst: in deiner Sync‑Logik, im Datenmodell und in den Bildschirmen, die „failed“ vs „sent“ anzeigen.
Beispielszenario: zwei Personen bearbeiten denselben Datensatz
Eine Field‑Technikerin, Maya, aktualisiert in einem Keller das Ticket „Job #1842“. Sie ändert den Status von „In progress“ auf „Completed“ und fügt die Notiz hinzu: „Ventil ersetzt, getestet OK.“ Die App speichert sofort und zeigt den Eintrag als ausstehend an.
Oben arbeitet ihr Kollege Leo online am selben Job. Er ändert die geplante Zeit und weist den Auftrag einem anderen Techniker zu, weil ein Kunde ein Update gemeldet hat.
Als Maya wieder Empfang hat, startet der Hintergrund‑Sync leise. So läuft es in einem vorhersehbaren, nutzerfreundlichen Ablauf:
- Mayas Änderung ist noch in der Sync‑Warteschlange (Job‑ID, geänderte Felder, Zeitstempel und die Version, die sie zuletzt gesehen hat).
- Die App versucht hochzuladen. Der Server antwortet: „Dieser Job wurde seit deiner Version aktualisiert“ (Konflikt).
- Deine Konfliktregel greift: Status und Notizen können gemerged werden, aber Zuweisungsänderungen gewinnen, wenn sie später auf dem Server gemacht wurden.
- Der Server akzeptiert ein gemergtes Ergebnis: status = „Completed“ (von Maya), Notiz hinzugefügt (von Maya), zugewiesener Techniker = Leos Änderung (von Leo).
- Der Job erscheint in Mayas App mit einem klaren Banner: „Synchronisiert mit Änderungen. Zuweisung wurde während deiner Offline‑Zeit geändert.“ Eine kleine „Überprüfen“‑Aktion zeigt, was sich geändert hat.
Füge einen Fehler hinzu: Mayas Login‑Token lief offline ab. Der erste Sync‑Versuch schlägt fehl mit „Anmeldung erforderlich“. Die App behält ihre Änderungen, markiert sie als „Pausiert“ und zeigt eine einfache Aufforderung. Nach der Anmeldung setzt der Sync automatisch fort, ohne dass sie etwas neu tippen muss.
Wenn es ein Validierungsproblem gibt (z. B. „Completed“ erfordert ein Foto), soll die App nicht raten. Sie markiert den Eintrag als „Benötigt Aufmerksamkeit“, sagt genau, was fehlt, und lässt ihn neu senden, wenn alles vollständig ist.
Plattformen wie AppMaster helfen hier, weil du Warteschlange, Konfliktregeln und Pending‑Zustände visuell designen kannst und trotzdem echte native Kotlin‑ und SwiftUI‑Apps auslieferst.
Kurze Checkliste und nächste Schritte
Behandle Offline‑Sync wie ein End‑to‑End‑Feature, das du testen kannst — nicht als Ansammlung von Reparaturen. Das Ziel ist simpel: Nutzer sollen nie zweifeln, ob ihre Arbeit gespeichert ist, und die App darf keine überraschenden Duplikate erzeugen.
Eine kurze Checkliste, um das Fundament zu prüfen:
- Die Sync‑Warteschlange liegt auf dem Gerät und jede Änderung hat eine stabile lokale ID plus eine Server‑ID, wenn verfügbar.
- Klare Status existieren (queued, syncing, sent, failed, needs review) und werden konsistent verwendet.
- Requests sind idempotent (wiederholbar), und jede Operation enthält einen Idempotency‑Key.
- Datensätze haben Versionierung (updatedAt, Revisionsnummer oder ETag), damit Konflikte erkannt werden können.
- Konfliktregeln sind in klarer Sprache formuliert (was gewinnt, was wird gemerged, wann fragt man den Nutzer).
Wenn das steht, prüfe, ob das Erlebnis genauso robust ist wie das Datenmodell. Nutzer sollten sehen können, was aussteht, verstehen, was fehlgeschlagen ist, und handeln können, ohne Angst vor Datenverlust.
Teste mit realistischen Szenarien:
- Flugmodus‑Bearbeitungen: erstellen, aktualisieren, löschen und dann reconnecten.
- Flackerndes Netz: Verbindung mitten im Sync verlieren und sicherstellen, dass Retries keine Duplikate erzeugen.
- App beendet: während des Sendens erzwingen, dass die App geschlossen wird, wieder öffnen und prüfen, ob die Warteschlange wiederhergestellt wird.
- Uhr‑Abweichung: Gerätzeit ist falsch; prüfen, ob Konflikterkennung trotzdem funktioniert.
- Doppelte Taps: Nutzer drückt Speichern zweimal; prüfen, ob es zu einer Server‑Änderung wird.
Prototyp den kompletten Ablauf, bevor du die UI polierst. Baue einen Bildschirm, einen Datensatztyp und einen Konfliktfall (zwei Änderungen am selben Feld). Füge einen einfachen Sync‑Statusbereich, einen Retry‑Button für Fehler und eine klare Konfliktseite hinzu. Wenn das funktioniert, wiederhole es für weitere Bildschirme.
Wenn du ohne Code baust, kann AppMaster (appmaster.io) native Kotlin‑ und SwiftUI‑Apps zusammen mit dem Backend generieren, sodass du dich auf Warteschlange, Versionsprüfungen und nutzerseitige Zustände konzentrieren kannst, statt alles von Hand zu verdrahten.


