Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 7 Min.

Datenspeicherung lokal und in der Cloud

Mobile Apps müssen die Daten, die beispielsweise durch Sensoren ermittelt werden, zwischen den Sitzungen speichern und ebenso an einen entfernten Server übertragen.
© EMGenie

In diesem letzten Teil der Delphi-Cross-Plattform-Serie betrachten wir die Speicherung der Daten, das heißt die lokale Speicherung auf dem Gerät und die Cloud-Anbindung über Webservices. Bei einer lokaler Datenspeicherung, zum Beispiel via SQLite auf dem Gerät, liegen alle Daten auf dem Endgerät. Das bietet folgende Vorteile beziehungsweise Use Cases:

  • Offline-Verfügbarkeit und Performance: Keine Internetverbindung nötig und sehr schnelle lokale Datenzugriffe.
  • Einfache Einrichtung: Kein Server erforderlich; SQLite läuft ohne zusätzliche Konfiguration auf mobilen Plattformen.

 

Die lokale Speicherung hat auch einige Nachteile:

  • Kein Abgleich/Backup: Daten bleiben auf einem Gerät, das heißt, es findet weder eine geräteübergreifende Synchronisation noch ein automatisches Backup statt. Bei einem Verlust des Geräts sind die Daten verloren.
  • Sicherheitsrisiko: Die lokale DB liegt unverschlüsselt auf dem Gerät, falls man sie nicht mit einem Passwort schützt.

 

Als Offline-First bezeichnet man eine Strategie, bei der die App auch ohne Netz voll funktionsfähig ist und Daten zwischenspeichert. Diese werden bei einem späteren Verbindungsaufbau automatisch synchronisiert. Dieses Konzept verbessert die Robustheit und Benutzererfahrung deutlich.

Sollen Daten in der Cloud gespeichert oder mit einem Server synchronisiert werden, geschieht dies meist über REST-Webservices. Die App schickt HTTP-Anfragen (GET/POST/PUT/DELETE) an einen Server und erhält typischerweise JSON-Daten zurück. Delphi stellt dafür die Komponenten TRESTClient, TRESTRequest und TRESTResponse bereit (Bild 1).

REST-Client-Komponenten in Delphi für FireMonkey-Apps (Bild 1)

REST-Client-Komponenten in Delphi für FireMonkey-Apps (Bild 1)

© Autor

Man konfiguriert den BaseURL des Dienstes am Client und den Resource-Pfad sowie die HTTP-Methode am Request – zum Beispiel eine POST-Anfrage (/upload) mit JSON-Daten im Body – und führt die Anfrage aus. Die REST-Bibliothek unterstützt auch Authentifizierung, zum Beispiel über die Authenticator-Komponenten (THTTPBasicAuthenticator für Basic-Auth, TOAuth2Authenticator für OAuth2), oder man setzt API-Schlüssel und Tokens direkt als HTTP-Header ein.

Neben dem generischen REST-Ansatz gibt es für bestimmte Cloud-Anbieter vorgefertigte Delphi-Komponenten. Beispielsweise für AWS: Die Klasse TAmazonConnectionInfo nimmt die Zugangsdaten (Access Key ID und Secret Key) auf. Mit TAmazonStorageService (Bild 2) kann man dann auf Amazon S3 zugreifen und zum Beispiel eine Datei hochladen.

Nutzung der AWS-Cloud aus einer Delphi-App (eigene Darstellung) (Bild 2)

Nutzung der AWS-Cloud aus einer Delphi-App (eigene Darstellung) (Bild 2)

© Autor

Für Backend-as-a-Service-Dienste wie Firebase kann man entweder deren REST-API direkt mit den genannten Komponenten ansprechen oder spezielle Delphi-Bibliotheken nutzen. Ein Vorteil solcher BaaS-Angebote ist, dass auf Client-Seite keine eigene Datenbank erforderlich ist – die gesamte Datenhaltung erfolgt über Web-Service-Aufrufe in der Cloud.

Lokale Speicherung: SQLite mit FireDAC

FireDAC ist Delphis universelle Datenzugriffsbibliothek und bietet schnellen, plattformübergreifenden Zugriff auf zahlreiche Datenbanken – darunter auch SQLite (Bild 3). In mobilen Projekten wird der SQLite-Treiber direkt mit FireDAC ausgeliefert.

