SwiftData und CloudKit: Synchronisation ohne eigenen Server

Viele Apps brauchen keinen eigenen Server. Sie brauchen nur einen Weg, die Daten eines Menschen auf seinem iPhone, seinem iPad und seinem nächsten Gerät gleich zu halten. Für unsere eigenen Apps ContoTrip und Avantido haben wir uns deshalb für SwiftData mit CloudKit entschieden. Die Daten liegen lokal auf dem Gerät und werden über die private iCloud-Datenbank des Nutzers abgeglichen. Wir betreiben dafür keine Datenbank, keine API und keinen Server – und wir haben keinen Zugriff auf diese Daten.

Dieser Beitrag beschreibt, warum wir das so machen, wie es in der Praxis aussieht und an welchen Stellen man Lehrgeld zahlen kann.

Warum kein eigener Server?

Ein eigenes Backend bedeutet Betrieb: Updates, Backups, Überwachung, Zugangsdaten, Datenschutzdokumentation und eine Stelle, an der sich die Daten vieler Menschen sammeln. Für eine Reisekosten- oder To-do-App ist das ein hoher Preis für eine Funktion, die Apple bereits mitliefert.

Mit CloudKit verschiebt sich die Verantwortung. Die Daten stehen in der privaten Datenbank des jeweiligen Apple-Kontos. Als Anbieter sehen wir sie nicht, und wir müssen sie auch nicht schützen, weil sie bei uns gar nicht ankommen. Das vereinfacht die Datenschutzerklärung und macht das Versprechen „Ihre Daten bleiben bei Ihnen“ technisch überprüfbar.

Der Aufbau in der App

Das Datenmodell entsteht mit SwiftData über @Model-Klassen. Beim Start erzeugt die App einen Container, der mit CloudKit gespiegelt wird. Ist auf dem Gerät kein iCloud-Konto angemeldet oder iCloud für die App deaktiviert, fällt die App auf rein lokalen Speicher zurück. Die App bleibt dann voll nutzbar, nur der Abgleich entfällt.

Unsere Apps entstehen mit Swift 6 und striktem Concurrency-Checking. Das Projekt beschreiben wir mit XcodeGen in einer project.yml. Die Xcode-Projektdatei wird daraus generiert und nie von Hand bearbeitet. Das hält Änderungen an Capabilities und Entitlements nachvollziehbar – und genau die spielen bei CloudKit eine große Rolle.

Datenmodell mit Blick auf den Abgleich

  • Beträge als Integer-Cents. Gleitkommazahlen sind für Geld ungeeignet, auch beim Abgleich zwischen Geräten.
  • Werte beim Erfassen festhalten. ContoTrip friert den Wechselkurs zum Zeitpunkt der Erfassung ein. Summen bleiben dadurch stabil, egal auf welchem Gerät und wann sie angezeigt werden.
  • Gerätelokalen Zustand vom Modell trennen. Was nur für ein Gerät gilt, gehört nicht in die synchronisierten Daten.

Fallstricke aus der Praxis

iCloud-Container lassen sich nicht löschen

Das ist die wichtigste Lektion. App-IDs und App-Groups kann man im Developer Portal wieder entfernen, iCloud-Container nicht. Wer den Namen einmal unter dem falschen Entwicklerteam registriert – etwa beim ersten Testbuild mit einem persönlichen Konto statt dem Firmenkonto –, blockiert ihn dort dauerhaft. Bei Avantido ist genau das passiert. Der Container trägt deshalb den Suffix .data. Seitdem gilt bei uns: Der erste Gerätebuild läuft immer gegen das Team, unter dem die App später veröffentlicht wird.

Ohne Push kein sofortiger Abgleich

Fehlt das Entitlement aps-environment, gleicht CloudKit beim Start der App und beim Wechsel in den Vordergrund ab. Eine Änderung auf dem iPad erscheint auf dem iPhone also nicht in derselben Sekunde, sondern beim nächsten Öffnen. Für unsere Apps ist das vertretbar, weil sie ohnehin keinen Push-Code enthalten. Wer Sofort-Sync braucht, muss die Capability „Push Notifications“ bewusst ergänzen.

Das Datenschutz-Label

Daten in der privaten iCloud-Datenbank sind für den Anbieter nicht zugänglich und müssen laut Apple im Privacy Nutrition Label nicht deklariert werden. Das ist ein echter Vorteil. Es entbindet aber nicht davon, andere Übertragungen ehrlich anzugeben – etwa wenn eine KI-Funktion Inhalte an einen Anbieter schickt.

Die Grenzen des Ansatzes

CloudKit in der privaten Datenbank ist für eine Person mit mehreren Geräten gedacht. Ein gemeinsamer Haushalt oder ein Team, das an denselben Daten arbeitet, braucht mehr. Wir lösen das bewusst anders: Geteilt wird, indem man jemandem etwas schickt – als Datei über das Share-Sheet, per AirDrop, Mail oder Messenger. Die Datei hat ein versioniertes Format und einen lesbaren Text-Fallback für Empfänger ohne die App.

Außerdem ist CloudKit eine Apple-Technologie. Eine Android-App kommt an diese Daten nicht heran. Für Produkte, die es auf beiden Plattformen geben soll, ist deshalb das gemeinsame Austauschformat der Berührungspunkt und nicht eine gemeinsame Cloud.

Wann wir diesen Weg empfehlen

  • Die App verwaltet persönliche Daten einer einzelnen Person.
  • Es gibt keinen fachlichen Grund, die Daten zentral auszuwerten.
  • Das Produkt soll ohne Benutzerkonto und Anmeldung auskommen.
  • Datenschutz ist Teil des Produktversprechens.

Braucht ein Projekt dagegen Zusammenarbeit mehrerer Nutzer, Auswertungen oder eine Web-Oberfläche, planen wir ein eigenes Backend – mit Symfony und einer klaren API. Die Entscheidung treffen wir am Anfang, denn nachträglich lässt sich die Architektur nur mit viel Aufwand umbauen.

Nach oben