Arbeitsweise (Architektur) von FireDAC zur Interaktion mit Datenbanken, unter anderem SQLite (Bild 3)

Arbeitsweise (Architektur) von FireDAC zur Interaktion mit Datenbanken, unter anderem SQLite (Bild 3)

© Embarcadero.com

Für die Verwendung genügt eine TFDConnection. Die Konfiguration erfolgt über die Parameter DriverID, Database und LoginPrompt. Der Pfad zur Datenbank muss plattformneutral gesetzt werden.

 

 

uses
  System.IOUtils, FireDAC.Comp.Client;

procedure TDataModule1.ConnectToDatabase;
begin
  FDConnection1.Params.Values['DriverID'] := 'SQLite';
  FDConnection1.Params.Values['Database'] :=
    TPath.Combine(TPath.GetDocumentsPath, 'photoapp.db');
  FDConnection1.LoginPrompt := False;
  FDConnection1.Connected := True;
end;

 

Der Aufruf TPath.GetDocumentsPath sorgt dafür, dass die Datenbank im Dokumentenverzeichnis der App liegt – auf iOS im App-spezifischen Documents-Ordner, auf Android im internen App-Speicher. FireDAC legt die Datei automatisch an, wenn sie nicht existiert.

Ist die Verbindung hergestellt, kann per SQL-Befehl die Tabellenstruktur erzeugt werden. Die Ausführung erfolgt zum Beispiel im AfterConnect-Ereignis:

 

 

FDConnection1.ExecSQL(
  'CREATE TABLE IF NOT EXISTS PhotoEntries (' +
  'ID INTEGER PRIMARY KEY AUTOINCREMENT, ' +
  'ImagePath TEXT NOT NULL, ' +
  'Latitude REAL, Longitude REAL, ' +
  'Comment TEXT, ' +
  'TimeStamp REAL)'
);

 

Damit wird die Tabelle nur angelegt, wenn sie noch nicht existiert.

Für das Schreiben von Datensätzen verwendet man ExecSQL, für das Lesen TFDQuery. FireDAC unterstützt parametrisierte SQL-Abfragen, was sowohl sicher als auch performant ist.

 

 

procedure TDataModule1.SaveEntry(const APath, AComment: string;
  const ALat, ALon: Double);
begin
  FDConnection1.ExecSQL(
    'INSERT INTO PhotoEntries (ImagePath, Latitude, Longitude, Comment, TimeStamp) ' +
    'VALUES (:Path, :Lat, :Lon, :Comment, :Time)',
    [APath, ALat, ALon, AComment, Now]
  );
end;

 

Zum Lesen kann TFDQuery genutzt werden:

 

 

FDQuery1.SQL.Text := 'SELECT * FROM PhotoEntries';
FDQuery1.Open;
while not FDQuery1.Eof do
begin
  Memo1.Lines.Add(FDQuery1.FieldByName('Comment').AsString);
  FDQuery1.Next;
end;

 

Einige Hinweise:

  • Deployment: Wenn eine SQLite-Datei mit der App ausgeliefert werden soll, muss sie im Bereitstellungsmanager eingetragen werden – bei iOS unter StartUp\Documents, bei Android unter assets\internal.
  • LoginPrompt: Immer auf False setzen, da SQLite keine Authentifizierung benötigt.

 

Mit diesen Schritten lässt sich FireDAC auf mobilen Plattformen einsetzen. Die Kombination mit SQLite ist ideal für Offline-Apps, die Daten lokal verwalten und optional später mit einer Cloud oder einem REST-API synchronisieren.

 

Datenspeicherung für die Foto-App mit Geolocation

In dieser Beispiel-App wird durch einen Button-Klick ein Foto aufgenommen, während parallel die aktuelle Geo-Position ermittelt wird. Zu jedem Bild kann der Benutzer optional einen Kommentar eingeben. Anschließend werden das Foto, die erfassten Geo-Koordinaten sowie der Kommentar zusammen als Eintrag in einer Liste angezeigt. Diese Daten bleiben zunächst nur im Arbeitsspeicher erhalten. Die Umsetzung wurde in den ersten drei Teilen der Delphi-Cross-Plattform-Serie beschrieben.

Die App soll die Daten nun in einer lokalen SQLite-DB speichern. Dazu sind folgende Schritte notwendig:

  • FireDAC einbinden: Im Formular werden die Komponenten TFDConnection (Verbindung zur SQLite-Datenbank), TFDPhysSQLiteDriverLink (Einbindung SQLite-Treiber) und TFDQuery (SQL-Befehle zum Schreiben und Lesen) hinzugefügt.
  • Verbindung konfigurieren: Die Datenbankdatei wird im Dokumentenverzeichnis der App angelegt, damit sie auf allen Plattformen nutzbar ist. Beim ersten Start erzeugt FireDAC die Datei automatisch, falls sie noch nicht existiert:

 

uses System.IOUtils;
FDConnection1.Params.Values['DriverID'] := 'SQLite';
FDConnection1.Params.Values['Database'] :=
  TPath.Combine(TPath.GetDocumentsPath, 'PhotoDB.db');
FDConnection1.LoginPrompt := False;
FDConnection1.Connected := True;

 

  • Tabelle anlegen: Beim Start der App prüfen wir, ob die Tabelle vorhanden ist, und legen sie gegebenenfalls an. Die Spalten entsprechen den Datenfeldern aus der Datenklasse-Klasse (Bildpfad, Koordinaten, Hinweis, Zeitstempel):

 

FDConnection1.ExecSQL(
  'CREATE TABLE IF NOT EXISTS Photos (' +
  'ID INTEGER PRIMARY KEY AUTOINCREMENT, ' +
  'ImagePath TEXT NOT NULL, ' +
  'Latitude REAL, Longitude REAL, ' +
  'Comment TEXT, TimeStamp REAL)'
);

                     

  • Datensatz speichern: Wenn ein neues Foto aufgenommen wurde (Event TakePhotoFromCameraAction1DidFinishTaking), wird der Eintrag gespeichert. Dazu wird die Methode ExecSQL mit Parametern verwendet:

 

procedure TDataModule1.SavePhoto(const APhoto: TPhoto);
begin
  FDConnection1.ExecSQL(
    'INSERT INTO Photos (ImagePath, Latitude, Longitude, Comment, TimeStamp) ' +
    'VALUES (:Path, :Lat, :Lon, :Comment, :Time)',
    [APhoto.Path, APhoto.Lat, APhoto.Lon, APhoto.Note, APhoto.Timestamp]
  );
end;

 

  • Daten abrufen: Zum Laden vorhandener Einträge verwenden wir TFDQuery:

 

FDQuery1.Open('SELECT * FROM Photos ORDER BY TimeStamp DESC');
while not FDQuery1.Eof do
begin
  AddToListView(
    FDQuery1.FieldByName('ImagePath').AsString,
    FDQuery1.FieldByName('Latitude').AsFloat,
    FDQuery1.FieldByName('Longitude').AsFloat,
    FDQuery1.FieldByName('Comment').AsString
  );
  FDQuery1.Next;
end;

 

  • Integration: Beim Start (FormCreate) wird die SQLite-DB initialisiert. Nach jeder neuen Fotoaufnahme ruft man SavePhoto(…) auf. Beim Starten oder Aktualisieren der App werden die gespeicherten Datensätze per TFDQuery geladen und über RefreshListView angezeigt.

 

Damit wird aus der bisher flüchtigen In-Memory-Sammlung eine persistente Datenspeicherung. Den Projektfortschritt kann man auf GitHub verfolgen und dort auch den Quellcode herunterladen.

Synchronisation, Sicherheit, Strategien

Beachten Sie die folgenden Hinweise bei der Speicherung von Daten (lokal/Cloud) in mobilen Apps:

  • Datenabgleich und Konflikte: Wenn Daten bidirektional synchronisiert werden, der Server also Daten ändern kann, die der Client auch offline bearbeitet hat, braucht man eine Strategie zur Konfliktauflösung. Oft wird Last-Write-Wins verwendet (der letzte Stand gewinnt), oder es werden Versionsnummern beziehungsweise Uhrzeiten geprüft, um Änderungen zu erkennen. In komplexen Fällen muss der Nutzer entscheiden, welche Version gilt, oder es werden Änderungen zusammengeführt.
  • Sicherheitsaspekte: Sämtliche Datenübertragung sollte verschlüsselt (HTTPS) erfolgen. In der App sollten keine Passwörter im Klartext gespeichert sein. Stattdessen arbeitet man mit Tokens, zum Beispiel OAuth2-Access-Token oder API-Key. Diese werden sicher gespeichert (verschlüsselt) und bei jedem Request gesendet. Geheimnisse wie API-Schlüssel sollten nie im App-Code hinterlegt sein.
  • Synchronisationsstrategien: Die Synchronisation kann automatisch im Hintergrund erfolgen oder manuell auf Anforderung. Oft ist ein hybrider Ansatz sinnvoll, das heißt eine periodische Hintergrund-Synchronisierung kombiniert mit einer manuellen Synchronisations-Option.

 

Mobile Apps sollten in der Regel nicht direkt auf Datenbankserver zugreifen, denn die Stabilität der Netzwerkverbindung genügt meist nicht, und ebenso sprechen die genannten Sicherheitsaspekte dagegen. Eine Zwischenschicht (Middleware) beziehungsweise ein Backend (BaaS) sind besser geeignete Lösungsansätze.

Fazit und Ausblick

Mit der lokalen Speicherung in SQLite und der (optionalen) Cloud-Anbindung über REST-APIs rundet Delphi das Spektrum mobiler App-Entwicklung ab. FireDAC bietet dabei eine Basis für persistente Datenhaltung, während die REST-Komponenten für die Cloud-Speicherung dienen.

Insgesamt demonstriert die vierteilige Artikelreihe, dass Delphi mit FireMonkey eine leistungsfähige und effiziente Entwicklungsumgebung für plattformübergreifende Projekte ist. Entwickler profitieren von nativer Performance, einer einheitlichen Codebasis und klassischen RAD-Stärken.

Neueste Beiträge

Mathematik mit .NET - Best of NuGet, Teil 3
Der immense Erfolg der Lehrsprache Python hat die Rolle anderer Programmiersprachen im Bereich der Mathematik weitgehend eliminiert. Trotzdem bietet das Projekt Math.NET verschiedenste Bibliotheken an, die – nach der Beschaffung aus NuGet – wertvolle Funktionen zur Verfügung stellen.
6 Minuten
9. Okt 2025
DDC hakt nach: Steiniger Weg von WPF zu Avalonia?
WPF hat ausgedient? Wer ein modernes User Interface über alle Plattformen hinweg entwickeln will, kommt an Avalonia UI kaum vorbei. Doch was taugt Avalonia im Vergleich zu MAUI oder Blazor? Dieses Interview räumt mit Mythen auf – und zeigt, worauf sich Entwickler:innen einstellen müssen.
5 Minuten
13. Okt 2025
Copilot Agent Mode – Implementieren eines eigenen MCP-Servers
Wie KI-gestützte Development-Workflows von mit .NET selbst entwickelten MCP-Servern profitieren.
8 Minuten
13. Okt 2025

Das könnte Dich auch interessieren

Delphi als Turbo für die mobile Entwicklung - Mobile Apps entwickeln mit Delphi, Teil 1
Delphi ermöglicht es, effizient plattformübergreifende Anwendungen zu erstellen. In diesem ersten Teil der Serie beleuchten wir die Motivation ebenso wie das Setup eines ersten Beispielprojekts.
6 Minuten
Einfach und schnell zur webbasierten Datenbank-App - GAPTEQ
Die Low-Code-Plattform GAPTEQ bietet bei der Entwicklung individueller Web-Anwendungen mit Zugriff auf SQL-Datenbanken eine nutzerfreundliche Alternative zu MS-Access.
2 Minuten
iOS-Apps ohne Mac und Xcode - Tabris.js, Innoopract
Ein Notebook mit beliebigem Betriebssystem, ein Editor zum Schreiben des Quellcodes und das auf JavaScript basierende Tabris.js genügen, um Android- und iOS-Apps zu erstellen.
3 Minuten
27. Nov 2019
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige