The post RAD Studio WebStencils: Die Delphi-Alternative zu Next.js & Co. appeared first on Entwickler Konferenz.
]]>In einer Zeit, in der sich Web-Entwicklungstrends ständig wandeln, erleben wir eine bemerkenswerte Rückkehr zu den Wurzeln: Server-Side Rendering (SSR) erlebt durch moderne Werkzeuge wie RAD Studio WebStencils eine Renaissance. In diesem Artikel werden Sie genau diese Technologie grundlegend kennenlernen, die Ihnen helfen wird, Ihre Webanwendungen schneller und effizienter zu entwickeln. Bevor wir in die Welt der WebStencils eintauchen, werfen wir einen Blick auf die Evolution der Web-Entwicklung und die Herausforderungen, die mit modernen Ansätzen verbunden sind. Anschließend werden die Grundlagen von WebStencils anhand
von einfachen Desktop-Anwendungen vermittelt – von der Komplexität einer Webanwendung sind wir hier noch weit entfernt. Abschließend werden wir eine simple Webseite mit Inhalten aus einer Datenbank mit WebStencils erstellen, um die Möglichkeiten dieser neuen Technologie zu demonstrieren.
Die Evolution der Web-Entwicklung
Ironischerweise gab es in den Anfangsjahren des Webs eine klare Trennung zwischen Server- und Client-Rendering. Mit der Einführung von SPAs verschwammen diese Grenzen zunehmend, was zu einer Vielzahl von Herausforderungen führte. Mit Delphi DataSnap und RAD Server wurden bereits vor vielen Jahren Lösungen für diese Probleme entwickelt. Allerdings waren diese Lösungen nicht in der Lage, die Vorteile von SSR zu nutzen. Insbesondere mit RAD Server wurden andere Ziele verfolgt. Es ging um die Entwicklung von REST-APIs und nicht um die Entwicklung von Webanwendungen. Mit RAD Studio WebStencils wird diese Lücke nun geschlossen. Zudem stellt Embarcadero mit WebStencils auch zahlreiche Beispiele für den Einsatz von HTMX auf der Client Seite bereit, die die Möglichkeiten von WebStencils eindrucksvoll demonstrieren. Ohne JavaScript-Frameworks, ohne Node.js und ohne Build-Prozesse kann so nun eine moderne Webanwendung entwickelt werden. Eine Erweiterung mit JavaScript-Frameworks ist jederzeit möglich. Selbstverständlich steht mit TypeScript auch eine typisierte Sprache im Web zur Verfügng, die immer mehr an Prägnanz gewinnt und ebenso mit WebStencils benutzt werden kann. Auch der Einsatz mit anderen Web Frameworks ist möglich. WebStencils kann z.B. auch mit TMS WEB Core genutzt werden. TMS WEB Core ist insbesondere für Delphi Entwickler interessant, da es die Entwicklung von SPAs mit Object Pascal ermöglicht und kein Erlernen einer neuen Programmiersprache erforderlich ist.
RAD Studio WebStencils: Die moderne Antwort mit einer bewährten Programmierumgebung
RAD Studio WebStencils vereint die Vorteile klassischer Server-Side Rendering-Ansätze mit modernen Entwicklungspraktiken. Das Framework ermöglicht:
Der Trend zur Rückkehr zum Server-Side Rendering, auch “SSR Renaissance” genannt, zeigt sich nicht nur bei WebStencils. Frameworks wie Next.js, Remix und Nuxt.js folgen einem ähnlichen Ansatz. Dies unterstreicht die wachsende Erkenntnis, dass ein hybrider Ansatz aus Server- und Client-Rendering oft die beste Lösung darstellt.
Diese Evolution markiert einen wichtigen Wendepunkt in der Web-Entwicklung, bei dem RAD Studio Web-Stencils eine Schlüsselrolle einnimmt.
Und was passiert mit den Single Page Applications und dazugehörigen Frameworks?
WebStencils haben nicht das Ziel verfolgt, Single Page Applications (SPAs) zu ersetzen, sondern um sie zu ergänzen. WebStencils können problemlos in bestehende SPAs integriert werden. Sie können sie verwenden, um bestimmte Teile Ihrer Anwendung serverseitig zu rendern, während andere Teile weiterhin als SPAs funktionieren. Somit können Sie die Vorteile beider Ansätze nutzen
und ihr gewohntes Web Framework, wie z.B. TMS WEB Core, weiterhin verwenden.
In vielen Fällen ist eine hybride Lösung die beste Wahl. WebStencils ermöglicht es Entwicklern, die Vorteile beider Ansätze zu nutzen und maßgeschneiderte Lösungen für ihre spezifischen Anforderungen zu erstellen. Insbesondere in TMS WEB Core führt die Kombination von SSR und SPAs zu einer kürzeren und effizienteren Entwicklungszeit.
Loslegen mit WebStencils
RAD Studio WebStencils sind Bestandteil von RAD Studio bzw. Delphi 12 und erfordern keine besondere Installation. Erst kürzlich wurde Version 12.3 von RAD Studio vorgestellt, die auch neue Funktionen für WebStencils mitbringt. Sie können nach der Installation sofort loslegen und die Vorteile von Server-Side Rendering in Ihren Projekten nutzen. Embarcadero stellt leider nur wenige Beispiele zur Verfügung. Hier sei auf die zahlreichen Webinare von Embarcadero verwiesen, die auch nachträglich noch auf YouTube
angeschaut werden können. WebStencils wurden hier in den vergangenen Monaten thematisiert und mit zahlreichen Beispielen demonstriert.
Wie funktionieren WebStencils?
Im Kern erzeugt WebStencils Textinhalte basierend auf einer Vorlage. Sie können diese Vorlagen entweder als String definieren oder aus einer Datei laden. Es gibt keine zwingende Verbindung zu Webtechnologien. WebStencils kann in jedem Delphi-Projekt verwendet werden. Laut Marco Cantu, dem Produktmanager von Delphi, ist es von Natur aus kein meinungsstarkes (engl. opinionated) Framework. Dies öffnet es für die Verwendung in jedem Szenario und ermöglicht es auch Drittentwicklern, es in ihren eigenen Frameworks zu verwenden. Embarcadero hat daher alle Komponenten für WebStencils aus Klassen abgeleitet, die leicht mit WebBroker, DataSnap und RAD Server verwendet werden können. Dies impliziert auch den Hauptanwendungsfall für WebStencils: Einfache Erstellung von Webseiten oder anderen web-spezifischen Dateiformaten mit einer modernen Template-Engine. Die folgende Abbildung zeigt die drei Bausteine von WebStencils. Eine Vorlage wird in den Prozessor geladen, der an eine Engine gebunden werden kann. Sowohl für Prozessor (Processor) als auch Engine existieren Komponenten, die man einfach auf Formularen und Datenmodulen verwenden kann. Eine Engine kann dbaei mehrere Prozessoren mit gemeinsamen Einstellungen verwalten, ist jedoch völlig optional und kein zwingender Bestandteil der Prozesskette. Die folgenden Beispiele werden sich daher auf die Verwendung des Prozessors (Processor) beschränken. Jedes Textformat kann generiert werden. Heutzutage sind XML, HTML, JSON und Markdown wahrscheinlich die am häufigsten verwendeten Dateiformate. Wir erkennen nun direkt, dass es keinerlei Bindung an die exklusive Verwendung für Webanwendungen gibt. Es ist somit z.B. auch denkbar WebStencils für die Ertstellung von simplen ‘Serienbriefen’ in VCL Desktopanwendungen zu verwenden.
Der Prozessor erzeugt Inhalte basierend auf einer Vorlage. Eine Vorlage enthält Platzhalter, die
durch Text ersetzt werden können. Dieser Text kann durch Ereignisse, eine TDataSet-Instanz oder
Felder und Eigenschaften eines beliebigen Objekts (abgeleitet von TObject) bereitgestellt werden.
Der Prozessor akzeptiert eine einzelne Objektinstanz sowie ein Modul, das seine Eigenschaften
und Felder mithilfe eines benutzerdefinierten Attributs an den Prozessor veröffentlicht.
Zusätzlich zum Textersatz kann die Vorlage spezielle Schlüsselwörter enthalten. Das sind z.B. Aus-
drücke um simple Berechnungen durchzuführen sowie Bedingungen (@if), ob Teile der Vorlage einbezogen werden sollen oder nicht. Außerdem können Sie über alle Datensätze eines Datensets iterieren und bestimmte Passagen der Vorlage für jeden Datensatz generieren (@foreach).
Wenn Sie eine Vorlage angeben, kann sie spezielle Platzhalter enthalten, um Teile aus anderen Vorlagen zu laden bzw. importieren. Auf diese Weise können Sie leicht ein gemeinsames HTML-Dokument definieren und dann individuell mit dem Inhalt für den jeweiligen zu generierenden Inhalt füllen.
Figure 1: So funktionieren WebStencils
Stellen Sie sich eine Website vor, die in drei Hauptgruppen strukturiert ist: – Kopfzeile (Header) mit Navigationsleiste – Hauptinhalt (Main Content) – Fußzeile (Footer)
Sie können dann eine Vorlagendatei angeben, die die Kopf- und Fußzeile enthält, aber der Hauptinhalt wird jedes Mal ersetzt.
Die folgenden Beispiele führen in die Grundlagen der Vorlagenerstellung ein und zeigen, wie man Vorlagenplatzhalter mit Werten durch Ereignisse, Datasets und Objekte ersetzt. Weiterführende Beispiele verwenden die Edge-Webbrowser-Komponente, um responsive Webinhalte darzustellen. Die Vorlagen enthalten dann HTML, das mit Daten aus einer SQLite-Datenbank gefüllt wird. Eine Erstellung von Web Servern mit Web Broker ist ebenfalls möglich, wird aber in diesem Artikel nicht behandelt.
Formale Beschreibung von WebStencils
WebStencils ist ein ‘Textinhalt-Generator’, der für serverseitiges Scripting verwendet werden kann. Im Kontext von mehrschichtigen Anwendungen ermöglicht die Skriptsprache innerhalb einer Vorlage die Erstellung beliebiger Textformate im Backend. Die Tatsache, dass Sie sowohl HTML als auch JSON erstellen können, macht es sehr flexibel, sowohl eine API als auch sogenannte visuelle Serverkomponenten zu implementieren. Sie können die Stärke der Delphi-Datenbank-Frameworks nutzen, um Informationen aus Datenbanken einzubeziehen, aber auch Ihre Datenbanken mit Daten zu aktualisieren, die im Frontend eingegeben wurden. Es ist
jedoch nicht nur für mehrschichtige Szenarien geeignet. WebStencils kann auch in herkömmlichen Delphi Windows Desktop-Anwendungen verwendet werden, um Serienbriefe oder andere dynamische Textdokumente zu erstellen. Für Web-Anwendungsfälle kann es leicht in bestehende Web-Frameworks wie z.B. WebBroker, RAD Server, DataSnap und TMS WEB Core integriert werden, um die Erstellung von HTML-Seiten zu unterstützen, die auf Vorlagen basieren.
Hallo WebStencils!
Lassen Sie uns WebStencils mit einem sehr einfachen Beispiel kennenlernen. Es kann als das ‘Hello World’ von WebStencils bezeichnet werden. Ich habe eine Windows VCL-Anwendung erstellt. Das Web wird in diesem Beispiel noch keine Rolle spielen. Zuerst müssen wir verstehen, wie WebStencils funktionieren, und dann können wir dies auf Webtechnologien übertragen.
Das Hauptformular der Anwendung enthält eine einzelne Schaltfläche, um den WebStencils-Prozessor zu starten. Der Prozessor kann in der Werkzeugpalette als TWebStencilsProcessor gefunden werden.
Figure 2: Hauptformular des Beispiels im Formulardesigner.
Offensichtlich sehen wir zur Laufzeit nur die einzelne Schaltfläche. Innerhalb des Schaltflächenereignisses werden wir den Code implementieren, um WebStencils zu verwenden. Wenn Sie auf die Schaltfläche klicken, wird nur ein kurzes Nachrichtenfeld mit dem Text –Hello World– angezeigt.
Figure 3: Hauptformular des Beispiels im Formulardesigner.
Der WebStencils Prozessor benötigt eine Vorlage und mindestens ein Objekt, ein Dataset, ein Modul oder ein Ereignis, um auf die Vorlage angewendet zu werden.
Diese schließen sich nicht gegenseitig aus. Sie können gleichzeitig beliebige Eingabequellen anwenden. Das bedeutet, dass Sie einige Ersetzungen in Ihrer Vorlage sowohl mit einem Ereignis als auch mit einem Dataset bereitstellen können, zum Beispiel.
In diesem Beispiel werden wir ein Ereignis bereitstellen, das Text innerhalb der Vorlage ersetzt.
Eine Vorlage definieren
Eine Vorlage ist nichts anderes als reiner Text. Sie kann entweder als TStringList in der Eigenschaft InputLines oder als Dateiname angegeben werden. Die Datei wird dann geladen, bevor der Prozessor aufgefordert wird, die Vorlage zu verarbeiten.
Wenn Sie einen Dateinamen angeben, wird jeder andere Vorlageninhalt ignoriert. Nur der Inhalt der angegebenen Datei wird verwendet. Jeder Text im Inhalt bleibt unberührt und wird in die Ausgabe kopiert, es sei denn, Sie verwenden das @-Symbol. Dieses Symbol zeigt WebStencils an, dass Sie entweder eine zu ersetzende Variable oder ein Schlüsselwort definieren möchten. Schlüsselwörter sind zum Beispiel @if oder @foreach und werden später besprochen.
Konzentrieren wir uns darauf, Text innerhalb der Vorlage zu ersetzen.
Processor.InputLines.Text := ’–@Data.Text–’;
Die obige Zeile setzt die Vorlage innerhalb der Processor-Komponente. Die Eigenschaft InputLines ist vom Typ TStringList. Wie bereits erläutert, ist dies eine Alternative zur Angabe eines Pfads zu einer Datei, die die Vorlage enthält. Wir bemerken, dass die Vorlage das @-Symbol gefolgt von Data.Text verwendet. Data wird als Objekt und Text als Eigenschaft bezeichnet. Formal werden diese beiden vom Prozessor ausgewertet und ergeben einen Wert.
Das Objekt und die Eigenschaft sind beide symbolische lokale Namen und können mithilfe des OnValue-Ereignishandlers aufgelöst werden. Alternativ können wir Objekte, Datensätze und Module unter einem ‘Namen’ registrieren, den wir dann mit @ referenzieren können. Der resultierende Wert ist dann entweder eine Zeichenkette, die im OnValue-Ereignis übereinstimmt, eine Objekteigenschaft oder ein Feld eines Datasets.
Da wir in diesem Beispiel einen einfachen Ereignishandler verwenden möchten und keine Datensätze oder Objekte definiert haben, müssen wir ein OnValue-Ereignis für die Processor Komponente implementieren.
Schwierige Verwendung von @
Auf den ersten Blick erscheint alles ziemlich einfach zu sein. Wann immer Sie einen Marker definieren möchten, verwenden Sie das @-Symbol. Es gibt nur ein winziges Problem. Was ist, wenn Ihre Vorlage @-Symbole enthält? Es gibt mehrere Fälle, in denen dies passieren kann:
Dies sind nur einige Beispiele, die mir in den letzten Monaten begegnet sind. Ich bin sicher, es gibt noch viele mehr.
Die Lösung besteht darin, ein zusätzliches @-Symbol hinzuzufügen. Wenn Sie das @-Symbol tatsächlich Teil Ihrer Vorlage machen möchten, müssen Sie zwei davon in Ihre Vorlage aufnehmen. Das bedeutet, wenn Sie @@ schreiben, wird es nach der Verarbeitung zu @. Angenommen, ich möchte meine E-Mail-Adresse in die Vorlage aufnehmen, würde ich die folgende Vorlagenzeichenkette
erstellen:
Email me at holger@@flixengineering.com !
Dies wird zu:
Email me at [email protected] !
Dies kann sehr mühsam sein, insbesondere wenn Sie Dateien von der Festplatte laden, die für andere Zwecke als die Verwendung mit der WebStencil-Vorlagen-Engine vorbereitet wurden. Stellen Sie sich vor, Sie greifen auf ein Repository von HTML-Vorlagen in Ihrem Unternehmen zu, das auch von anderen HTML-Anwendungen verwendet wird. Sie können diese Vorlagen nicht ändern, ohne es den anderen Anwendungen unmöglich zu machen, sie zu verwenden. Daher müssten Sie diese Vorlagen laden, die Änderungen vornehmen und sie dann an WebStencils übergeben. Obwohl dies möglich ist, ist es eine sehr unbefriedigende Lösung. Stattdessen hat WebStencils das @processing-Schlüsselwort eingeführt: – @processing on: Verarbeite Marker in dieser Vorlage. Dies ist die Standardeinstellung. – @processing off: Verarbeite Marker in dieser Vorlage nicht. Dies ermöglicht es, Vorlagen ‘wie sie sind’ an den Prozessor zu übergeben.
Das @processing-Schlüsselwort betrifft die gesamte Vorlage. Daher ist es ratsam, es in Verbindung mit kleineren Vorlagenschnipseln zu verwenden, die Sie mithilfe von @import in eine größere Vorlage laden.
Auf diese Weise kann jeder Schnipsel individuell Marker verarbeiten oder nicht.
Implementierung des Ereignisses
Wenn wir die Prozessor-Komponente auswählen und uns ihre Ereignisse ansehen, finden wir das Ereignis namens OnValue.
procedure TForm1.ProcessorValue(Sender: TObject; const AObjectName, APropName:
string; var AReplaceText: string; var AHandled: Boolean);
begin
if (AObjectName = ’Data’) and (APropName = ’Text’) then
begin
AReplaceText := ’Hello World’;
AHandled := True;
end;
end;
Wann immer der Prozessor auf ein @-Symbol gefolgt von einem Objekt und einem Wert stößt, wird OnValue ausgelöst. Im Parameter AObjectName wird der Name des Objekts sowie der Name des Werts in APropName übergeben. Der Codeausschnitt zeigt, dass wir einfach den Namen des Objekts und den Eigenschaftsnamen vergleichen können, ob sie mit dem übereinstimmen, wonach wir
suchen. In diesem Fall möchten wir Data.Text durch Hello World für das Objekt Data und seine Eigenschaft Text ersetzen. Dafür weisen wir den Ersetzungstext der Variablen AReplaceText zu. Diese wird an den Prozessor zurückgegeben, da sie mit var definiert ist. Gleiches gilt für den Parameter AHandled. Sie müssen ihn auf True setzen, wenn Sie eine Ersetzung vorgenommen haben. Auf diese Weise weiß der Prozessor, ob alle Symbolmarkierungen in der Vorlage ersetzt wurden oder nicht. Wenn nicht alle Markierungen behandelt werden, kann der Prozessor eine Exception werfen.
Starten des Prozessors
Um den Prozessor zu starten, lesen Sie den generierten Text mit der Content-Funktion. Es sieht aus wie eine Eigenschaft, ist aber tatsächlich eine Funktion:
TWebStencilsProcessor = class(TCustomContentProducer, IWebStencilsComponent)
public
constructor Create(Owner: TComponent); override;
destructor Destroy; override;
/// <summary> Produziert Inhalt aus der Vorlage, die durch InputFileName angegeben wird.
/// Wenn InputFileName leer ist, wird InputLines verwendet. </summary>
function Content: string; override;
Die vollständige Implementierung des Button.OnClick-Ereignisses ist wie folgt:
procedure TForm1.Button1Click(Sender: TObject);
begin
Processor.InputLines.Text := ‘–@Data.Text–‘;
ShowMessage(Processor.Content);
end;
Weisen Sie zuerst die Vorlage mit einem String zu. Zeigen Sie dann den generierten Inhalt mit ShowMessage an. Es wird das OnValue-Ereignis bei Bedarf implizit abgerufen. In diesem Fall wird es nur einmal ausgeführt, da wir nur einen Marker verwenden.
Es ist nicht notwendig, Leerzeichen zwischen Markern und dem Text, der Teil der Vorlage ist, zu lassen. Ich habe absichtlich führende und nachfolgende — Zeichen zur Vorlage hinzugefügt. Nur die Markerdeklaration wird ersetzt. Denken Sie auch daran, dass jedes Mal, wenn Sie Processer.Content lesen, die Vorlage erneut ausgewertet wird. Das bedeutet, dass Sie dieselbe Komponente für verschiedene Vorlagen oder flexiblere Ereignisimplementierungen wiederverwenden können.
Ja, es ist so einfach!
Herzlichen Glückwunsch! Dies sind die Grundlagen der Prozessor-Engine von WebStencils. Sie hätten nicht gedacht, dass es so einfach sein würde, oder?
Auf diese Weise können Sie bereits flexible Textinhalte erstellen, die sich beispielsweise auf berechnete Werte stützen.
Das Ersetzen aller Platzhalter im OnValue-Ereignis könnte für alle möglichen Ersetzungen verwendet werden, ist jedoch nicht sehr effizient. Stellen Sie sich vor, ein Dataset hat Dutzende von Feldern und Sie müssen für jedes Feld mehrere Codezeilen im Ereignishandler hinzufügen.
WebStencils bietet Mittel, um dies viel sauberer und effizienter zu handhaben. Daher zeigt das nächste Beispiel, wie man Datensätze aus einem TDataSetverwendet.
Verarbeitung von einzelnen Datensätzen und kompletten Datasets
Im ersten Beispiel haben wir gelernt, wie man einen Platzhalter in einer Vorlage mit dem OnValue-Ereignis ersetzt. Jetzt wird es etwas komplexer, da wir Datasets mit WebStencils einführen. Auch hier verwenden wir eine Windows VCL-Anwendung, um die Funktion zu demonstrieren. Zur Entwurfszeit platzieren wir zwei Schaltflächen auf dem Formular. Eine Schaltfläche wird ein Beispiel ausführen, dass eine Vorlage verwendet, um den aktuellen Datensatz des Datasets zu verarbeiten (Process current record). Die andere Schaltfläche startet ein Beispiel, das eine Vorlage erstellt, um das gesamte Dataset zu durchlaufen (Process ALL records). Der vom Prozessor generierte Text wird im Memo-Steuerelement namens txtResult angezeigt.
Figure 4: Hauptformular des Beispiels im Formulardesigner.
Die Daten werden in einem TFDMemTable gespeichert. Dies ist die FireDAC-Komponente, die ein Client Dataset mit vielen weiteren Funktionen als die traditionelle TCientDataset-Komponente kapselt. Die in diesem Dataset definierten Daten sind trivial. Wenn Sie den Feldeeditor öffnen, sehen Sie, dass es drei Felder mit primitiven Datentypen gibt.
Wir können den Vor- und Nachnamen einer Person sowie ihr Alter speichern. Die ersten beiden Felder sind natürlich vom Typ String, das letzte Feld ist ein Integer-Feld. Eine der großartigen Funktionen von FireDAC ist, dass Sie die Daten dieser Datensätze zur Entwurfszeit im Formular-Editor bearbeiten können. Klicken Sie einfach mit der rechten Maustaste auf die TFDMemTable-Komponente und wählen Sie Edit DataSet… aus, um den Entwurfszeit-Dateneditor zu öffnen.
Figure 5: Feld-Editor des FDMemTable
Figure 6: Daten können direkt zur Entwurfszeit bearbeitet werden.
Figure 7: Der Entwurfszeit-Dateneditor von FireDAC
Die Daten werden innerhalb des Formulars gespeichert und sind zur Laufzeit verfügbar. Dies macht das Erstellen von Demos mit FireDAC zu einer Freude, da Sie für einfache Beispiele wie dieses keine Datenbankdatei benötigen. Wenn Sie die Anwendung ausführen, können Sie entweder den aktuellen Datensatz (der der erste sein wird) oder alle Datensätze verarbeiten. Wenn Sie möchten, können Sie dieses Demo erweitern, indem Sie ein Navigator-Steuerelement hinzufügen, um durch das Datenset zu navigieren.
Zugriff auf den aktuellen Datensatz
Um auf einen Datensatz zuzugreifen, können Sie die Methode verwenden, die Sie im ersten Beispiel gelernt haben. Sie binden das Dataset an einen Objektnamen, und die Feldnamen werden als Werte verwendet. Schauen wir uns die verwendete Vorlage an:
procedure TForm1.btnProcessOneClick(Sender: TObject);
begin
Processor.InputLines.Text :=
”’
Text is @People.LastName!
Text is @People.FirstName @(UpperCase(People.LastName))
”’;
Process;
end;
Erneut weisen wir InputLines.Text einen String zu. Die erste Zeile der Vorlage bezieht sich auf People.LastName. Der Wert von People bezieht sich auf das Feld LastName. Wie können wir WebStencils mitteilen, People an das Dataset zu binden? Die Prozessorkomponente Processor hat eine Methode namens AddVar, die drei Parameter akzeptiert:
Im Code sieht das so aus:
Processor.AddVar( ’People’, People, False );
Das bedeutet, wir binden das Dataset People an den Marker namens People. Beachten Sie, dass der Markername ein String ist. Der letzte Parameter ist False, da die VCL People freigibt, wenn die Anwendung beendet wird. Wenn Sie True angeben würden, würde das Dataset nach der Verarbeitung freigegeben, und Sie würden höchstwahrscheinlich eine Zugriffsverletzung erhalten, wenn die Anwendung beendet wird. Wenn Sie den Prozessor ein zweites Mal ausführen, wird er mit Sicherheit eine Zugriffsverletzung auslösen, da das Dataset nicht mehr verfügbar ist.
Zusammenfassend weist die Zeile das Dataset People allen @People-Vorkommen zu. Dies impliziert auch, dass jeder Wert ein Feld im Dataset sein muss. Betrachtet man @People.LastName, ist dies korrekt, und wir erwarten, dass der Nachname anstelle des Markers eingefügt wird, wenn er verarbeitet wird.
Die nächste Zeile der Vorlage fügt ebenfalls den Vornamen mit @People.FirstName ein. Anschließend wird die nächste Ersetzung etwas komplexer, zeigt jedoch, dass wir sogar Funktionen aus Delphi in unserer Vorlage verwenden können. WebStencils ist ziemlich intelligent und löst Funktionen mithilfe von RTTI auf.
Falls Sie nicht wissen, was RTTI ist, denken Sie einfach so darüber: Sie können Funktionsnamen eingeben, die für die Prozessorkomponente zugänglich sind, und dieser wird in der Lage sein, diese Funktionen aufzurufen.
Wenn Sie einen Ausdruck auswerten möchten, müssen Sie ihn in Klammern setzen. Anstelle von @People.LastName müssen Sie also @( Ausdruck ) verwenden. Die Klammern sind der Schlüssel, damit es funktioniert. So wird @( UpperCase( @People.LastName )) zuerst @People.LastName auswerten und das Ergebnis dann in UpperCase einfügen. Beachten Sie jedoch, dass Sie keine String-Helfer oder andere Dinge mit Duck Typing aufrufen können. Dies wird nicht funktionieren:
@People.LastName.toUpper
Das würde buchstäblich zu folgendem Ergebnis führen, wenn der Nachname des Datensatzes auf Reacher gesetzt ist:
Reacher.toUpper
Der .toUpper-Teil wird einfach zu Text und nicht zu einem Ausdruck. Außerdem ist es ratsam, Ausdrücke sehr kurz zu halten. Verwenden Sie berechnete Felder, wann immer Sie Datensätze mit WebStencils verwenden. Ihr Code wird dadurch viel sauberer, und Sie haben Zugriff auf die gesamte Vielfalt der Object Pascal-Sprache. Genau wie im ersten Beispiel ist dies bereits alles, was Sie tun müssen, um einen einzelnen Datensatz zu verarbeiten:
Beachten Sie, dass Sie den zweiten Schritt nur einmal implementieren müssen und die Vorlage so oft ändern können, wie Sie möchten. Die Referenz des Namens zum Dataset bleibt erhalten. Wir nutzen dies im Beispiel, da ich das Symbolmarker nur einmal für beide Anwendungsfälle binde, nachdem das Formular erstellt wurde:
procedure TForm1.FormCreate(Sender: TObject);
begin
txtResult.Clear;
Processor.AddVar( ‘People’, People, False );
end;
Wie zuvor gezeigt, weisen wir im Button-Klick-Ereignis die Vorlage zu und führen den Prozessor aus, indem wir die Methode Process aufrufen. Die Methode Process weist den Inhalt der Memo-Komponente zu. Implizit wird dadurch die Vorlage verarbeitet.
procedure TForm1.Process;
begin
txtResult.Lines.Text := Processor.Content;
end;
Figure 8: Ausgabe des Beispiels für einen Datensatz
Iterieren aller Datensätze
Wenn wir alle Datensätze iterieren und eine Vorlage darauf anwenden möchten, müssen wir die Vorlage ändern und nicht wie man vielleicht denken könnte die Art und Weise, wie wir den Prozessor aufrufen. Genauer gesagt, kommt hier das Schlüsselwort @foreach ins Spiel. Wir werden zunächst die vereinfachte Variante des Schlüsselworts verwenden, bevor wir uns die formal korrekte und bessere Methode ansehen, eine Iteration in der WebStencils-Skriptsprache auszudrücken. Das Schlüsselwort @foreach funktioniert ähnlich wie Delphis relativ neue for-in-Schleife. Denken Sie an die Delphi-Schleife for var person in people. Wenn people eine Liste ist, iterieren wir die Liste, und jedes Element der Liste wird in person zurückgegeben. Genau so funktioniert @foreach. Der Name leitet sich tatsächlich von anderen Programmiersprachen ab, die keine for-in-Schleife, sondern ein foreach-Schlüsselwort haben. Schauen wir uns die Vorlage an, die wir verwenden können, um alle Datensätze in einem Dataset zu iterieren. Wie zuvor ist das Dataset an den Marker namens People gebunden.
procedure TForm1.btnProcessAllClick(Sender: TObject);
begin
Processor.InputLines.Text := ”’
@ForEach People {
Text is @loop.LastName!
Text is @loop.FirstName @loop.LastName
}
”’;
Process;
end;
Das Schlüsselwort @foreach wird gefolgt vom Namen des Markers, der auf das Dataset verweist. In diesem Fall verwenden wir erneut People. Dann müssen wir den Teil der Vorlage, der für jeden Datensatz eingefügt werden soll, mit {…} umschließen. Betrachtet man das Beispiel, bedeutet das, dass der folgende Teil für jeden Datensatz eingefügt wird:
Text is @loop.LastName!
Text is @loop.FirstName @loop.LastName
Die Referenz wechselt von People zu @loop. Sie bezieht sich auf die aktuelle Instanz der Iteration. Wie zuvor können wir nun die Feldnamen als Werte verwenden. Somit bezieht sich @loop.LastName auf das Feld LastName des aktuellen Datensatzes des Iterationsschritts. WebStencils stellt sicher, dass es mit dem ersten Datensatz loslegt und mit dem letzten endet. Sie müssen nicht First aufrufen, um den Datensatzzeiger auf den ersten Datensatz zu setzen. WebStencils wird den Datensatzzeiger vor der Verarbeitung auf den ersten Datensatz setzen.
Bei Anwendung der Vorlage auf alle Datensätze wird der Text in der Memo-Komponente wie folgt angezeigt:
Erweiterte Nutzung von @ForEach
Das letzte Beispiel verwendet @ForEach, um über alle Datensätze eines Datasets zu iterieren. Jedes Element der Iteration kann mit @loop angesprochen werden. Dies ermöglicht es uns, über eine Liste zu iterieren. Sobald jedoch verschachtelte Schleifen benötigt werden, ist es nicht mehr möglich, auf das aktuelle Element einer der Schleifen zuzugreifen, weil beide Schleifen dann über @loop referenziert werden. Das bedeutet, dass Sie nicht mehr wissen, auf welches Element Sie sich beziehen. In diesem Fall müssen Sie die vollständige Definition von @ForEach verwenden.
Genauer gesagt ist @ForEach Object {} eine vereinfachte Syntax, die von WebStencils aus Komfortgründen bereitgestellt wird. Die vollständige Definition von @ForEach sieht etwas komplexer aus:
@ForEach ( var Object in List ) { … }
Das bedeutet, dass unser letztes Beispiel auch wie folgt ausgedrückt werden könnte:
Figure 9: Ausgabe des Beispiels für alle Datensätze
@ForEach ( var loop in People ) { … }
Angenommen, jeder Datensatz in People hätte mehrere Adressen. Sie könnten wie folgt iterieren:
@ForEach ( var person in People ) {
@ForEach ( var address in @person.addresses ) {
Text ist @address.street
Text ist @address.city
}
}
Wir schliessen diesen Artikel damit ab, uns anzuschauen, wie wir HTML-Inhalte mit WebStencils generieren können. Wir verwenden dazu die Edge-Browser-Komponente, um die HTML-Inhalte darzustellen. Die Edge-Browser-Komponente ist Bestandteil von RAD Studio 12.3 und kann in der Werkzeugpalette gefunden werden. Sie ist eine Wrapper-Komponente um den Microsoft Edge WebView2 Browser. Diese Komponente ist die einzige Möglichkeit, HTML-Inhalte in Delphi darzustellen, die auf dem neuesten Stand der Technik sind. Sie können sie verwenden, um HTML-Inhalte darzustellen, die mit WebStencils generiert wurden.
Generierung von HTML-Inhalten
Bisher enthielten alle Beispiele nur einfachen Text. Jetzt sind wir bereit, HTML-Tags zur Vorlage hinzuzufügen. Wie Sie sehen werden, ist daran nichts Besonderes. Wir fügen einfach die HTML-Tags zur Vorlage hinzu, und der Inhalt wird wie zuvor generiert. Auch wenn ich kein Tutorial zu HTML geben kann, denken Sie daran, dass HTML die Struktur eines Dokuments und dessen Inhalt bestimmt. Die Formatierung erfolgt in der Regel mit CSS. CSS ist eine Stylesheet-Sprache, die das Layout und die Formatierung von HTML-Dokumenten definiert. CSS wird in der Regel in einem separaten Stylesheet gespeichert, das dann in das HTML-Dokument eingebunden wird. Es ist jedoch auch möglich, CSS direkt im HTML-Dokument zu definieren. Falls Sie sich fragen, warum HTML-Dokumente auch ohne CSS in einem Webbrowser gerendert werden, liegt die Antwort in Ihrem Webbrowser. Jeder Browser hat einen Standardsatz von Stilen (engl. styles), die verwendet werden, wenn Ihr HTML-Dokument keine benutzerdefinierten Stile definiert.
Im Jahr 2024 sehen die Standardvorgaben, die formal als User Agent Style Sheets bezeichnet werden, immer noch ziemlich so aus wie im Jahr 2000. Um eine modern aussehende Webseite zu erstellen, sollten Sie daher immer CSS verwenden. Entweder nutzen Sie ein CSS-Framework wie Bootstrap oder Tailwind, oder Sie definieren Ihre eigenen Styles. In der Regel ist es eine gute Idee, mit einem CSS-Framework zu beginnen, anstatt zu versuchen, Ihre eigenen Styles von Grund auf zu definieren.
Dieses Beispiel verwendet dasselbe Dataset wie das letzte. Ich habe den Button und die Funktionalität entfernt, um nur Inhalte für den aktuellen Datensatz zu generieren. Der Prozessor wird immer das gesamte Dataset durchlaufen. Zu Beginn verwenden wir weiterhin eine Memo-Komponente, um den generierten HTML-Inhalt anzuzeigen. Das Hauptformular sieht jetzt so aus:
Figure 10: Hauptformular des Beispiels im Formulardesigner.
Um HTML zu generieren, müssen wir HTML-Elemente zur Vorlage hinzufügen. Beachten Sie, dass dies ein sehr einfaches Beispiel ist. Es enthält nicht einmal einen Datei-Header, der für eine vollständige Seite erforderlich ist. Der Edge Webbrowser (und auch Chrome) wird die Seite trotzdem rendern. Das Beispiel zeigt nur, dass Sie HTML-Elemente zur Vorlage hinzufügen können.
Schauen wir uns den Quellcode mit der Vorlage an, die diese Ausgabe generiert:
procedure TForm1.btnProcessAllClick(Sender: TObject);
begin
Processor.InputLines.Text := ”’
@ForEach People {
<h1>@loop.FirstName @loop.LastName</h1>
<p>@loop.FirstName is @loop.Age years old.</p>
}
”’;
Process;
end;
Da wir über alle Datensätze iterieren und beabsichtigen, für jeden Datensatz das gleiche HTML-Snippet zu generieren, muss dieser Teil in @ForEach {} eingeschlossen werden. Dann drucken wir den Vor- und Nachnamen als Überschrift erster Ordnung mit <H1>. Die nächste Zeile wird als Absatz formatiert, indem der Text mit <P> eingeschlossen wird. Beachten Sie, dass die Komponente TMemo keine Funktionalität bietet, um das erstellte HTML-Snippet zu interpretieren. Es wird es als einfachen Text anzeigen.
Figure 11: Ergebnis der HTML-Vorlage in der TMemo-Komponente
Verwendung der Edge-Browser-Komponente
Im letzten Beispiel haben wir HTML-Inhalte erstellt, die als reiner Text angezeigt wurden. Kein Endbenutzer wird eine solche Ausgabe nutzen können. Wir benötigen eine Komponente, die HTML interpretiert und im Benutzerinterface visualisiert. In modernem Delphi können wir TEdgeBrowser verwenden, der den Chromium-Webbrowser nutzt, der in Microsoft Windows integriert ist.
Wenn Sie Kunde von TMS Software sind, erinnern Sie sich vielleicht daran, dass TMS eine eigene Implementierung für Delphi deutlich früher vorgestellt hat und Sie diese Komponente auch in älteren Delphi-Versionen verwenden können. Darüber hinaus bietet deren Steuerung, die TTMSFNCEdgeWebBrowser genannt wird, mehr Funktionen, um mit den im Browser angezeigten Inhalten zu interagieren. Ihre Brückenfunktionalität, um Daten zwischen Ihrer Anwendung und dem Browser auszutauschen, ermöglicht es Ihnen, Webtechnologie einfach in VCL-Anwendungen zu integrieren. Im Formulardesigner ist nur eine Änderung im Vergleich zum vorherigen Beispiel vorzunehmen. Wir müssen die TMemo-Komponente durch TEdgeBrowser ersetzen.
Figure 12: Hauptformular des Beispiels im Formulardesigner.
Das Template sowie der Prozessor können unverändert bleiben. Es sind keine Änderungen erforderlich.
Die einzigen Änderungen, die wir vornehmen müssen, sind:
Das war’s schon!
Mit diesen Änderungen und Ergänzungen ist die Anwendung in der Lage, das HTML-Snippet in der Browser-Komponente anzuzeigen. Wie bereits erwähnt, sieht das gerenderte Ergebnis im Standardlayout nach heutigen Maßstäben recht unattraktiv aus.
Figure 13: Ergebnis der HTML-Vorlage in der TEdgeBrowser-Komponente
The post RAD Studio WebStencils: Die Delphi-Alternative zu Next.js & Co. appeared first on Entwickler Konferenz.
]]>The post Datenmanagement in Delphi: Das TMS Data Grid im Überblick appeared first on Entwickler Konferenz.
]]>Ein Data Grid erfüllt mehrere essenzielle Funktionen, die die Verwaltung und Darstellung von Daten erheblich erleichtern. Es visualisiert Informationen in einer klar strukturierten, tabellarischen Form, die eine einfache Lesbarkeit und Nachvollziehbarkeit gewährleistet. Durch die Möglichkeit, Daten direkt innerhalb des Grids zu bearbeiten, können Benutzer neue Einträge hinzufügen, bestehende ändern oder löschen, ohne auf externe Bearbeitungstools angewiesen zu sein. Darüber hinaus bietet das Data Grid leistungsstarke Funktionen zum Sortieren, Filtern und Gruppieren von Daten, wodurch die Navigation und Analyse selbst großer Datenmengen effizienter wird. Ein weiteres zentrales Merkmal ist die nahtlose Integration mit externen Datenquellen wie Datenbanken oder APIs. Dadurch bleiben die angezeigten Informationen stets aktuell, ohne dass manuelle Aktualisierungen erforderlich sind.
Die Vorteile dieser Komponente sind vielseitig: Sie steigert die Effizienz von Arbeitsprozessen, reduziert Fehler durch interaktive Bearbeitungsmöglichkeiten und gewährleistet eine konsistente Darstellung von Daten auf verschiedenen Plattformen. In anspruchsvollen Geschäftsanwendungen bildet das Data Grid häufig das zentrale Element der Benutzeroberfläche und bietet den Nutzern eine leistungsfähige Kontroll- und Analysefunktion, die zur Optimierung betrieblicher Abläufe beiträgt.
TMSFNCDataGrid
In diesem Artikel analysieren wir das Data Grid von TMS Software, eine umfassende und vielseitige Komponente, die speziell für die Entwicklung datenintensiver Anwendungen in Delphi konzipiert wurde. Das TMSFNCDataGrid, ein zentraler Bestandteil des TMS FNC UI Packs, zeichnet sich durch eine Kombination aus Flexibilität, plattformübergreifender Unterstützung und benutzerfreundlicher Handhabung aus (siehe Textkasten „Framework-Neutral Components“).
FNC-Komponenten: Framework-Neutrale Entwicklung mit TMS Software
FNC steht für „Framework-Neutral Components” und bezeichnet eine Technologie von TMS Software, die es ermöglicht, Benutzeroberflächenkomponenten unabhängig vom zugrunde liegenden Framework zu entwickeln. FNC-Komponenten sind so gestaltet, dass sie in verschiedenen Plattformen wie VCL (Windows), FireMonkey (Cross-Plattform), TMS WEB Core (Webanwendungen) und sogar Lazarus-Projekten nahtlos eingesetzt werden können. Der Vorteil von FNC-Komponenten liegt in ihrer Wiederverwendbarkeit und Flexibilität. Entwickler können mit einer einzigen Codebasis Anwendungen für unterschiedliche Zielplattformen erstellen, ohne den Code für jede Umgebung anpassen zu müssen. Dies spart Entwicklungszeit und reduziert den Wartungsaufwand erheblich.
Darüber hinaus bieten FNC-Komponenten eine breite Palette von Funktionalitäten, darunter fortschrittliche Steuerelemente wie Grids, Diagramme, Editoren und vieles mehr, die alle auf konsistente Weise implementiert sind.
./.
Es bietet eine Vielzahl von Funktionen, für die Datenvisualisierung und -verwaltung in Delphi-basierten Anwendungen. Die Hauptfunktionen sind:
Zunächst beschreiben wir die Installation, danach werden ausgewählte Funktionen im Detail betrachtet.
Installation und erster Test in Delphi
Laden Sie von der Webseite des Herstellers das TMS FNC UI Pack für Ihre Delphi-Version herunter und installieren Sie diese Komponenten (eine Trial-Edition ist verfügbar). Der Installationsprozess integriert die Komponenten innerhalb der Tool-Palette in die Delphi IDE.
Kommen wir zu einem ersten Test:
Das TMSFNCDataGrid unterstützt die Verbindung zu verschiedenen Datenquellen. Verwenden Sie beispielsweise Datenmodule und binden Sie das Grid an eine Datenbanktabelle. Sie können Daten ebenfalls programmatisch hinzufügen, beispielsweise durch Aufruf der Methoden AddRow(…) und SetCell(…).
Ein Beispiel für die Definition der Eigenschaften des DataGrid könnte wie folgt aussehen:
TMSFNCDataGrid1.BeginUpdate;
try
TMSFNCDataGrid1.AddRow;
TMSFNCDataGrid1.Cells[0, 0] := ‘Artikel-ID’;
TMSFNCDataGrid1.Cells[1, 0] := ‘Produktname’;
TMSFNCDataGrid1.Cells[2, 0] := ‘Preis’;
finally
TMSFNCDataGrid1.EndUpdate;
end;
Die Installation und Einrichtung des TMSFNCDataGrid sind intuitiv und schnell erledigt. Einen ersten Eindruck bekommen wir vom Data Grid, in dem wir es von der Tool-Palette auf das Formular, beispielsweise einer FireMonkey-Applikation ziehen und die Spalten der Tabelle über die Eigenschaft Columns definieren. Im Designer sehen wir sofort – wie gewohnt von Delphi – das Ergebnis. Wenn wir die Applikation (beispielsweise unter Windows) ausführen, wird das Data Grid in der App angezeigt (Abbildung 1).
Abbildung 1: Ein erstes Experiment mit dem TMSFNCDataGrid.
Uses Case: Webbasierte Kundenverwaltung
Ein Unternehmen benötigt eine webbasierte Anwendung zur Verwaltung von Kunden, um Kundendaten zentral zu speichern, schnell durchsuchen und effizient bearbeiten zu können. Die Lösung soll plattformunabhängig in modernen Browsern laufen, eine intuitive Benutzeroberfläche bieten und einfach anpassbar sein. Zudem sollen Kundeninformationen exportiert und visuell ansprechend dargestellt werden können.
Das TMSFNCDataGrid wird dabei als zentrale Komponente der webbasierten Kundenverwaltungsanwendung verwendet. Es stellt die Kundendaten in einer tabellarischen Form dar und ermöglicht es, Spalten für Kundennummer, Name, Adresse, Telefonnummer und Kundenstatus flexibel zu konfigurieren. Anpassbare Spalten bieten die Möglichkeit, zusätzliche Informationen wie Umsatz oder die letzte Kontaktaufnahme übersichtlich darzustellen. Farbcodierungen sorgen dafür, dass verschiedene Kundenstatus wie „Aktiv“, „Inaktiv” oder „VIP” auf einen Blick erkennbar sind. Die Mitarbeiter können Kundendaten direkt im Grid bearbeiten, indem sie beispielsweise Adressen aktualisieren oder den Kundenstatus ändern.
Zur komfortablen Dateneingabe stehen In-Place-Editoren wie Dropdown-Menüs für den Status oder numerische Eingabefelder für Kreditlimits zur Verfügung, wodurch eine schnelle und fehlerfreie Eingabe gewährleistet wird. Um Eingabefehler zu vermeiden, sind Datenvalidierungen wie die Überprüfung der Telefonnummer integriert. Mithilfe der integrierten Filterzeile können Benutzer gezielt nach Kunden suchen, indem sie Filter nach Namen, Status oder anderen Kriterien anwenden.
Die Sortierfunktionen ermöglichen eine geordnete Anzeige nach Umsatz, Registrierungsdatum oder Postleitzahl. Kundendaten lassen sich nach verschiedenen Kategorien wie Region, Umsatzbereich oder Status gruppieren, wodurch eine bessere Übersichtlichkeit erreicht wird. Benutzer haben die Möglichkeit, Gruppierungen individuell per Drag & Drop anzupassen und ihre bevorzugte Ansicht zu speichern. Für die Weiterverarbeitung der Daten bietet das TMSFNCDataGrid umfangreiche Exportfunktionen. Kundendaten können in Formaten wie Excel, CSV oder PDF exportiert werden, wodurch sie sich ideal für Marketingkampagnen oder Berichte eignen. Der HTML-Export ermöglicht es zudem, die Daten in einer optisch ansprechenden Ansicht per E-Mail zu versenden.
Die webbasierte Anwendung läuft in allen gängigen Browsern wie Chrome, Firefox und Edge und kann sowohl auf einem lokalen Server als auch in der Cloud bereitgestellt werden. Der Zugriff erfolgt bequem über URLs, wodurch eine flexible Nutzung gewährleistet ist.
./.
Daten filtern und sortieren
Das Data Grid bietet die einfache Integration von Filter- und Sortieroptionen. Im Bereich des Sortierens haben wir folgende Optionen:
Grid.Options.Sorting.Enabled := True;
Das Data Grid überprüft dabei die aktuelle Sortierrichtung der angeklickten Spalte. Wenn die Spalte bereits in absteigender Reihenfolge sortiert ist, wird sie in aufsteigender Reihenfolge sortiert. Andernfalls wird die Spalte in absteigender Reihenfolge sortiert. Bei der interaktiven Sortierung haben wir ein entsprechendes Symbol (Pfeil nach oben, Pfeil nach unten) im Data Grid.
Kommen wir zum Filtern der Daten:
Diese Funktionen ermöglichen es Daten effizient zu sortieren und zu filtern, was die Benutzerfreundlichkeit und Datenverwaltung in Anwendungen erheblich verbessert und vielfach für Standardaufgaben genutzt werden kann.
Abbildung 2: Data Grid mit aktiver Filter-Funktion.
Daten importieren und exportieren
Das TMSFNCDataGrid bietet leistungsstarke Import- und Exportfunktionen. Diese erlauben es, Daten nahtlos zwischen verschiedenen Formaten wie CSV, Excel, JSON, HTML und PDF zu übertragen. Mit diesen Funktionen können Daten aus externen Quellen einfach in das Data Grid geladen und bearbeitete Daten für Berichte oder die Weitergabe exportiert werden. Im Einzelnen:
TMSFNCDataGrid1.LoadFromCSVData(‘CARS.csv’);
können wir Daten aus einer Excel-Tabelle laden und im Data Grid anzeigen. Für einen Export der Daten benötigen wir ebenfalls nur eine Quellcodezeile, beispielsweise:
TMSFNCDataGridExcelIO1.XLSExport(‘gridexport.xls’);
Die Daten werden aus dem Data Grid in ein valides Excel-Format geschrieben. Die Excel-Datei können wir daraufhin unmittelbar (ebenfalls beispielsweise mittels einer FNC-Komponente) öffnen (Abbildung 3):
TTMSFNCUtils.OpenFile(‘gridexport.xls’);
Abbildung 3: Export der Daten in das Excel-Format.
Die Import- und Exportfunktionen steigern die Effizienz der Datenverwaltung in Anwendungen. Sie machen es einfach, externe Datenquellen zu nutzen und bearbeitete Daten in vielseitigen Formaten bereitzustellen.
Use Case: Mobile App für Lagerverwaltung mit FireMonkey
Ein Unternehmen benötigt eine mobile Anwendung zur Lagerverwaltung, um Lagerbestände effizient zu überwachen, Artikel zu suchen, neue Waren zu erfassen und Umlagerungen vorzunehmen. Die App soll auf mobilen Geräten mit Android und iOS laufen und auch offline verfügbar sein, wobei die Synchronisation der Daten erfolgt, sobald eine Internetverbindung besteht. Das TMSFNCDataGrid dient als zentrale Komponente der mobilen App und ermöglicht eine effiziente, interaktive Benutzeroberfläche zur Verwaltung von Lagerbeständen. Durch die Flexibilität und plattformübergreifende Unterstützung von FireMonkey wird eine reibungslose Nutzung auf verschiedenen Geräten sichergestellt. Das Data Grid zeigt die Lagerbestände in einer tabellarischen Ansicht mit Spalten für Artikelnummer, Artikelname, Bestand, Standort und Mindestbestand an. Mitarbeiter haben die Möglichkeit, Bestandsmengen direkt im Grid zu aktualisieren, beispielsweise nach einer Inventur. Für eine intuitive und fehlerfreie Dateneingabe stehen In-Place-Editoren wie numerische Eingabefelder und Dropdown-Menüs zur Verfügung. Um den Arbeitsablauf weiter zu optimieren, ist ein Barcode-Scanner integriert, mit dem Artikel per Scan erfasst und deren Daten direkt im Grid angezeigt werden können.
Zur schnellen Suche nach Artikeln ermöglicht die Filterzeile die gezielte Eingabe von Suchkriterien wie Artikelnummer oder Standort. Die integrierten Sortierfunktionen erleichtern die Navigation durch umfangreiche Bestandslisten, indem sie beispielsweise eine Sortierung nach Lagerbestand oder Artikelname ermöglichen. Lagerbestände lassen sich nach Standort oder Produktkategorie gruppieren, was zu einer übersichtlicheren Darstellung führt. Mitarbeiter können Gruppierungsebenen flexibel per Drag & Drop anpassen, um schneller auf benötigte Daten zugreifen zu können. Die Anwendung funktioniert auch offline, indem alle Daten lokal auf dem Gerät gespeichert werden. Änderungen, die ohne bestehende Internetverbindung vorgenommen werden, werden in einer Warteschlange gespeichert und bei der nächsten verfügbaren Verbindung mit der zentralen Datenbank synchronisiert. Darüber hinaus stehen Exportoptionen zur Verfügung, die es ermöglichen, Lagerbestände in Formaten wie CSV oder Excel zu exportieren und direkt aus der App per E-Mail zu versenden. Diese mobile Lösung bietet eine effiziente Möglichkeit, Lagerbestände jederzeit und überall im Blick zu behalten. Die benutzerfreundliche Oberfläche in Kombination mit den leistungsstarken Funktionen des TMSFNCDataGrid sorgt für eine gute Unterstützung bei täglichen Lagerprozessen und steigert die Effizienz der Bestandsverwaltung erheblich.
./.
Master-Detail-Bindungen
Master-Detail-Beziehungen sind eine grundlegende Funktion in datenintensiven Anwendungen, die darauf abzielen, komplexe Datenstrukturen auf intuitive und synchronisierte Weise darzustellen. In diesem Ansatz dient ein „Master“-Data Grid als übergeordnete Ansicht, die eine Übersicht über Hauptdatensätze (beispielsweise Bestellungen) bietet. Ein „Detail“-Data Grid zeigt hingegen die zugehörigen Detailinformationen (beispielsweise Bestellpositionen), die mit dem aktuell ausgewählten Eintrag im Master- Data Grid verknüpft sind.
Master-Detail-Ansichten erleichtern die Navigation und Analyse umfangreicher Datensätze erheblich. Sie bieten dem Benutzer eine übersichtliche Darstellung der Hauptdatensätze und ermöglichen bei Bedarf den direkten Zugriff auf zugehörige Detailinformationen. Änderungen im Master-Data-Grid werden automatisch im Detail-Data-Grid übernommen, wodurch eine nahtlose Navigation und eine konsistente Datenanzeige sichergestellt werden. Separate Datenabfragen sind nicht erforderlich, da die Verknüpfung zwischen Master- und Detaildaten automatisch erfolgt. Diese Funktion ist besonders vorteilhaft für Geschäftsanwendungen, die auf relationalen Datenbanken basieren, wie beispielsweise Bestell-, Kunden- oder Inventarverwaltungssysteme.
Die Implementierung von Master-Detail-Beziehungen ist dank der flexiblen Architektur der Komponente einfach umzusetzen. Es kann durch die folgende Schrittfolge beschrieben werden:
Beachten Sie: Die Komponenten sind aufeinander abgestimmt, d.h. wir können die Datenbindungen und Verknüpfungen mit Hilfe der Eigenschaften im Objekt Inspektor von Delphi vornehmen, was den Aufwand zum Schreiben von Quellcode maßgeblich reduziert. Beispielsweise können wir die Detail-Tabelle auf diese Weise über einen Adapter an die Datenquelle der Mastertabelle mittels Fremdschlüssel binden (Abbildung 4).
Abbildung 4: Verbindung von Master- und Detailtabelle über die Primär- und Fremdschlüssel.
Bei der Ausführung einer Applikation mit einer Verknüpfung von Master- und Detailtabelle werden die Detailinformationen korrekt innerhalb eines übergeordneten Datensatzes eingeblendet (Abbildung 5).
Abbildung 5: Ausführung einer Applikation mit Master- und Detailtabelle.
Editierfunktionen
Das Data Grid bietet flexible und erweiterbare Möglichkeiten zur Bearbeitung von Daten direkt innerhalb des Rasters. Diese sogenannten In-Place-Editoren ermöglichen eine intuitive Dateneingabe und Anpassung, ohne dass zusätzliche Fenster oder Dialoge erforderlich sind. Nachfolgend sind die Hauptmerkmale und Möglichkeiten der Editierfunktionen dargestellt:
Globale und spaltenweise Bearbeitungskontrolle:
Vorgefertigte In-Place-Editoren:
Das Data Grid enthält eine Vielzahl von integrierten Editoren, die direkt genutzt werden können:
Das Data Grid erlaubt die Verwendung benutzerdefinierter Editoren, die auf spezifische Anforderungen zugeschnitten sind:
Anpassung und Erweiterung:
Beispiele für In-Place-Editoren:
Die Editierfunktionen bieten eine hohe Flexibilität und Anpassbarkeit, zum Beispiel durch einfache Textbearbeitung, komplexe Datumsauswahl oder interaktive Schieberegler.
Weitere Funktionen
Das TMSFNCDataGrid bietet eine Vielzahl weiterer Funktionen, die Entwicklern helfen, komplexe Daten effektiv zu verwalten und darzustellen. Eine zentrale Funktion ist die Datenbankbindung, die eine nahtlose Integration verschiedener Datenquellen ermöglicht. Mithilfe des TTMSFNCDataGridDatabaseAdapter lassen sich Datenquellen wie TDataSet einfach verknüpfen, sodass Änderungen automatisch zwischen Grid und Datenbank synchronisiert werden. Die Unterstützung von Master-Detail-Beziehungen erlaubt es, hierarchische Datenstrukturen übersichtlich abzubilden, indem Haupt- und Detaildatensätze miteinander verknüpft werden. Durch die flexible Architektur eignet sich das Grid sowohl für relationale Datenbanken als auch für andere Datenquellen und ermöglicht eine einfache Konfiguration mit minimalem Programmieraufwand.
Die Gruppierungsfunktion erleichtert die Organisation großer Datensätze, indem sie Daten nach einer oder mehreren Spalten strukturiert. Benutzer können Spalten per Drag & Drop in eine Gruppierungsleiste ziehen, um eine individuelle Darstellung zu erstellen. Entwickler haben zudem die Möglichkeit, Gruppierungen programmgesteuert zu konfigurieren und auf spezifische Anforderungen zuzuschneiden. Änderungen an den Daten werden automatisch in der gruppierten Ansicht aktualisiert, was die Benutzerfreundlichkeit erheblich steigert.
Ein weiteres leistungsstarkes Feature sind die Berechnungsfunktionen, die es ermöglichen, Summen, Durchschnitte oder andere statistische Werte automatisch für Spalten oder Zeilen berechnen zu lassen. Benutzerdefinierte Formeln können implementiert werden, um spezielle Anforderungen zu erfüllen, während Änderungen an den Daten sofort aktualisierte Berechnungsergebnisse liefern. Die Darstellung der Berechnungen kann flexibel in separaten Spalten, Fußzeilen oder Zellen erfolgen.
Das Erscheinungsbild des Grids lässt sich umfassend anpassen, um den individuellen Anforderungen verschiedener Anwendungen gerecht zu werden. Jede Zelle, Zeile oder Spalte kann mit individuellen Layouts, Farben und Schriftarten formatiert werden. Über ereignisgesteuerte Anpassungen lässt sich das Design dynamisch anpassen, sodass eine responsive Darstellung auf verschiedenen Bildschirmgrößen und Plattformen gewährleistet ist.
Dank der plattforübergreifenden Unterstützung kann das TMSFNCDataGrid in einer Vielzahl von Entwicklungsumgebungen eingesetzt werden. Ob Windows-Anwendungen mit VCL, plattformübergreifende Anwendungen mit FireMonkey oder Webanwendungen mit TMS WEB Core – die einheitliche Codebasis ermöglicht eine schnelle und effiziente Entwicklung auf unterschiedlichen Plattformen. Die nahtlose Integration in Entwicklungsumgebungen wie Delphi und C++ Builder erleichtert die Einbindung des Grids in bestehende Projekte und unterstützt eine reibungslose Arbeitsweise.
Beispiele
Eine umfassende Beispielsammlung wird durch den Hersteller bereitgestellt. Mit der Installation der beiden Bibliotheken TMS FNC UI Pack und TMS FNC Core Pack landen auch viele Beispiele zu den einzelnen FNC-Komponenten auf der Festplatte. Im Unterordner DataGrid findet man Beispiele für viele der Features der Datentabelle, u.a. auch das Zusammenspiel mit anderen Komponenten aus der FNC-Bibliothek.
./.
Fazit und Ausblick
Das hier vorgestellte Data Grid erweist sich als eine leistungsstarke und flexible Komponente für Delphi-Entwickler, die mit datenintensiven Anwendungen arbeiten. Durch die Kombination von plattformübergreifender Unterstützung, einfacher Datenbankintegration und einer Vielzahl an Funktionen wie In-Place-Editoren, Master-Detail-Beziehungen sowie Import- und Exportmöglichkeiten wird es zu einem Werkzeug in der modernen Softwareentwicklung.
Die Flexibilität, Daten auf intuitive Weise zu visualisieren, interaktiv zu bearbeiten und dynamisch zu organisieren, bietet eine zentrale Lösung, um komplexe Geschäftsanforderungen effizient umzusetzen. Die Möglichkeit, eigene Editoren zu integrieren oder bestehende Funktionen individuell anzupassen, erhöht den Mehrwert des Data Grids erheblich.
Links & Literatur
[1] https://download.tmssoftware.com/doc/tmsfncuipack/components/ttmsfncgrid/
[2] https://www.tmssoftware.com/site/blog.asp?post=1256
The post Datenmanagement in Delphi: Das TMS Data Grid im Überblick appeared first on Entwickler Konferenz.
]]>The post Delphi & C++Builder: Das bietet RAD Studio 12.2 für Entwickler:innen appeared first on Entwickler Konferenz.
]]>KI-Unterstützung bei der Codierung
Mit Version 12.2 führt RAD Studio neue KI-gestützte Funktionen für CodeInsight ein, die den Codevervollständigungs- und Optimierungsprozess unterstützen. Diese Funktionen basieren auf einer offenen Architektur, die es erlaubt, aus verschiedenen KI-Plugins zu wählen oder eigene Erweiterungen zu integrieren. RAD Studio bietet standardmäßig Unterstützung für die Online-KI-Lösungen von OpenAI, Gemini und Claude und den Offline KI-Service von Ollama für einen maximalen Datenschutz. Die Integration von KI in CodeInsight hat das Ziel, die Produktivität zu steigern, indem sie kontextbezogene Codevorschläge macht, Fehler im Code schneller erkennt und die Navigation im Code erleichtert. Diese neue Funktion ist optional und standardmäßig deaktiviert, um sicherzustellen, dass die Nutzung vollständig kontrollierbar ist und nach den individuellen Bedürfnissen des Entwicklungsteams gestaltet werden kann (Abbildung 1).
Abbildung 1: Auswahl und Konfiguration einer KI in die RAD Studio.
Für die Nutzung dieser KI-Dienste müssen Sie den Bedingungen des jeweiligen Anbieters zustimmen, einen API-Schlüssel erhalten, den Sie in die RAD Studio-Konfiguration eingeben können und dem KI-Unternehmen die fälligen Gebühren zahlen. Die Ausnahme ist der KI-Dienst Ollama, welcher ohne Servicegebühr offline genutzt und lokal oder auf einem Server Ihrer Wahl installiert werden kann. Es stehen nach der Auswahl und Konfiguration (API, URL, Key) folgende KI-basierte Funktionen in der IDE zur Unterstützung beim Programmieren zur Verfügung:
KI-Dienste im Überblick
./.
Compiler Update für Windows
Mit RAD Studio 12.2 wurde eine 64-Bit-Binärversion des Delphi-Windows-Compilers eingeführt, die speziell für sehr große Anwendungen konzipiert ist. Diese Version ermöglicht es, sehr große Anwendungen als eine ausführbare Datei zu erstellen, da die neuen Compiler über 64-Bit-Speicher verfügen. Diese neuen Compiler sind derzeit über die Befehlszeile und über die IDE bei Verwendung der externen Kompilierung verfügbar. Sie sind nur in den Enterprise- und Architects-Editionen enthalten. Im Übrigen ist der aktuelle C++ Clang-Compiler seit seiner Veröffentlichung in RAD Studio 12.0 ebenfalls ein 64-Bit-Binary.
IDE-Fokusmodus und Scrollbar-Anmerkungen
RAD Studio enthält einen neuen Fokus-Modus für ein ungestörtes Arbeiten am Quellcode. Dieser wird mit der Tastenkombination Ctrl+Alt+Z aktiviert. Der Fokus-Modus bietet folgende Funktionen:
Ebenso kann bestimmt werden, welche Optionen (Lesezeichen, Code Foldings, Debug-Infos, …) angezeigt werden sollen. In Kombination mit einer dunklen Einfärbung des Bildschirms kann auf diese Weise ein konzentrierter Arbeitsplatz für „schwierige Passagen“ am Quelltext konfiguriert werden (Abbildung 2).
Abbildung 2: Fokusmodus in RAD Studio.
Eine weitere sehr nützliche Funktion sind die neuen Scrollbar-Anmerkungen: Die Scrollbar des Editors zeigt auf einen Blick die Codeabschnitte an, die geändert wurden, Lesezeichen haben, Fehler oder Warnungen enthalten und vieles mehr. Auch das sorgt für mehr Übersicht beim Schreiben des Quellcodes.
C++Builder Visual Assist Integration
Visual Assist ist ein Tool, dass die Aufgabe hat die Übersichtlichkeit und Wartbarkeit von C++-Code zu verbessern. Es unterstützt die Code-Navigation, bietet Funktionen zur automatischen Code-Vervollständigung und beinhaltet Werkzeuge zur Code-Analyse und Refaktorisierung. Visual Assist ist direkt in die IDE C++Builder integriert. Mit Version 12.2 von RAD Studio (C++ Builder) wurde die Integration um neue Funktionen erweitert, darunter drei neue Refactorings: Introduce Variable, Create From Usage und Extract Method. Hinweis: Visual Assist ist nicht für Delphi, sondern nur für die Programmiersprache C++ verfügbar. Als externes Tool kann es auch als Extension in Visual Studio für die Programmiersprachen C++ und C# eingesetzt werden.
Entwicklung von Apps für die mobilen Systeme
Bekanntermaßen kann man mit Delphi und der Grafikbibliothek FireMonkey (FMX) Apps für die mobilen Geräte, d.h. die Betriebssysteme iOS und Android erstellen. Ein besonderes Merkmal ist dabei die Nutzung der visuellen Controls für das effizientere Gestalten der Benutzeroberfläche, inklusive des Einsatzes des grafischen Designers. Die aktuelle Version von RAD Studio 12.2 bietet Verbesserungen für die mobile Entwicklung mit Delphi, sowohl für iOS als auch für Android. Um Apple-Plattformen besser zu unterstützen, wurde der Linker auf die neueste Version aktualisiert, so dass es jetzt möglich ist, in Xcode geschriebene statische iOS-Bibliotheken zu verknüpfen, wie zum Beispiel das Firebase iOS SDK. Um mehr Kontrolle über die Paketierung und Bereitstellung zu geben, wurden in Android-Projektoptionen hinzugefügt, dass *.Dex-Dateien komprimiert und native Bibliotheksdateien in der Toolchain komprimiert werden können. Darüber hinaus kann für Android die TargetSdkVersion der Android-Manifest-Datei jetzt im Dialogfeld Projektoptionen konfiguriert werden. Ebenso besteht die Möglichkeit, Android-Bibliotheken (*.aar-Dateien) zu importieren, was zum Beispiel mit dem Facebook SDK für Android und Firebase Analytics funktioniert.
Dateitypen in Android
DEX-Dateien (Dalvik Executable Files) sind Dateien im Bytecode-Format, das speziell für die Android-Plattform entwickelt wurde. Sie enthalten kompilierte Java-Code-Bestandteile, die von der Dalvik Virtual Machine (DVM) oder der neueren Android Runtime (ART) auf Android-Geräten ausgeführt werden. Bei der Entwicklung einer Android-App wird der Java- oder Kotlin-Code zuerst in Bytecode kompiliert und anschließend in DEX-Dateien umgewandelt, die die Anwendung für die Android-Plattform lauffähig machen. Eine typische Android-App enthält mindestens eine DEX-Datei, die alle Klassen und Methoden enthält, die für den Betrieb der App erforderlich sind. Diese Dateien werden im APK (Android Package) der App gebündelt und auf das Android-Gerät übertragen, wo sie zur Laufzeit interpretiert oder vorab in Maschinencode übersetzt werden.
AAR-Dateien (Android Archive Files) sind Archive, die Bibliotheken und Ressourcen für die Entwicklung von Android-Apps enthalten. Sie werden häufig verwendet, um wiederverwendbare Android-Bibliotheken zu bündeln, die dann in anderen Projekten integriert werden können. Eine AAR-Datei kann neben kompiliertem Code (DEX-Dateien) auch Ressourcen wie XML-Dateien, Bilder, Layouts, Assets, und Manifest-Dateien enthalten. Im Gegensatz zu JAR-Dateien, die nur Java-Klassen beinhalten, können AAR-Dateien zusätzlich Ressourcen und native Bibliotheken enthalten, was sie vielseitiger für Android-spezifische Anforderungen macht. Entwickler fügen eine AAR-Datei zu ihrem Projekt hinzu, um die enthaltenen Funktionen und Ressourcen in ihrer Anwendung zu nutzen, ohne die Bibliothek selbst entwickeln oder kompilieren zu müssen.
./.
WebStencils Template Library
RAD Studio bietet verschiedene Werkzeuge und Frameworks für die Webentwicklung, die speziell darauf ausgelegt sind, serverseitige Anwendungen zu erstellen und APIs bereitzustellen, u.a. das WebBroker-Framework. WebBroker ist ein serverseitiges Framework in RAD Studio, das es ermöglicht, HTTP-Anfragen zu verarbeiten und HTML-Inhalte, JSON oder andere Formate zurückzugeben. Es eignet sich gut für die Entwicklung von Webanwendungen und APIs, die auf einer serverseitigen Logik basieren. RAD Studio Version 12.2 führt WebStencils ein, eine serverseitige skriptbasierte Integration und Verarbeitung von HTML-Dateien in WebBroker- und RAD Server-Technologien. Mit dieser flexiblen Funktion können Sie Websites entwickeln, die auf beliebigen JavaScript-Bibliotheken basieren und mit den von einer RAD Studio-Serveranwendung extrahierten und verarbeiteten Daten betrieben werden. Das Hauptziel von WebStencils ist die Unterstützung bei der Navigation von Websites durch die Übernahme von Webtechnologien (WebBroker, DataSnap, RAD Server) und die Bereitstellung von serverseitigem Scripting. Beispielsweise können Sie mit WebStencils HTML-Seiten mit Standardwerkzeugen generieren und beliebige CSS- und JavaScript-Bibliotheken übernehmen, während Sie gleichzeitig die Möglichkeit haben, Daten aus den generierten Seiten hinzuzufügen, die aus der Delphi- oder C++Builder-Anwendung stammen, wie zum Beispiel das Ergebnis einer Datenbankabfrage. Darüber hinaus können WebStencils eine gute Grundlage für HTMX als Webentwicklungslösung sein. HTMX-Seiten profitieren von der serverseitigen Codegenerierung und der Einbindung in REST-Server für die Aktualisierung von Inhalten.
HTMX – Was ist das?
HTMX ist eine JavaScript-Bibliothek, die es ermöglicht, HTML direkt durch einfache Attribute interaktiv und dynamisch zu machen, ohne dass umfangreiche JavaScript-Logik erforderlich ist. Mit HTMX lassen sich asynchrone Funktionen (AJAX) nutzen, um Teile einer Website ohne komplettes Neuladen zu aktualisieren. Es basiert auf der Idee von „Hypertext-Driven Applications“ und erweitert HTML um eine Reihe von Attributen, mit denen Benutzeroberflächen auf den Server reagieren können. Die Hauptfunktionen von HTMX sind:
HTMX ist ideal für Anwendungszwecke, wo serverseitige Logik in die Webanwendungen integriert werden soll, ohne dabei komplexe Frontend-Frameworks wie React oder Angular zu verwenden. Es eignet sich gut für serverseitig gerenderte Webseiten und ermöglicht ein einfacheres Entwicklungsmodell, das auf HTML und serverseitigen Daten basiert.
./.
Qualitätsverbesserungen
RAD Studio Version 12.2 beinhaltet auch einige Qualitätsverbesserungen, die die Stabilität und Effizienz der Entwicklungsumgebung erhöhen. Dazu zählen:
SKIA in Delphi
Auch wenn dieser Artikel sich auf die Neuerungen von RAD Studio 12.2 konzentriert, verdient ein Feature aus der Vorversion besondere Erwähnung: die Integration der Grafikbibliothek Skia ab Version 11 in Delphi. Skia ist eine leistungsstarke Grafikbibliothek, die ursprünglich von Google entwickelt wurde und in zahlreichen Anwendungen wie Chrome und Android verwendet wird. Durch die Integration in Delphi und C++Builder ermöglicht Skia hochqualitatives Grafik-Rendering auf allen unterstützten Plattformen und bringt leistungsstarke visuelle Effekte sowie bessere Performance für Multimedia- und grafikreiche-Anwendungen. Die Bibliothek ist sowohl in VCL (für Windows) als auch in FMX (plattformübergreifend) nutzbar und ermöglicht die effiziente Erstellung visueller Anwendungen mit modernen Grafikstandards. Skia unterstützt die Darstellung von Vektor- und Rastergrafiken sowie komplexen Animationen und ist für ihre Effizienz und Flexibilität bekannt. Die Skia-Bibliothek bietet Funktionen wie Antialiasing zur Glättung von Kanten, Farbverläufe, Shading-Effekte und Text-Rendering, das auch für RTL-Sprachen (Right-to-Left) wie Arabisch und Hebräisch geeignet ist. Außerdem unterstützt Skia verschiedene Grafikformate wie BMP, PNG, JPEG und animierte Formate wie GIF, WebP und Lottie-Animationen. Ein entscheidender Vorteil von Skia ist das hardwarebeschleunigte Rendering über die GPU, das besonders bei grafikintensiven Anwendungen zu flüssigen Animationen und einer geringen CPU-Belastung führt.
Die Integration von Skia in RAD Studio eröffnet in Delphi neue Möglichkeiten zur Erstellung grafisch anspruchsvoller Anwendungen. Skia4Delphi, eine speziell für Delphi angepasste Variante von Skia, ermöglicht hochqualitatives Rendering für VCL- und FMX-Anwendungen. Dies umfasst das Zeichnen von Vektorgrafiken, die Manipulation von Text und das Rendern von SVG-Dateien. Der Vorteil dieser Integration ist, dass Entwickler moderne Grafiktechniken anwenden können, ohne separate Bibliotheken nutzen oder zusätzliche Hardwareanforderungen berücksichtigen zu müssen. Durch die Einbindung in RAD Studio lassen sich Skia-Features direkt über die IDE steuern und konfigurieren, was die Anwendung für anspruchsvolle Designs und interaktive Benutzeroberflächen vereinfacht.
Skia bringt spezielle Steuerelemente (Controls) für die VCL- und FMX-Frameworks in Delphi mit, die die Implementierung von Grafikfunktionen vereinfachen (Abbildung 3)
Abbildung 3: SKIA-Controls in RAD Studio.
Die Integration von Skia in FireMonkey (FMX) bringt erhebliche Verbesserungen für das plattformübergreifende Rendering in RAD Studio. Durch die Aktivierung von Skia als Standard-Canvas in FMX-Anwendungen können Entwickler:innen die Qualität und Leistung der grafischen Darstellung erhöhen. Das gilt insbesondere für die mobilen Plattformen. Die Skia-Engine ersetzt dabei das Standard-Rendering von FMX und bietet Vorteile wie (Abbildung 4):
Abbildung 4: Kernfeatures der Skia4Delphi-Bibliothek.
Diese Optimierungen wirken sich besonders positiv auf Multimedia-Apps und grafikintensive Anwendungen aus, die auf unterschiedlichen Plattformen (Windows, macOS, iOS, Android) eingesetzt werden. Dabei ist die Aktivierung denkbar einfach. Mit einem Klick über den Projektmappen-Explorer lässt sich die Nutzung der Grafikbibliothek sehr einfach aktivieren (Abbildung 5).
Abbildung 5: Skia über die Projekteigenschaften in einem RAD Studio-Projekt aktivieren.
In RAD Studio 12 ist zusätzlich ein Multi Device Icon Generator integriert, der auf Skia basiert und die plattformübergreifende Erstellung von Icons und Grafiken für verschiedene Geräte erleichtert. Mit diesem Tool können Entwickler Icons und Grafiken in den benötigten Auflösungen und Formaten für verschiedene Plattformen generieren. Der Generator verwendet eine Bildquelle und bietet Optionen für manuelle Anpassungen wie Zoom und Hintergrundfarben. Nach der Konfiguration können alle notwendigen Bildelemente für die Zielplattformen automatisch generiert und bereitgestellt werden. Dieses Tool reduziert die Zeit und den Aufwand für die finale Bildbereitstellung, insbesondere bei plattformübergreifenden Anwendungen, erheblich und trägt zur Vereinheitlichung des visuellen Designs bei.
RAD Studio-Editions
RAD Studio ist eine integrierte Entwicklungsumgebung (IDE) von Embarcadero Technologies, die es ermöglicht, plattformübergreifende Anwendungen für Windows, macOS, iOS, Android und Linux zu erstellen. Die aktuelle Version, RAD Studio 12.2, bietet verschiedene Editionen, die auf unterschiedliche Bedürfnisse und Anforderungen zugeschnitten sind:
./.
Fazit und Ausblick
Die neue Version von RAD Studio 12.2 bringt einige interessante Verbesserungen, beispielsweise eine konfigurierbare KI-Unterstützung für das Schreiben von Quellcode, Verbesserungen beim Compiler, neue Funktionen für das integrierte Tool Visual Assist und notwendige Qualitätsanpassungen. Erwähnenswert ist insbesondere auch die Integration der Grafikbibliothek Skia (bereits seit Version 11 von RAD Studio), welche eine optimierte grafische Darstellung und Performance auf allen unterstützten Plattformen ermöglicht. Dieses Feature ist insbesondere für Multimedia- und UI-intensive Anwendungen von Vorteil. Weitere Funktionen wie der Multi-Device-Icon-Generator und die WebStencils-Template-Library erleichtern die plattformübergreifende Entwicklung bzw. die Entwicklung von serverbasierten Applikationen.
Dr. Veikko Krypczyk ist begeisterter Entwickler und Fachautor. Er bietet Seminare und Workshops zu unterschiedlichen Themen der Softwareentwicklung. Weitere Informationen zu diesen und anderen Themen der IT und Angebote zu Seminaren und Workshops finden Sie unter https://larinet.com und https://www.tech-punkt.com. Hier finden Sie Seminare zu aktuellen Themen, welche den Inhalt kompakt und auf den Punkt gebracht vermitteln.
Links & Literatur
[1] https://www.embarcadero.com/products/rad-studio
[2] https://www.embarcadero.com/de/products/rad-studio/whats-new-in-12-athens
[3] https://docwiki.embarcadero.com/RADStudio/Athens/en/Skia4Delphi
The post Delphi & C++Builder: Das bietet RAD Studio 12.2 für Entwickler:innen appeared first on Entwickler Konferenz.
]]>The post Delphi – der Erfolgsgeschichte auf der Spur appeared first on Entwickler Konferenz.
]]>1995 war ein gutes Jahr für Programmiersprachen: In dem Jahr wurden erste Versionen sowohl für Java, JavaScript, PHP als auch für Delphi vorgestellt. Wenn wir uns einmal auf Delphi konzentrieren: Was war deiner Meinung nach das Erfolgsrezept der Sprache, das dafür sorgte, dass auch heute noch eine aktive Entwickler-Community existiert?
Matthias Eissing: Es war nicht nur die Sprache, die Delphi zum Erfolg verhalf. Es war ein Gesamtkonzept, welches auf drei wesentlichen Säulen basierte und immer noch basiert: (i) Echter Compiler, der eine ausführbare Datei ohne Abhängigkeiten von DLLs oder einer Laufzeitumgebung erzeugt, (ii) umfangreiche und erweiterbare Klassenbibliothek mit visuellen Komponenten und (iii) visuelle, Formular-basierte Entwicklung mit Datenbankanbindung. Jedes für sich gab es auch jeweils in anderen Compilern, IDEs und Entwicklungsumgebungen: Compiler, wie C++; Komponenten, visuelle Entwicklung und ereignisorientierte Programmierung wie zum Beispiel VisualBasic; und Datenbank-zentrische Ausrichtung, wie Oracle Forms oder Sybase PowerBuilder.
Mit Delphi war das einzigartig – und ist es auch heute noch in vielen Bereichen. Delphi besitzt sicherlich immer noch die beste IDE, um visuell Windows Desktop-Anwendungen zu erstellen. Das hat selbst Microsoft mal in einer CeBIT realisiert, wo die AUTOSTART.EXE auf der tausendfach verteilten CeBIT-Demo-CD-ROM mit einem mir sehr bekannten Ich daherkam: Ja, es war ein Delphi-Programm!
Max Kleiner: Basierend auf der Sprache Pascal waren wir neugierig, endlich Turbo Pascal verlassen zu können und in die objektorientierte Komponentenwelt einzusteigen. Borland hatte ein cooles Image, die Architektur der VCL war seiner Zeit meilenweit voraus.
Christoph Schneider: Mitten während meiner Lehre als Elektroniker im Jahre 1984 erwarb ich meinen ersten Personal Computer, ein CASIO FP-1100. Dieser lief noch unter dem Betriebssystem CP/M und hatte damals noch keine Harddisk, dafür zwei 5.25” Floppy Disks. Die erste belegte die Betriebssystem-Diskette, in der zweiten steckte die neu erworbene Turbo-Pascal-Entwicklungsumgebung. Jahre später, mitten in meinem zweiten Informatikstudium, hatte ich mittlerweile auf IBM PC umgestellt, und dort setzte sich Windows als Bedieneroberfläche definitiv durch. Ich lernte mit Turbo Pascal für Windows die Programmierung der damals noch sehr komplexen Anwendungsentwicklung unter Windows kennen. Da war das VCL-Framework mit Delphi wirklich revolutionär einfach, und mein Vorteil war, dass ich die objektorientierte Erweiterung von Pascal bereits gut kannte. An Delphi schätzte ich sehr, dass ich mich nicht mehr mit allen Details von Windows herumschlagen musste, um ein Fenster auf dem Bildschirm zu zeichnen und auf Maus- und Tastatur-Eingaben zu reagieren. Mit diesem Werkzeug entwickelte ich zum ersten Mal wieder schneller Applikationen, als dies noch unter MS-DOS möglich war.
Bernd Ua: Die Kombination aus schneller und grafischer Entwicklungsumgebung mit einer mächtigen aber sicheren Programmiersprache kam genau zu richtigen Zeit. Anders Hejlsberg hatte alles, was er für eine effektive Komponenten-basierte IDE brauchte, in die Sprache Pascal und dessen Objektmodell einfließen lassen und die Sprache entsprechend angepasst. Aber Delphi ermöglichte nicht nur das schnelle Erstellen von UI-Anwendungen für Windows, sondern auch ebenso einfach den Zugriff auf verschiedenste Datenbanken, und hat damit die Lücke, die sich zwischen Datenbanktools wie dBase, Paradox oder Access mit ihren Runtimes und klassischen Compilern wie Visual C++ aufgetan hat, perfekt gefüllt.
Max Kleiner: Im 1995 galt es die Immobiliensoftware CalWin von VB auf 32-bit Delphi zu migrieren. Zudem baute ich eine Zugsteuerung von Turbo Pascal auf Delphi um, die Anforderung war damals, absolut kollisionsfrei zu funktionieren.
Bernd Ua: Ich wollte neben dem Chemie-Studium noch programmieren lernen, und aus dem ersten Kurs „Programmierung für Ingenieure“ konnte ich für mich vor allem eins herausziehen: Fortran war nicht die Sprache meiner Wahl. Dann habe ich mir jenseits der angebotenen Kurse C++ und Pascal angeschaut und fand letzteres eingängiger. Also habe ich mich mit Pascal beschäftigt und relativ bald eine Messdaten-Auswertung und -Erfassung zunächst mit Turbo Pascal für DOS und dann mit Borland Pascal für Windows geschrieben. Da war Delphi für mich quasi unausweichlich, als es herauskam, und praktischerweise konnte ich dann damals auch neben dem Studium direkt für Borland arbeiten.
Und was reizt dich heute noch an der Programmierung mit der Sprache?
Matthias Eissing: Es ist ja nicht nur die Sprache selbst. Es ist die integrierte Umgebung, die ja heute für Windows, Android, iOS/iPadOS und auch Linux kompilieren kann. Reizvoll ist sicherlich die leichte Lesbarkeit der Sprache selbst. Auch Projekte, die ich vor X Jahren mal erstellt habe, kann ich wieder lesen. Ja; das klingt banal. Es ist aber leider die Ausnahme von Programmiersprachen und auch insbesondere Frameworks, die als Hype mal wieder (kurz) durchs Dorf getrieben werden. Diese Lesbarkeit in Verbindung mit der Technologie-Konstanz – das ist es, was mich an Delphi selbst und auch der Sprache reizt.
Max Kleiner: Ich baue ständig mein Tool maXbox aus, und da sind auch noch etliche Anwendungen, wie SecureCenter oder Pas2JS, die weiterleben wollen. Auch die Möglichkeiten, in einer überschaubaren Community daheim zu sein, gefällt. Mit XE2 im Jahr 2011 kam ja die 64-Bit-Win Unterstützung und bald darauf auch MacOS, iOS und Android. Anfangs hätte ich nie gedacht, dass ich meine Fähigkeiten nutzen werde (tja, die Kunden fordern auch) und als Support anderer Plattformen einsetzen kann.
Bernd Ua: Normalerweise reizt einen ja immer das Neue oder das Unbekannte, und das ist bei mir meistens genauso. Insofern wäre die Frage besser, was ich an Delphi schätze und nicht, was mich an Delphi reizt. Nach fast drei Jahrzehnten Delphi und noch länger Pascal gibt es da auch nichts für mich, was noch zu entdecken wäre. Der Hersteller und die Community sind da bei Delphi recht konservativ. Egal, was in der Sprache ergänzt wird, ist ein wichtiger Punkt immer die Abwärtskompatibilität zur alten Codebasis. Dementsprechend sind Must Haves wie generische Typen oder anonyme Methoden mit der Zeit dazu gekommen und haben die Sprache erweitert und aktualisiert, aber jeweils ohne die Brücken zu altem Code zu brechen. Wenn man in anderen Systemen Frameworks kommen und gehen sieht und sich vor Augen führt, wieviel Produktiv-Code dabei dann mit in die Tonne wandert und neu geschrieben werden muss, versöhnt das mit dem Umstand, dass einem das Feature X in der Entwicklungsumgebung oder das Feature Y in der Sprache fehlt.
Christoph Schneider: Nachdem mit Delphi 7 im August 2002 die letzte gute Version erschien, kam aus meiner Sicht erst wieder im Jahr 2009 eine spannende neue Version von Delphi heraus, die uns neue Sprachfeatures wie Generics und anonyme Funktionen sowie die überfällige Unicode-Unterstützung brachte. Als dann 2011 das Zeitalter für plattformunabhängige und native Entwicklung basierend auf dem neuen Framework Firemonkey gestartet wurde, war für mich klar, dass ich auch künftig auf diese Sprache setzen werde. Ab 2017 erhielt ich die Möglichkeit, ein größeres Projekt für einen Kunden zu erstellen, welches unter den beiden Betriebssysteme Windows und MacOS laufen sollte. Auch für die mobilen Plattformen iOS und Android erstellte ich mehrere Apps mit Firemonkey, welche mit der Desktop-Anwendung über eine Cloud-Datenbank kommunizierte.
Welche Entwicklung neueren Datums in der Delphi-Szene findest du besonders spannend?
Matthias Eissing: Ganz ehrlich: Dass sich grundlegend nichts geändert hat. Klar: Moderne Programmierkonzepte wie Generics, anonyme Methoden, Handling von Threads durchs Tasks, Cross-Plattform-Entwicklung etc sind sehr willkommene und auch wünschenswerte Erweiterungen. Aber das grundlegende Prinzip ist weiterhin gleich. Technologie-Konstanz ist auch etwas, was Kunden wirklich schätzen: Dass man ein Projekt von “vor X Jahren” portieren kann, mit kleinem/geringen Aufwand. Das ist für Projekte, die über den Lebenszyklus des nächsten Framework-Hypes hinausgehen, sehr wichtig geworden.
Max Kleiner: Delphi 11 wie auch das kommende 12 hat meiner Meinung nach die bisher beste Schnittstelle eingeführt, da sie (fast) vollständig anpassbar ist und ein API zum Bauen eigener Plug-ins bietet, um zusätzliche Funktionalität bereitzustellen. Das Thema API fasziniert mich am meisten, andere Funktionen anzuzapfen, um dann meistens in der (werbefreien) Konsole zu coden.
Bernd Ua: Ich finde es spannend zu sehen, wie sich zur Zeit gerade in den Schwellenländern wie Brasilien ein neuer Delphi-Hype entwickelt. Während es in Westeuropa und in Amerika ruhiger um Delphi geworden ist und wenig neue Entwickler zur Community dazustoßen, ist das in Brasilien zum Beispiel komplett anders. Bei Delphi-Konferenzen in Brasilien kommen problemlos mehr als tausend Leute zusammen, und auch neue Open-Source-Projekt werden dort gestartet.
Matthias, eine deiner Sessions auf der EKON heißt “Das Neueste vom RAD Studio – Neuigkeiten in Delphi.” Was ist die Kernbotschaft, die jeder Teilnehmer mit nach Hause nehmen sollte?
Matthias Eissing: Es geht, wie der Titel schon sagt, um die Neuerungen der Version 12; soweit man innerhalb der Vorschau schon darauf eingehen kann, und welche Funktionen, Erweiterungen und Neuerungen denn auch schon (absehbar) da sind. Kann sich natürlich ändern Die Kernbotschaft ist sicherlich: Delphi lebt, entwickelt sich weiter und wird auch hier den Entwickler besser unterstützen.
Max, du wirst auf der EKON das MachineLearningPackage vorstellen. Worum handelt es sich dabei?
Max Kleiner: Es geht im Kern darum, vortrainierte Modelle aus verschiedenen Frameworks oder Tools zu integrieren, also das bereits bewährte und geprüfte Wissen im Supervised Learning einzusetzen. Man muss auch die Scheu verlieren und die eigene Komfortzone verlassen, um die gespeicherten neuronale Netze aus anderen Plattformen, deren Parameter bereits durch selbstüberwachtes Lernen trainiert wurden, ansatzweise zu verstehen.
Bernd, du hältst auf der EKON den Workshop “Docker für Delphi-Entwickler:innen”. Was wirst du den Leuten mitgeben?
Bernd Ua: Die meisten Delphi-Entwickler:innen arbeiten nach wie vor mit der VCL-Bibliothek und adressieren auch nur Windows als Zielplattform. Nur ein deutlich geringerer Teil der Delphi-Entwickler:innen baut tatsächlich Web-APIs mit Delphi oder schreibt mit der Firemonkey-Bibliothek Linux-Anwendungen. In dem WebApi/Linux-Szenario ist Docker ja quasi unverzichtbar, ich möchte aber auch reinen VCL- und Windows-Entwickler:innen zeigen, wo sie Docker einsetzen können und wie sie mit Docker ihren Werkzeugkasten sinnvoll erweitern.
Christoph, dein Talk auf der EKON heißt “Hybride Verschlüsselung ohne Libraries mit WinRT.” Worum wird es gehen?
Christoph Schneider: Informationssicherheit ist für die allermeisten Entwickler zunehmend ein wichtiges Thema. In dieser Session wird das Schützen von Dokumenten und Nachrichten vor unerlaubtem Zugriff mittels kryptographischer Methoden behandelt. Für Windows-Anwendungen kann eine Verschlüsselung inzwischen gänzlich mit Delphi-Boardmitteln hergestellt werden. Es braucht keine Kryptobibliothek mehr, sondern nur Kenntnisse über den Aufbau der Hybridenverschlüsselung, um die symmetrischen und asymmetrischen Verschlüsselungsalgorithmen richtig zu kombinieren.
Nach einer kurzen theoretischen Einführung in die hybride Verschlüsselung zeige ich die Implementierung unter Verwendung der WinApi.Security. Detaillierte mathematische Erklärungen der eingesetzten kryptographischen Algorithmen kann ich dabei in der kurzen Zeit nicht geben. Doch werde ich auf sicherheitsrelevante Punkte bei der Wahl der Algorithmen und Konfiguration hinweisen. Das Thema des sicheren Schlüsselaustausch mittels Zertifikate kann in dieser Session nicht behandelt werden.
Vielen Dank für Eure Antworten!
The post Delphi – der Erfolgsgeschichte auf der Spur appeared first on Entwickler Konferenz.
]]>The post Web Anwendungen als Cross-Plattform-Lösung einsetzen – insbesondere auch offline appeared first on Entwickler Konferenz.
]]>Mittlerweile finden wir kaum noch Anwendungen, die für genau eine Plattform konzipiert werden können. Insbesondere die Beschränkung einer Anwendung nur auf dem Desktop verfügbar zu sein, ist mittlerweile nicht mehr tragbar. Viele Delphi Entwickler stehen nun vor der Frage, wie sie ihre Anwendung auf weiteren Plattformen anbieten können. Webanwendungen bringen klare Vorteile, um eine Anwendung auf jeder Plattform mit der selben Quelltextbasis zu entwickeln. Das reduziert die Entwicklungskosten. Auf der Seite des Endkunden ist keine spezielle Software oder Hardware erforderlich. Aktualisierung und Wartung bereits vorhandener Installationen ist einfach möglich. Insbesondere ist keine Installation beim Kunden erforderlich, damit die Software einsatzbereit ist. Selbst auf Mobilgeräten ist die Verwendung von Webanwendungen unproblematisch. Vielmehr gibt es zahlreiche Werkzeuge mit Gestaltungsmöglichkeiten für Benutzeroberflächen, wie z.B. Bootstrap [1], die speziell für Smartphones und Tablets ausgelegt werden.
Einzig und allein ein Hauptgrund behindert den Umstieg auf Webanwendungen: Die Anwendungen müssen auf einem Webserver im Internet (oder zumindest in einem Netzwerk) bereitgestellt werden. Das erfordert eine Verbindung zu dem Netzwerk, in dem der Webserver erreichbar ist, um die Anwendung zu nutzen. Daher kommen oftmals weiterhin native Anwendungen zum Einsatz, die speziell für die entsprechenden Endgeräte erstellt werden. Als Delphi Entwickler hat man hier mit dem FireMonkey Framework weiterhin sehr gute Karten, da man sowohl Software für Microsoft Windows, Apple macOS, Linux, als auch die mobilen Plattformen Apple iOS, iPadOS und Android entwickeln kann, ohne für jede Plattform eigene Varianten zu erstellen. Trotzdem sind insbesondere bei der Auslegung der Benutzeroberfläche viele Hürden zu nehmen, die bei Webanwendungen meist flexibler zu meistern sind.
Progressive Web Apps (PWA, dt. Progressive Webanwendungen) sind eine spezielle Art von Webanwendungen, die versuchen die Vorteile von Web- und nativen mobilen Anwendungen zu kombinieren. So können PWA auch in Offline-Szenarien zum Einsatz kommen. Moderne Webbrowser bieten hier meist eine Anbindung an das ausführende Betriebssystem und binden PWA direkt ein. Auf mobilen Endgräten, wie z.B. dem iPhone sind PWAs schwierig von nativen Anwendungen auf dem Home Screen zu unterscheiden (siehe Abbildung 1). Aber auch während der Ausführung der Anwendungen sind keine Hinweise auf eine Webanwendung direkt erkennbar, da sie im Vollbildmodus angezeigt und Merkmale des Webbrowsers ausgeblendet werden. Insbesondere die URL wird nicht angezeigt. Die Anwendung wird lokal auf dem Gerät zwischengespeichert und kann somit auch ausgeführt werden, wenn es keine Verbindung zum Netzwerk hat. Zudem wird bei bestehender Internetverbindung automatisch geprüft, ob auf dem Webserver eine neue Version bereitgestellt wird. Ist das der Fall, so wird die lokale Version automatisch aktualisiert. Ein weiterer Vorteil von nativen Anwendungen ist, dass sie auf spezielle Gerätefunktionen wie Kameras, Sensoren, Positionsbestimmung und Push- Nachrichten zugreifen können. Auch diese Beschränkung wird durch PWA aufgehoben, ohne dabei die Sicherheit zu kompromittieren. Der Zugriff auf diese Gerätefunktionen ist möglich. Jede PWA wird in einer individuellen Sandbox ausgeführt. Dazu werden alle Dienste nur mit einer gesicherten Verbindung über HTTPS ausgeführt. Zugriffe auf das lokale Dateisystem usw. sind erst nach manueller Bestätigung des Benutzers möglich. All diese Vorgänge müssen insbesondere nicht manuell implementiert werden sondern sind fester Bestandteil einer jeden PWA und stellen somit sicher, dass es sich bei PWA um sichere, gesicherte (im Englischen wird explizit unterschieden zwischen ’safety’ und ’security’) Anwendungen handelt.

Abbildung 1

Abbildung 2
Viele Entwickler führen auch die Vorgaben und Lizenzbeschränkungen von App Stores sowie Gebühren bei der Bereitstellung auf diesen Plattformen als Hinderungsgrund an, dass native Anwendungen auf bestimmten Plattformen bereitgestellt werden. Apple hat z.B. strenge Richtlinien wie die Benutzeroberfläche einer nativen Anwendung auszusehen hat und das erfordert meist, dass man die Anwendung jeweils auf die neueste Version von iOS und iPadOS aktualisieren muss. Auch diese Hürde entfällt durch den Einsatz von PWA. Ihre Kunden navigieren im Webbrowser zu einer URL und von dort kann die Anwendung dann komfortabel auf dem Gerät installiert werden. Leider gibt es unterschiedliche Ansätze, die vom verwendeten Gerät abhängen, so dass hier keine universelle Anleitung gegeben werden kann. Auf dem Apple iPhone und iPad wird die Anwendung über die Teilen Funktion, über die man z.B. auch ein Lesezeichen erstellt, zum Home Screen hinzugefügt (siehe Abbildung 2). Auf Android-Geräten hingegen wird direkt eine Dialogbox eingeblendet, dass man die Anwendung auf dem Home Screen installieren kann. Die Anwendung kann meist beliebig benannt werden. Das Symbol wird allerdings immerzu vom Entwickler festgelegt (siehe Abbildung 3).
In den vergangenen Ausgaben des Entwickler-Magazins wurde TMS WEB Core bereits als ein Werkzeug zur Entwicklung von Webanwendungen mit Delphi vorgestellt. Insbesondere werden aber auch Funktionen zur einfachen Erstellung von PWAs bereitgestellt, die nicht im Detail vorgestellt wurden. In diesem Artikel werden wir eine solche Anwendung entwickeln, die auch ohne Internetverbindung auf mobilen Geräten funktionieren wird. Wir werden eine kleine Wetterstation erstellen, die immerzu das aktuelle Wetter an unserer Position anzeigt. Dazu werden wir die Geocodingkomponente von TMS WEB Core verwenden. Sollte keine Internetverbindung bestehen, so wird auf den letzten Datenabgleich zurückgegriffen (siehe Abbildung 4).

Abbildung 4

Abbildung 5
Als Datenquelle nutzen wir das OpenWeather API (siehe Abbildung 5). Zur Nutzung des APIs ist die Erstellung eines Benutzerkontos erforderlich. Zudem ist ein Zugangsschlüssel zu generieren, der den Entwickler gegenüber des OpenWeather API identifiziert (siehe Abbildung 6). Um das hier gezeigte Beispiel zu reproduzieren, ist die kostenlose Variante ausreichend. Es gibt zahlreiche weitere kostenpflichtige Pakete, die eine höhere Informationstiefe der Wetterinformationen liefern. Für diesen Artikel reicht es allerdings aus, grundlegende Wetterinformationen abzurufen. Der kostenlose Endpunkt stellt bereits Wetterdaten für drei Tage zu zahlreichen Tageszeiten zur Verfügung.
TMS WEB Core integriert sich in die RAD Studio IDE. Es werden Vorlagen für verschiedene Anwendungtypen bereitgestellt. Darunter ist auch die Vorlage mit dem Namen TMS WEB PWA Application zu finden, die uns die Grundlage für eine PWA liefert (siehe Abbildung 7). Man erreicht diese Vorlage über File > New > Other… in der Kategorie Delphi > TMS WEB.
Es wird dann der Grundstock für eine PWA erstellt. Es empfiehlt sich direkt nach der Erstellung des Projektes, alle Projektdateien zu speichern (siehe Abbildung 9). Speichern Sie die Dateien in einem neuen Verzeichnis. Sie können die Vorgaben akzeptieren, jedoch empfehle ich die folgenden Anpassungen, die in den folgenden Punkten erläutert werden.

Abbildung 8

Abbildung 9
Dem Prinzip der rapiden Anwendungsentwicklung (RAD) bleibt TMS WEB Core treu. Sie können durch die Nutzung von Komponenten, die Sie aus der Werkzeugleiste auswählen und auf dem Formular positionieren, in Windeseile eine grafische Oberfläche erstellen. Die Namen und Funktion der Komponenten sind stark an die VCL von Delphi angelehnt. Die VCL beinhaltet TLabel für Textelemente, TMS WEB Core bietet TWebLabel an. Nahezu jede VCL-Komponente ist als TWeb-Variante mit demselben Namen zu finden. So gelingt es uns schnell mit TWebLabel, TWebImageControl und TWebTableControl die in Abbildung 10 dargestellte Oberfläche zu erstellen. Die verwendeten Komponenten, deren Namen und eine Kurzerklärung wofür sie verwendet werden, finden Sie in Tabelle 1.
Wir können die Anwendung bereits starten. Der Standardwebbrowser auf Ihrem System wird geöffnet und die Komponenten werden mit den zur Entwicklungszeit angegebenen Werten angezeigt.
Bevor wir die Komponenten mit Leben füllen können, müssen zwei grundlegenden Funktionen implementiert werden:
Beiden Funktionen werden im Web asynchron ausgeführt. Das heißt, wenn wir die aktuelle Position anfragen, kann die Komponente nicht direkt eine Antwort liefern. TMS WEB Core bietet vielfache Möglichkeiten, die Antwort auszulesen. Drei, um genau zu sein:
| Name | Komponente | Beschreibung |
| txtHeader | TWebLabel | Titel der Anwendung |
| txtLocationText | TWebLabel | Aktuelle Position |
| txtLocationNumbers | TWebLabel | Koordinaten der Position |
| txtDescription | TWebLabel | Aktuelle Wetterlage |
| Icon | TWebImageControl | Symbol für Wetterlage |
| Grid | TWebTableControl | Tabelle mit Kerninformationen |
Tabelle 1: Komponenten des Hauptformulars.
In diesem Beispiel werden wir die Implementierung über ein Ereignis und await vorstellen. Für eine detaillierte Betrachtung der Varianten sei hier auf weiterführende Literatur verwiesen.
Sowohl die Positionsbestimmung als auch die Anbindung an den Webservice sind in einem separatem Datenmodul zu finden (siehe Abbildung 11). Auf dem Datenmodul wurden zwei Komponenten abgelegt:
Die Methode UpdateLocation des Datenmoduls startet den Prozess.
procedure TWeatherServiceManager.UpdateLocation; begin Geocoder.GetGeolocation; end; procedure TWeatherServiceManager.GeocoderGeolocation( Sender: TObject; Lat, Lon, Alt: Double); begin Location.Latitude := Lat; Location.Longitude := Lon; if Assigned(FOnLocationUpdated) then begin FOnLocationUpdated(Location); end; end;
Sobald eine Position gefunden wird, können wir die Koordinaten aus den Parametern Lat und Lon auslesen. Das Ereignis OnLocationUpdated wird getriggert, falls es zugewiesen wurde. Über diesen Weg kann die Benutzeroberfläche informiert werden. Um das Beispiel nicht zu komplex gestalten, wird das Standardereignis vom Typ TNotifyEvent verwendet.
property OnLocationUpdated : TNotifyEvent read FOnLocationUpdated write FOnLocationUpdated;
Das OpenWeather API wird mit HTTP Requests angesteuert. In der Dokumentation sind die Endpunkte angegeben und welche Informationen zurückgegeben werden. Die Antworten sind allesamt in JSON kodiert.
Die URL für die Anfrage wird in GetForcastUrlForLocation konstruiert. Sie beinhaltet die geographischen Koordinaten und den API Key, der von OpenWeather bereitgestellt wird. Auf diesem Weg können Sie für beliebige Koordinaten Wetterinformation abrufen.
function TWeatherServiceManager.GetForecastUrlForLocation: String; begin Result := Format( REQ_PATTERN_FORECAST, [ Location.Latitude, Location.Longitude, API_KEY ] ); end; procedure TWeatherServiceManager.GetForecastForCurrentLocation; var LResponse: TJSXMLHttpRequest; begin Request.URL := GetForecastUrlForLocation; LResponse := await( TJSXMLHttpRequest, Request.Perform ); if LResponse.Status = 200 then begin ProcessForecastResult(LResponse.response); end; end;
Die Methode GetForecastForCurrentLocation weist der TWebHttpRequest-Komponente die notwendigen Informationen zu. In diesem Fall müssen wir nur die URL nachreichen, da alle anderen Informationen bereits zur Entwicklungszeit über den Objektinspektor festgelegt wurden. Die Funktion await erfordert zwei Parameter. Zuerst wird der Typ des Rückgabewertes spezifiziert. Anschließend die Methode, auf die gewartet werden soll. Sobald die Methode Request.Perform beendet ist, wird ihr Rückgabewert in LResponse abgelegt. Der spezielle Datentyp, der mehr oder weniger der Antwort von einem HTTP Request in JavaScript nachgebildet wurde, liefert in der Eigenschaft Status den HTTP-Statuscode zurück. Der Wert 200 deutet auf eine erfolgreiche Anfrage hin, die wir dann in der Methode ProcessForecastResult verarbeiten und in ein Objekt des Typs TWeatherForecast schreiben.
Es handelt sich hierbei um einen eigenen Typ, den wir deklarieren, um die Rückgabewerte vom Webservice abzulegen. Es ist denkbar, weitere Eigenschaften zu definieren, um z.B. die Temperatur sowohl in Fahrenheit als auch Celsius abzurufen.
type TWeatherForecast = class public property Dt: TDateTime; property Temperature: Double; property Humidity: Integer; property Description: String; property Icon: String; property PropPrec: Integer; property IconUrl: String read GetIconUrl; property DtReadable: String read GetDtReadable; end;
Neben simplen Eigenschaften, die Werte aus privaten Feldvariablen bereitstellen, gibt es zwei Eigenschaften, die uns das Leben einfacher machen. Wir können über IconUrl die URL auslesen, wo ein Icon zur Wetterlage, die beschrieben wird, zu finden ist.
function TWeatherForecast.GetIconUrl: String; begin Result := Format( URL_ICON, [Icon] ); end;
Mit DtReadable wird der Datumswert des Webservice in eine für uns lesbare Form umgewandelt.
function TWeatherForecast.GetDtReadable: String; var LFormat: TFormatSettings; begin LFormat := TFormatSettings.Create; LFormat.ShortDateFormat := 'ddd mmm d, yyyy'; LFormat.LongTimeFormat := '''@'' ham/pm'; Result := DateTimeToStr( UniversalTimeToLocal(Dt), LFormat ); end;
Der Zeitpunkt wird vom Webservice im universellen Zeitformat übermittelt, so dass wir auf die lokale Zeit mit UniversalTimeToLocal umwandeln müssen. Die Formatierung erfolgt wie in der VCL über TFormatSettings.
Die Auswertung der Antwort mit den Wetterinformationen erfolgt mit Hilfe von Klassen, die TMS WEB Core zum Verarbeiten von in JSON kodierten Informationen bereitstellt.
procedure TWeatherServiceManager.ProcessForecastResult( AResponse: JSValue; ADoStore: Boolean = true); var LArray: TJSArray; LObj: TJSObject; LRoot, LCity, LMain, LWeather: TJSObject; i: Integer; LForecast: TWeatherForecast; begin LRoot := TJSObject(AResponse); LCity := TJSObject(LRoot['city']); Location.Name := JS.toString(LCity['name']); Location.Country := JS.toString(LCity['country']); LArray := TJSArray( LRoot['list'] ); FForecasts.Clear; for i := 0 to LArray.Length-1 do begin LObj := TJSObject( LArray[i] ); LMain := TJSObject(LObj['main']); LWeather := TJSObject( TJSArray(LObj['weather'])[0] ); LForecast := TWeatherForecast.Create; LForecast.Dt := UnixToDateTime( JS.toInteger( LObj['dt'] ) ); LForecast.Temperature := JS.toNumber( LMain['temp'] ); LForecast.Humidity := JS.toInteger( LMain['humidity'] ); LForecast.Description := JS.toString( LWeather['description'] ); LForecast.PropPrec := trunc( JS.toNumber( LObj['pop'] ) * 100 ); LForecast.Icon := JS.toString( LWeather['icon'] ); FForecasts.Add(LForecast); end; end;
Das Datenmodul definiert eine generische Liste in der Feldvariablen FForecasts auf der alle gelieferten Wetterinformationen abgelegt werden.
Nachdem alle Informationen in die Datenstruktur übernommen wurden, sind zwei Dinge zu tun:
if (FForecasts.Count>0) then begin if ADoStore then begin StoreLastForecastResponse(AResponse); end; if (Assigned(FOnForecastUpdated)) then begin FOnForecastUpdated(nil); end; end;
Da wir die Methode zum Auswerten der JSON-Daten auch verwenden, um zuvor gespeicherte Daten zu laden, zeigt die Variable ADoStore an, ob die Daten gespeichert werden müssen.
Der Webbrowser hat im Normalfall keinen Zugriff auf das System, auf dem die Webseite angezeigt wird. Als Lösung wird in jedem Webbrowser das Local Storage bereitgestellt. Es funktioniert wie eine INI-Datei, dass einem Schlüssel, der über eine Zeichenkette identifiziert wird, ein Wert zugewiesen werden kann. Für jede Anwendung wird vom Browser ein eigener Speicherbereich eingerichtet. Die Identifizierung erfolgt über die URL der Anwendung.
In unserem Fall müssen wir einen Weg finden, die Antwort des Webservice dort abzulegen. Falls die Anwendung ohne bestehende Internetverbindung ausgeführt wird, können wir so eine vorangegangene Antwort an die soeben vorgestellte Methode zum Auswerten übergeben.
procedure TWeatherServiceManager.StoreLastForecastResponse(AResponse: JSValue); begin TLocalStorage.SetValue( STORAGE_KEY_FORECAST, TJSJSON.stringify(AResponse) ); // as the date/time is only used locally, we can use the local time of the // system TLocalStorage.SetValue( STORAGE_KEY_DT_FORECAST, DateTimeToRFC3339( Now ) ); end;
TMS WEB Core bietet die Klasse TLocalStorage zum Zugriff auf den lokalen Datenspeicher. Die Methode SetValue schreibt einen Wert in einen Schlüssel. Die JSON-Informationen des Webservice können mit einem Trick über stringify als Zeichenkette ebenfalls abgelegt werden. Zudem speichern wir den Zeitpunkt der letzten erfolgreichen Abfrage vom Webservice.
Das Einlesen erfolgt in der Methode LoadLastForecastResponse.
procedure TWeatherServiceManager.LoadLastForecastResponse; var LStoredForecast: String; LJSON: JSValue; begin LStoredForecast := TLocalStorage.GetValue(STORAGE_KEY_FORECAST); if not LStoredForecast.IsEmpty then begin LJSON := TJSJSON.parse(LStoredForecast); // process, but do not store locally - it's already stored ProcessForecastResult(LJSON, False); end; end;
Das Gegenstück zu SetValue ist GetValue zum Einlesen von Daten als String. Wurden keine Daten unter dem angefragten Schlüssel abgelegt, so wird eine leere Zeichenkette returniert. Ansonsten können wir mit parse den JSON-Datentyp rekonstruieren und an die Methode zum Auswerten übergeben. Als zweiten Parameter übergeben wir False, da es sich um lokale Werte und nicht um neue Werte des Webservice handelt.
Die visuellen Komponenten können mit zusätzlichen CSS-Klassen versehen werden, um das Erscheinungsbild an ein gewünschtes Design anzupassen. Eine populäre Bibliothek, die in TMS WEB Core direkt unterstützt wird, ist Bootstrap. Bibliotheken, die von TMS bereitgestellt werden, können über den Library Manager in ein Projekt eingefügt werden. Durch einen Rechtsklick auf das Projekt ist der Bibliotheksmanager im Kontextmenü über die Funktion Manage JavaScript Libraries… zu erreichen (siehe Abbildung 12). Dort können wir eine der Bootstrap-Versionen auswählen, um unsere grafischen Elemente mit CSS-Klassen aus dieser Bibliothek zu versehen. Jede grafische Komponente beinhaltet die Eigenschaft ElementClassName. So kann das Labels txtHeader z.B. durch Wahl der Klasse display-4 in einer Titelschrift dargestellt werden. Damit TMS WEB Core weiß, ob die Schrifteinstellungen aus dem Objektinspektor oder aus dem CSS-Framework verbindlich sind, ist ElementFont auf efProperty oder efCSS zu setzen. Schauen Sie sich die einzelnen Komponenteneigenschaften im Objektinspektor an, indem Sie auf die einzelnen Komponenten klicken. Bootstrap ist keinesfalls erforderlich, liefert aber gegenüber dem Endbenutzer direkt eine klare Darstellung als Webanwendung. Es ist anzumerken, dass es sich hierbei um einen Zwischenschritt handelt. TMS WEB Core erlaubt auch tiefergehendes, responsives Design mit Bootstrap über die HTML-Datei, die jedem Formular zugeordnet ist. Entsprechende Videos hierzu sind auf dem YouTube-Kanal von TMS oder in der Literatur zu finden [2].
In der Beschreibung der Methoden des Datenmoduls wurde bereits klar, dass andere Objekte über Ereignisse informiert werden können, sobald z.B. Daten vom Webservice übermittelt wurden. Wir müssen nun bei Erstellung der Anwendung das Datenmodul erzeugen und die Ereignisse mit Methoden des Hauptformulars verbinden.
procedure TFrmMain.WebFormCreate(Sender: TObject); begin txtHeader.Caption := 'Your Weather Report'; FService := TWeatherServiceManager.Create(self); FService.OnLocationUpdated := OnLocationUpdated; FService.OnForecastUpdated := OnForecastUpdated; FService.LoadLastForecastResponse; UpdateLocation; Application.OnOnlineChange := OnOnlineStatusChanged; end;
Bei Erstellung des Hauptformulars erzeugen wir eine neue Instanz vom Datenmodul TWeatherServiceManager und weisen es der Feldvariablen FService zu. Weiterhin weisen wir die Ereignisse OnLocationUpdated und OnForecastUpdates des Datenmoduls den zugehörigen Methoden im Hauptformular zu. Sofern im lokalen Speicher Informationen abgelegt wurden, werden diese direkt geladen. Das ist auch sinnvoll, wenn eine langsame Internetverbindung besteht. Es werden direkt Informationen angezeigt. Erst wenn wir die aktuelle Position bestimmt haben, können wir die Wetterinformationen abfragen. Daher rufen wir die Methode UpdateLocation auf, die die Positionsbestimmung des Datenmoduls aufruft:
procedure TFrmMain.UpdateLocation; begin if Application.IsOnline then begin FService.UpdateLocation; end; end;
Die Positionsbestimmung kann natürlich nur dann erfolgen, wenn eine Internetverbindung besteht, da anschließend eine Abfrage am Webservice erforderlich ist.
Die letzte Zeile des OnCreate Ereignis des Hauptformulars hat eine besondere Bedeutung. Sobald sich der Status der Internetverbindung ändert, möchten wir informiert werden. Besteht nun eine Verbindung, so soll die Position bestimmt werden. Das Applikationsobjekt einer TMS WEB Core PWA besitzt genau dieses Ereignis, dass über einen Wechsel der Internetverbindung informiert. Das Ereignis wird im Hauptformular zugewiesen und ist wie folgt implementiert:
procedure TFrmMain.OnOnlineStatusChanged( Sender: TObject; AStatus: TOnlineStatus); begin if AStatus = osOnline then begin UpdateLocation; end; end;
Der Parameter AStatus signalisiert eine nun bestehende Verbindung mit osOnline. Es kann dann die Positionsbestimmung aufgerufen werden.
Bei einer erfolgreichen Positionsbestimmung muss der Webservice befragt werden. Wir wissen, dass das Datenmodul das Ereignis OnLocationUpdate aufruft. Dort werden wir dann die Abfrage am Webservice auslösen:
procedure TFrmMain.OnLocationUpdated(Sender: TObject); begin UpdateForecast; end; procedure TFrmMain.UpdateForecast; begin if Application.IsOnline then begin FService.UpdateForecast; end; end;
Erneut ist zu beachten, dass eine Internetverbindung ggf. mittlerweile nicht mehr besteht, so dass wir die Abfrage nur bei bestehender Verbindung einleiten. Sobald die Abfrage erfolgreich war und ausgewertet wurde, wird das Ereignis OnForecastUpdated aufgerufen. Hier können wir nun die Benutzeroberfläche im Hauptformular aktualisieren:
procedure TFrmMain.OnForecastUpdated(Sender: TObject); var LForecast: TWeatherForecast; begin LForecast := FService.CurrentForecast; Icon.URL := LForecast.IconUrl; txtDescription.Caption := LForecast.Description; txtLocationText.Caption := FService.Location.Name + ', ' + FService.Location.Country; txtLocationNumbers.Caption := Format( '(Lat: %.2f, Lon: %.2f)', [ FService.Location.Latitude, FService.Location.Longitude ] ); Grid.Cells[ 0, 0 ] := 'Forecast for'; Grid.Cells[ 1, 0 ] := LForecast.DtReadable; Grid.Cells[ 0, 1 ] := 'Temperature'; Grid.Cells[ 1, 1 ] := LForecast.Temperature.ToString + ' C'; Grid.Cells[ 0, 2 ] := 'Humidity'; Grid.Cells[ 1, 2 ] := LForecast.Humidity.ToString + '%'; Grid.Cells[ 0, 3 ] := '% of Precipation'; Grid.Cells[ 1, 3 ] := LForecast.PropPrec.ToString + '%'; end;
Das Datenmodul liefert über CurrentForecast die zutreffenden Wetterinformationen in der selbst definierten Datenstruktur TWeatherForecast zurück. Wir können somit mit bekannten Mitteln die Informationen in ein Grid einfügen und die Labels mit Informationen befüllen. Beachten Sie, dass wir der TWebImageControl-Komponente eine URL zuweisen können und das zugehörige Bildmaterial automatisch aus dem Web geladen wird. Wir stellen auch sicher, dass immer Wetterinformationen geliefert werden. Der Trick ist außerdem, dass wir an dieser Stelle nicht mehr unterscheiden müssen, ob wir online oder offline sind. CurrentForecast liefert Daten aus der Liste des Datenmoduls zurück, die entweder mit den Angaben aus dem lokalen Speicher oder vom Webservice gefüttert werden.
function TWeatherServiceManager.GetCurrentForecast: TWeatherForecast; var LIndex: Integer; LForecast: TWeatherForecast; begin Result := nil; LIndex := 0; // This simple algorithm works because the forecast items are returned in // order. The first index in the list denotes the most current // weather forecast // whereas the last index is the most distant in the future. // For the particular endpoint chosen this means 3 days out. while LIndex < FForecasts.Count do begin LForecast := FForecasts[LIndex]; if UniversalTimeToLocal(LForecast.Dt) > Now then begin Result := LForecast; break; end; Inc(LIndex); end; if Result = nil then begin Result := FForecasts.Last; end; end;
Die aktuelle Vorhersage wird gemäß dem aktuellen Datum zurückgeliefert. Existiert keine aktuelle Angabe, da z.B. sehr lange keine Internetverbindung mehr bestand oder Sie die Anwendung lange nicht mehr gestartet haben, so wird immerzu die letzte Information angezeigt. Die Daten vom Webservice werden in zeitlich aufsteigender Reihenfolge zurückgeliefert, so dass die Elemente in der Liste stets sortiert sind.
Das komplettiert die Beschreibung der Anwendung. Alle anderen Funktionen werden über die PWA-Vorlage bereitgestellt.
Als Kind habe ich bereits gelernt, dass Vertrauen gut ist, aber Kontrolle meist besser. Es ist unmöglich auf allen existierenden Geräten zu prüfen, ob ihre Webanwendung alle PWA-Anforderungen erfüllt. Google Chrome Lighthouse wurde zunächst von Google als eine Erweiterung für den Chrome Webbrowser angeboten, die Anwendungen prüft. Mittlerweile ist diese Funktion sogar in der Entwicklerkonsole in der Kategorie Lighthouse vollständig integriert und erfordert keinen zusätzlichen Download mehr.
Die Prüfung der hier vorgestellten Anwendung verläuft positiv (siehe Abbildung 13).
Dieser Artikel hat Sie in die Welt der Progressive Web Applications (PWA) eingeführt und gezeigt, wie schnell und effizient Sie Anwendungen von diesem Typ mit TMS WEB Core entwickeln können. Das Ausschlusskriterium, dass Webanwendungen nur mit bestehender Internetverbindung genutzt werden können, wird neben vielen weiteren Blockaden aus dem Weg geräumt. Die Anwendung, die hier vorgestellt wurde, ist unter der URL https://www.tmssoftware.com/pwa/weather/ erreichbar. Probieren Sie sie ruhig einmal aus und fügen sie auf einem Ihrer Mobilgeräte hinzu. Den Quelltext finden Sie auf GitHub unter https://github.com/holgerflick/weatherpwa.
Als weiterführende Literatur ist zunächst die ausführliche Dokumentation von TMS anzuführen. Dem Produkt liegt ein PDF-Dokument mit über 700 Seiten bei. Dazu habe ich ein Buch geschrieben mit dem Titel „TMS WEB Core: Web Application Development with Delphi: Rapid Application Development for the Web“ [3] in der zweiten Auflage. Mit dem Buch kann jeder Delphi Entwickler anhand von detailliertem, praxisnahem Beispiel die Entwicklung von Webanwendungen in der Tiefe erlernen. Dabei wird der komplette Prozess von der Installation bis zur Veröffentlichung auf Webservern und sogar in Docker Containern vorgestellt.
[1] https://getbootstrap.com/
[2] https://www.youtube.com/tmssoftwareTV
[3] https://flixengineering.com/books
Flick_pwa_1.png
Abb. 1: PWA-Anwendungen sind auf mobilen Geräten nicht von nativen Anwendungen auf dem Home Screen zu unterscheiden. Ein Icon kann mit jeder Anwendung in mehreren Auflösungen bereitgestellt werden.
Flick_pwa_2.png
Abb. 2: Auf dem Apple iPhone können PWA-Anwendungen über die Funktion ‘Teilen’ zum Home Screen hinzugefügt werden. Anstatt, dass man ein Lesezeichen im Webbrowser erstellt, wird über die Funktion Add to Home Screen ein Symbol auf dem Home Screen erstellt.
Flick_pwa_3.png
Abb. 3: Progressive Web Apps können benannt werden. Das Symbol wird zusammen mit der Anwendung vom Entwickler festgelegt und kann vom Benutzer nicht verändert werden.
Flick_pwa_4.png
Abb. 4: Webanwendung zur Anzeige des Wetters an der aktuellen Position. Sollte das Gerät keine Internetverbindung haben, wird die zutreffende Prognose aus dem Speicher geladen.
Flick_pwa_5.png
Abb. 5: Das OpenWeather API dient als Datenquelle für die Wetterinformationen der App.
Flick_pwa_6.png
Abb. 6: Zur Datenabfrage über das OpenWeather API ist ein Benutzerkonto erforderlich. Man kann dann einem Zugangsschlüssel generieren, die bei jeder Anfrage am Webservice zu übertragen ist.
Flick_pwa_7.png
Abb. 7: Vorlage zur Erstellung einer neuen PWA in RAD Studio.
Flick_pwa_8.png
Abb. 8: Anwendungsinformationen können komfortabel in den Projektoptionen eingegeben werden. Die Generierung des Manifests der Anwendung erfolgt automatisch.
Flick_pwa_9.png
Abb. 9: Elemente einer PWA im Projektmanager.
Flick_pwa_10.png
Abb. 10: Das Hauptformular der Anwendung. (1) TWebLabel, (2) TWebImageControl, und (3) TWebTableControl.
Flick_pwa_11.png
Abb. 11: Datenmodul mit Komponenten zur Positionsbestimmung und Kommunikation mit einem Webservice.
Flick_pwa_12.png
Abb. 12: Eine Vielzahl von JavaScript-Bibliotheken kann über den Bibliotheksmanager zu Projekten hinzugefügt werden.
Flick_pwa_13.png
Abb. 13: Google Chrome Lighthouse erstellt einen Bericht, ob Ihre Anwendung die Kriterien für eine PWA erfüllt.
The post Web Anwendungen als Cross-Plattform-Lösung einsetzen – insbesondere auch offline appeared first on Entwickler Konferenz.
]]>The post Agile: Wohin des Weges? appeared first on Entwickler Konferenz.
]]>Das Agile Manifest [1] existiert bereits seit 2001. Als die ersten Projekte begannen, agil zu arbeiten, erfuhren sie meist Verwunderung, nicht selten auch Ablehnung. Das ist nachvollziehbar, da agiles Arbeiten in vielen Aspekten deutlich anders und ungewohnt war. Zu Beginn dominierten Fragen wie „Geht das überhaupt?“ oder „Ist dieser Hype bald vorbei?“ Diese Fragen waren oft Ausdruck der Hoffnung, dass sich das Thema bald von selbst erledigen würde und man so weitermachen könnte wie bisher. Und die Hoffnung war nicht ganz unberechtigt, da die IT von Moden getrieben ist und die Industrie immer wieder neue Themen für die Vermarktung braucht. Viele Hypes erreichen nie das Plateau der Produktivität und verschwinden dann wieder in der Versenkung.
Wer den neuen Themen aufgeschlossen gegenüberstand, fand in neuen Frameworks starke Innovation und Inspiration. Zu einer Zeit, in der klassisch gemanagte Projekte nicht selten einen problematischen Verlauf nahmen, war der Boden fruchtbar für Neues.
Es gab viel zu entdecken. Mit Scrum, Kanban, Lean, DevOps und Design Thinking seien nur einige wichtige Vertreter genannt. Einfach erklärt, aber schwer gemacht. Neue Praktiken, Prinzipien und Werte wollten gelernt und verinnerlicht werden. Dabei musste so manches aus dem Rucksack der Erfahrungen entfernt und durch Neues ersetzt werden. Es entstanden Organisationen, wie beispielsweise ScrumAlliance oder Scrum.org, die den Themen mehr Struktur verliehen und Zertifizierungen anboten. Zu Beginn waren Rollenbeschreibungen wie Scrum Master oder Product Owner in Stellenausschreibungen noch selten zu finden. Aufgrund der steigenden Nachfrage setzten eine Kommerzialisierung und Professionalisierung ein, die bis heute andauern.
Die eingangs genannten Fragen hört man heute nicht mehr. Zu oft wurden die Vorteile des iterativen und adaptiven Vorgehens bewiesen. Studien belegen regelmäßig die Leistungsfähigkeit agilen Arbeitens. Beispielsweise geben 89 Prozent der Befragten der Studie „Status Quo (Scaled) Agile“ der Hochschule Koblenz an, dass der Gewinn größer ist als der Aufwand [2]. Bei skalierten Ansätzen sogar 93 Prozent.
Damit ist agiles Arbeiten wohl im Mainstream angekommen. Mainstream bedeutet, dass ein Thema selbstverständlich geworden ist. Das Interesse lässt nach und der Wunsch, es explizit zu besprechen, nimmt ab. Agile ist Mainstream, genauso wie Java, genauso wie Autofahren. Hm!?
Vor kurzem bemerkte ein Kollege auf die Frage, ob wir im Team einen dedizierten Scrum Master benötigen, dass mittlerweile sowieso fast jeder Entwickler wüsste, wie es funktioniert, und ein Scrum Master daher unnötig wäre. Wenn es darum geht, Praktiken wie Stand-ups, Reviews oder Retros auf der Ebene einzelner Teams einzusetzen, ist das insbesondere bei Entwicklern wohl zur Selbstverständlichkeit geworden. Eingesetzt werden meist Frameworks wie Scrum, Kanban oder Kombinationen aus beidem. Regelmäßig lässt sich dabei auch Cargo Cult beobachten. Dabei werden agile Praktiken eingesetzt, weil man es eben so macht, und nicht, weil es im Kontext sinnvoll ist. Ist das dann agil?
Seit geraumer Zeit beschäftigen sich Organisationen damit, agiles Arbeiten zu skalieren, das heißt, mehr und größere Vorhaben mit agilen Praktiken zu bearbeiten. Dabei orientieren sie sich an Frameworks wie LeSS [3], Scrum@Scale [4], SAFe [5], Nexus [6] oder dem Spotify-Modell [7]. Alle diese Frameworks sind inspirierend und enthalten viele spannende Ideen und Anregungen für die eigene Skalierung.
Einfaches Kopieren der beschriebenen Ansätze führt aber kaum zum Erfolg. Zu unterschiedlich sind die Erfahrungen, Prägungen, Erfolgsrezepte und mitarbeitenden Menschen in den Organisationen, um sie durch ein einheitliches Modell zu organisieren. Am Beispiel Spotify wird das deutlich. Das Spotify-Modell ist attraktiv, da es interessante Konzepte verwendet und leicht verständlich ist. Jedoch markiert es lediglich einen Zeitraum in der Entwicklung von Spotify. So, wie es beschrieben ist, wird es auch von Spotify nicht gelebt [8].
Dass der Weg zu agilem Arbeiten nicht leicht ist, erkennen wir auch an Zuschreibungen aus Projekten wie Zombie-Scrum, FlaccidScrum, ScrumBut, WaterScrum, Fake oder Dark Agile. Diese weisen auf oberflächliche Implementierungen hin, bei denen agile Praktiken angewendet, Prinzipien und Werte aber oft nicht gelebt und berücksichtigt werden. Dabei wird vernachlässigt, das agiles Arbeiten oft einen grundlegenden Kulturwandel bedeutet, der für Organisationen sehr herausfordernd sein kann. Auch der sogenannte agil-industrielle Komplex trägt möglicherweise dazu bei, dass Implementierungen nicht gelingen. Der Begriff entstand in Anlehnung an den Begriff des militärisch-industriellen Komplexes, der ein Verhalten von Institutionen und Beratungsunternehmen beschreibt, die aus Gründen der Profitsteigerung versuchen, selbst Nachfrage zu erzeugen. Der Verkauf von Dienstleistungen ist dabei wichtiger als die Lösung echter Kundenprobleme. Auch das führt zu oberflächlichen Implementierungen.
Interessanterweise ist agiles Arbeiten in den meisten Organisationen immer noch primär im Bereich der Entwicklung anzutreffen. Diese agilen Inseln sind oft schnell und flexibel. Dadurch, dass sie eingebettet sind in nicht agile Prozesse und Wertströme mit Engpässen und entsprechenden Wartezeiten, werden die Ziele der Agilität auf Ebene der Organisation häufig nicht oder nur unvollständig erreicht. Das zu ändern, ist Ziel der sogenannten Business Agility. Business Agility beschreibt die Fähigkeit ganzer Organisationen, sich an veränderliche Rahmenbedingungen anzupassen. Folgt man dem „2021 Business Agility Report“ [10] ist die Reife noch nicht sehr ausgeprägt. Ein Wert von 5,0 auf einer Skala von 1 bis 10 bedeutet, dass gerade das Laufen gelernt wird. Von Mainstream ist das noch weit entfernt (Abb. 1).
Im Kern geht es beim Thema Agilität um die Veränderung der Organisationskultur [11]. Erwartungsgemäß tun sich größere Organisationen damit schwerer als kleinere, da sie eine längere Geschichte mit sich herumtragen.

Abb. 1: 2021 Business Agility Report
Bevor wir Hypothesen über die Zukunft anstellen, lässt sich festhalten, dass die agile Bewegung bisher enormen Einfluss auf die Art genommen hat, wie heute Software entwickelt wird. Vieles ist gelungen und hat zur Verbesserung von Produkten und Dienstleistungen sowie der Zufriedenheit von Entwicklern bei ihrer Arbeit beigetragen (Kasten: „Warum agil?“).
Agiles Arbeiten ist attraktiv und erstrebenswert, da es zwei zentrale Ziele adressiert: erstens die Beweglichkeit von Organisationen am Markt und damit verbundene Wettbewerbsvorteile, zweitens die Zufriedenheit der Mitarbeitenden. Je nach Studie unterscheiden sich die Beschreibungen und Gewichtungen beider Faktoren. Beispiele sind Schnelligkeit am Markt und Mitarbeiterzufriedenheit [10], Optimierung der Produkteinführungszeit und Attraktivität als Arbeitgeber [2], Verbesserung der Fähigkeit, mit wechselnden Prioritäten umzugehen, und die Verbesserung der Teamproduktivität [9]. Das erste Ziel gewinnt in Zeiten wachsender Komplexität und Volatilität immer mehr an Bedeutung. Agiles Arbeiten bietet eine Möglichkeit, in diesem Umfeld erfolgreich zu sein. Beide Ziele bedingen und stärken sich gegenseitig und erzeugen im Idealfall einen eskalierenden Regelkreis. Eine Win-win-Situation sowohl für Organisationen als auch für Mitarbeitende.
Was wir heute erleben, ist eine Häufung krisenhafter Situationen: Finanzkrise, Coronakrise, Klimakrise, Energiekrise, Demographiekrise und so weiter. Oft sind wir davon überrascht und daher unzureichend vorbereitet. Wir sind Menschen, das ist normal. Denn obwohl wir versuchen können, uns durch vorausschauendes, szenariobasiertes Denken auf mögliche Ereignisse vorzubereiten, lassen sich insbesondere Effekte, die durch Krisenüberlagerung (Polykrisen) entstehen, kaum vorhersehen. Diese Situation bezeichnet man als VUCA, was so viel bedeutet wie Volatilität, Unsicherheit, Komplexität und Ambivalenz. Der Begriff entstammt dem United States Army War College und diente dazu, die Welt nach Ende des Kalten Krieges zu beschreiben [12]. Inzwischen stellt er ebenfalls eine zentrale Triebfeder für den Trend zur Agilisierung dar.
Während der Begriff VUCA vor nicht allzu langer Zeit noch eher abstrakt wahrgenommen wurde, drängt er sich seit der Coronakrise mit Macht in das Bewusstsein und die Erlebniswelt vieler Menschen. Das Verständnis dafür wächst, warum es wichtig ist, agil zu sein. Was können wir tun, wenn ständig alles in Bewegung ist und wir uns immer weniger auf die Planbarkeit der Zukunft verlassen können? Genau, selbst beweglich sein, um uns schnell an veränderte Rahmenbedingungen anpassen zu können. Das gilt für Individuen genauso wie für Organisationen. Und genau darum geht es auch bei der Agilität. Sie hilft uns, in einem Umfeld von Unsicherheit handlungsfähig zu bleiben und sogar gestaltend tätig zu sein. Wir können davon ausgehen, das agile Organisationen besser mit der Coronakrise fertig werden als klassisch organisierte. Erste Studien zeigen in diese Richtung. Der „2021 Business Agility Report“ [10] fragte nach der Zustimmung für die Aussage: „Business Agility hat einen überragend unterstützenden Einfluss beim Umgang mit Covid“. 80,6 Prozent stimmen zu, 0 Prozent widersprechen (Abb. 2). Agilität scheint wichtiger als je zuvor.

Abb. 2: Zur Frage „Business Agility hat einen überragend unterstützenden Einfluss beim Umgang mit Covid“
Manche agile Frameworks bauen aufeinander auf. Beispielsweise basieren LeSS und Nexus auf Scrum. SAFe basiert auf Scrum und Kanban und Flight Levels auf Kanban. Daneben gibt es eigenständige Bewegungen und Frameworks, wie DevOps, Design Thinking, Modern Agile oder Lean. Und obschon es eine Vielzahl hervorragender agiler Frameworks gibt, ist Agilität nicht mit diesen gleichzusetzen. Bei näherem Hinsehen stellen wir fest, dass alle einen sehr ähnlichen Kern aus Werten und Prinzipien besitzen. Dieser Kern ist es, der das Wesen der Agilität ausmacht. Abbildung 3 zeigt wichtige Konzepte der bekanntesten agilen Frameworks.

Abb. 3: Zentrale Konzepte
Das vermutlich wichtigste Konzept und zentrale Schwungrad ist die stetige Verbesserung, also Inspect and Adapt, auch als Kaizen oder Sense and Respond bezeichnet. Nicht umsonst ist es eine der Säulen in Scrum. Es ist so einfach wie einleuchtend. Ein Vorgehen, das die eigene Verbesserung eingebaut hat, kann sich aus sich selbst heraus erneuern und sich an die jeweiligen Kontexte anpassen. Damit das weiter gelingt, gilt es stärker als bisher, eine lernende und experimentierfreudige Organisation zu entwickeln. Dazu bedarf es ständiger Reflektion und kritischer Kontroversen, eingebettet in einen Rahmen psychologischer Sicherheit [13]. Das gilt außerhalb der Entwicklung auch für alle Bereiche der Organisationen wie Marketing, Vertrieb oder Betrieb und betrifft Geschäftsmodelle, Produkte, Design, Code, Architektur und Prozesse gleichermaßen.
Evolvierbarkeit bzw. Wandelbarkeit kennen wir auch aus dem Bereich Clean Code [14] in Bezug auf die Codebasis und Architektur. Es geht darum, flexibel zu sein, und die Fähigkeit zu erlangen, sich schnell auf sich ändernde Rahmenbedingungen einstellen zu können. Das kann beispielsweise bedeuten, ein Produkt, das am Markt nicht erfolgreich ist, zeitnah aus dem Portfolio zu nehmen, um dadurch gebundene Kapazitäten für neue Initiativen zu gewinnen. Oder Technologien aufzugeben, die nicht flexibel genug sind, um neue Produkte in kurzer Zeit zu entwickeln.
Um in der VUCA-Welt bestehen zu können, werden die Faktoren Beweglichkeit und Innovationsfähigkeit immer wichtiger. Laut dem Global Innovation Index des WIPO [15] steht Deutschland im Bereich der Innovation auf Platz 10 und ist auch in Europa nicht unter den ersten drei. Noch drastischer zeigt es der „Digital Riser Report“ [19]. Hier fällt Deutschland in der G20-Gruppe auf den drittletzten Platz (Abb. 4).

Abb. 4: Digital Riser Ranking G20
Laut der Studie fehlt es vor allem am Mindset. Wir haben es uns bequem gemacht. Im Bereich digitaler Infrastruktur und Produkte sind wir eher Konsumenten meist amerikanischer Produkte als Produzenten eigener Lösungen. Hier gibt es viel Potenzial und Handlungsbedarf, um die Wettbewerbsfähigkeit im Rahmen der Digitalisierung zu verbessern. Aktuelle Krisen führen uns vor Augen, dass es wichtig ist, Kreativität und eigene Antworten zu entwickeln und Abhängigkeiten zu reduzieren. Auch auf dieser Ebene kann mehr Autonomie die Handlungsfähigkeit verbessern.
So unerwünscht Krisen meist sind, so hilfreich können sie als Katalysatoren sein. Da Krisen vermutlich nicht weniger werden und sich gegenseitig überlagern, wird es immer wichtiger, Innovationsfähigkeit und Beweglichkeit zu entwickeln. Je höher die äußere Änderungsdynamik ist, umso mehr gewinnt das an Relevanz. Digitale Lösungen kombiniert mit agiler Kultur bieten dafür keine umfassende Lösung, aber sicherlich gute Ansätze, um damit umzugehen. Gerade für Organisationen mit starren Strukturen wird es zunehmend wichtig sein, sich zu verändern und mit Mut und Lernbereitschaft eine Kultur zu entwickeln, die schnelle Anpassung ermöglicht. Um die Menschen für die Veränderung zu gewinnen, ist ein Umfeld psychologischer Sicherheit [13] entscheidend.
Enge Zusammenarbeit von talentierten und produktiven Menschen ist ein Schlüssel, der in vielen Frameworks, beispielsweise Scrum, Design Thinking oder DevOps, betont wird. Im Zentrum stehen dabei cross-funktionale Teams, die sich ganzheitlich um einen Wertstrom kümmern, unterstützt von Plattformen, die von den Teams weitgehend selbst betrieben werden können. Domänenexperten arbeiten eng zusammen mit Entwicklern, UX-Designern, Ops und Anwendern der Produkte, die alle voneinander lernen. Bezeichnungen von Rollenkombinationen wie BizDevs, DevOps oder DevSecOps zeigen diesen Trend. Ansätze wie Service Safaris oder Dogfooding weisen ebenfalls in diese Richtung. Dabei entwickeln sich Organisationen mit IT-Abteilungen zunehmend zu Tech-Firmen, die digitale Produktentwicklung als ihre Kernkompetenz verstehen. Manche gehen den Weg der Transformation, andere versuchen es über Ausgründungen. Der Mensch steht im Mittelpunkt der Innovation. Leadership wird wichtiger. Dabei geschieht Führung weniger durch Planung und Anweisung, sondern eher durch Inspiration, Motivation und Vorbild.
Die Liberalisierung agiler Ansätze nimmt zu. Das basiert auf der Erkenntnis, dass Organisationen einzigartige Gebilde sind, die durch eine individuelle Kulturentwicklung geprägt wurden. Die genannten Umfragen [2], [9] zeigen, dass SAFe insbesondere in größeren Organisationen am häufigsten eingesetzt wird. SAFe ist verglichen mit anderen Frameworks deskriptiver. Die Wahl von SAFe könnte man so interpretieren, dass die Organisationen mit einer klassischen Unternehmenskultur eher deskriptive Frameworks bevorzugen, da es für sie schwieriger ist, liberalere Frameworks einzusetzen, bei denen es stärker darauf ankommt, durch Inspect and Adapt den eigenen „Way of Work“ zu finden. Darum wird es aber vermutlich stärker gehen. Agile Kultur von der Stange gibt es nicht. Ansätze wie Modern Agile [13], Liberating Structures [16] oder Sense and Respond [17] helfen den Mitarbeitenden einer Organisation, eine Kultur zu entwickeln, die schnelles Lernen und Adaption möglich macht und Innovation hervorbringt. Auch Sozialtechnologien wie die Soziokratie [18] beinhalten viele Angebote, beispielsweise zur belastbaren Entscheidungsfindung in selbstorganisierten Organisationen. Dabei findet jede Organisation ihren eigenen Weg, den man vielleicht als Custom Agile bezeichnen könnte.
Oft agieren wir aus einseitigen Perspektiven heraus, beispielsweise wenn wir aus technischer Perspektive eine maximale Testabdeckung auf vielen Ebenen anstreben und dabei Redundanzen produzieren, die Kapazitäten binden und somit die Weiterentwicklung des Produkts verlangsamen. Oder wenn wir als UX-Designer im Sinne eines optimalen Nutzererlebnisses in unseren Entwürfen die technische Machbarkeit nicht berücksichtigen und so die Entwicklung verteuern. Oder wenn wir als Fachbereich ein Feature beauftragen, das kein Anwender braucht. Aus dem Design Thinking kennen wir die gleichberechtigte Einbeziehung der Dimensionen Mensch, Technologie und Wirtschaft. Innovation findet in der Schnittmenge dieser Dimensionen statt (Abb. 5) und ist immer ein Kompromiss.

Abb. 5: Design-Thinking-Dimensionen
Systemisches Denken geht noch weiter und versucht, Kontexte ganzheitlich zu betrachten. Dabei werden Wechselbeziehungen zwischen Elementen eines Systems erfasst und in einem Systemmodell beschrieben. Durch die Beschreibung schaffen wir natürlich keine exakte Abbildung der Realität, aber eine gute Basis für Verständnis und Dialog. Abbildung 6 zeigt eine Näherung zum Zusammenhang zwischen kognitiver Last und Lieferergebnis. Kognitive Last beschreibt das Ausmaß mentaler Ressourcen, die zur Bearbeitung eines Systems aufgewendet werden müssen. Besonders in der Wissensarbeit ist das ein wichtiger Faktor.

Abb. 6: Systemisches Modell zur kognitiven Last
Ein Beispiel: Unser DevOps-Team kümmert sich neben der Entwicklung um die Bereitstellung des Produkts mittels einer Kubernetes Runtime. Das erhöht die kognitive Grundlast. Je mehr Fachlichkeit und Features von einem Team verarbeitet werden müssen, umso höher wird die kognitive Last. Je höher die kognitive Last, umso niedriger das Lieferergebnis. Je niedriger das Lieferergebnis, umso mehr parallele Arbeit wird gestartet. Eine eskalierende Schleife kommt in Gang, bei der das Lieferergebnis weiter sinkt. Zur Linderung wird der Automationsgrad der Tests erhöht. Das senkt einerseits die kognitive Last und erhöht sie andererseits dadurch, dass die Tests erstellt und gewartet werden müssen. Die Einführung von Frameworks kann den gleichen Effekt haben. Wir sehen an diesem Beispiel, wie eine systemische Sichtweise es uns ermöglicht, komplexe Zusammenhänge besser zu erfassen und zu diskutieren. Systemische Sichtweisen helfen uns ebenfalls, Wechselwirkungen von Polykrisen in den Blick zu nehmen und besser zu verstehen.
Systemische Ansätze werden für die digitale Produktentwicklung wichtiger. Innovation und Experimente in produktiven Umgebungen erfordern es, Risiken realistisch unter Einbeziehung vieler Einflussfaktoren einzuschätzen und auf dieser Basis schnelle Lieferstrategien zu entwickeln und Lernschleifen zu ermöglichen.
Wie es scheint, wird die Welt nicht einfacher werden. VUCA wird bleiben. Der Begriff Agile wird in Zukunft vermutlich eine weniger zentrale Rolle spielen, nicht zuletzt, weil das der Logik aller Industrietrends entspricht. Aufgrund der zunehmenden Komplexität und Unsicherheiten ist das Thema aber relevanter denn je. Es geht um Innovationsfähigkeit und die Fähigkeit zu schneller Veränderung. Die agile Community hat eine Vielzahl starker Techniken hervorgebracht, die uns helfen können, dabei besser zu werden. Insgesamt dürfte das Thema die Organisationsentwicklung also weiterhin maßgeblich beeinflussen. Das sind natürlich Thesen. Wird es wirklich so kommen? Wir wissen es nicht, die Welt ist komplex. Jedoch ist die Wahrscheinlichkeit hoch, das agiles Arbeiten in Zukunft noch wichtiger werden wird, da es uns hilft, mit den Herausforderungen der Zukunft konstruktiv umzugehen. Vermutlich noch weit über die IT hinaus.
Anmerkung Aus Gründen der besseren Lesbarkeit wird auf die gleichzeitige Verwendung der männlichen und weiblichen Sprachform verzichtet. Sämtliche Personenbezeichnungen gelten gleichermaßen für alle Geschlechter.
Links & Literature
[1] Agiles Manifest: https://agilemanifesto.org
[2] Studie Status Quo Agile 2020 – Hochschule Koblenz: https://www.hs-koblenz.de/bpm-labor/status-quo-scaled-agile-2020
[3] LeSS: https://less.works
[4] Scrum@Scale: https://www.scrumatscale.com
[5] SAFe: https://www.scaledagileframework.com
[6] Nexus: https://www.scrum.org/resources/nexus-guide
[7] Spotify Modell: https://blog.crisp.se/tag/spotify
[8] Spotify doesn’t use the Spotify Model: https://www.jeremiahlee.com/posts/failed-squad-goals/
[9] 15th State of Agile Report: https://digital.ai/resource-center/analyst-reports/state-of-agile-report
[10] 2021 Business Agility Report: https://businessagility.institute/learn/2021-business-agility-report-rising-to-the-challenge/669
[11] Pleus, Wolfgang: „Agile Kultur. Teil 1: Einführung“; in: Windows Developer 1.2021; „Agile Kultur. Teil 2: Veränderung“; in: Windows Developer 2.2021
[12] Barber, Herbert: „Developing Strategic Leadership: The US Army War College Experience“, Journal of Management Development, Band 11, Nr. 6, 1992
[13] Modern Agile: https://modernagile.org
[14] Clean Code: https://clean-code-developer.de
[15] Global Innovation Index 2021: https://www.globalinnovationindex.org
[16] Liberating Structures: https://www.liberatingstructures.com
[17] Sense & Respond: https://senseandrespond.co
[18] Soziokratie: https://sociocracy30.org
[19] Digital Riser Report 2021: https://digital-competitiveness.eu/digitalriser/
The post Agile: Wohin des Weges? appeared first on Entwickler Konferenz.
]]>The post Interview with Marco Cantu appeared first on Entwickler Konferenz.
]]>Marco Cantu: Over more than 25 years Delphi was and remains an excellent choice to learn programming, due to its easier syntax compared to curly brace languages and the fact it allows progressing from procedural programming to the world of object orientation, while other popular languages only offer an OOP paradigm. For learning, Python has grown a lot with great merit, but the ability to easily build a local Windows application with full fledged UI in Delphi remains unparalleled for a beginner. The landscape changed a lot and there are more nice programming languages to pick, but Delphi has also improved considerably with generic programming, dynamic constructs, anonymous methods and is continuously evolving over type, while retaining a high degree of compatibility with the billions of lines of existing code written with it.
Entwickler Konferenz: And of course are there any breaking changes or what are the most noticeable changes in Delphi 11?
Marco Cantu: The biggest changes in Delphi 11 relate with the development environment itself, given we made the move to using High DPI support in the IDE. This is not only a cosmetic type of chance offering crisp font text in the editor and high resolution icons, but also a big functional change because now you can design your VCL (and FireMonkey) applications directly at High DPI. This is a big change to the designer, along with the ability to preview VCL styles at design time, another big feature introduced in this release. Alongside, we updated the Welcome page getting rid of the HTML surface we used to display it. There is more in Delphi 111, from VCL extensions to a lot of quality improvements, but the IDE is cearly the focus of the new release.
Entwickler Konferenz: How can Project Reunion help to better interact Microsoft Tech with Delphi?
Marco Cantu: Delphi has been following the changes in the MIcrosoft development model for Windows for a long time. It has been the first third-party dev tool to offer full support for invoking WinRT APIs (at least the subset available to native applications) and the first IDE to integrate APPX support for Microsoft store deployment. We have continued along these lines offering MSIX packaging from the IDE and we already have a specific component wrapping the WebView 2 control (that is. the version of Edge based on Chromium). MSIX and WebView2 are two of the subsystems part of Project Reunion (now called Windows App SDK) we have been supporting since the last release. We are also expanding our WinRT API coverage and looking forward to being able to call all of the APIs (including WinUI 3 user interface controls) from within a native non-packaged application. As the Windows App SDK is still under development, we are closing monitoring and supporting its features as they become available.
The entire story around the Windows App SDK is very important for us. Microsoft long ago promoted the idea that the native Windows API was dead and moving to .NET was becoming a requirement, scaring some of our customers. Later they went on implying that the Unified Windows Platform (UWP) was the only viable futures, but then they started allowing integration with the so-called Desktop Bridge (originally intended as a migration path) and now they are saying native non-packages applications (the current name for native WinAPI apps) are first class citizen applications with access to the entire platform API. In other words, after saying for 15 years that the Delphi (and Visual C++ and other tools) underlying model and structure was old, they are now saying it is a great way to go for the future. This is great news for Delphi, given we have kept improving the tool and in particular the VCL library, which is by far the best Windows desktop UI library — we have kept focusing on it while Microsoft created and deprecated at least 5 other Windows UI libraries in the same time.
Entwickler Konferenz: Delphi adopted some features from Project Reunion, did it also adopt features from other platforms?
Marco Cantu: While Windows remains our primary target and working with the new APIs offered by the platforms is a top priority for us, we do the same across the spectrum of platforms we support. In this release of Delphi we offer macOS ARM-64 native support, targeting Apple M1 CPUs, alongside with Intel 64-bit targets and deployment of Universal platform binaries. We currently support the official platform application stores for Windows, macOS, iOS and Android, and each of them requires staying current with API usage, a reason we keep moving to newer libraries for mobile platforms. In terms of the Windows platform, along the classic VCL library we also offer our multi-device FireMonkey library which lets you target with the same exact source code Windows, macOS, iOS, Android and even native Linux UI, with the ability to customize the UI for each platform in the designer but reply on shared source code for all targets. Doing this without losing the native compilation and native platform integration is pretty unique these days.
Entwickler Konferenz: What advantages does Delphi have compared to Microsoft’s own compiler?
Marco Cantu: In terms of compilers we offer a different language than Microsoft, so it is hard to draw a direct comparison. While we also offer a C++ language solution companion to Delphi, C++Builder, the Delphi language offers advantages in terms of readability and simplicity, and is a much nicer language to start with. Compared to C#, one of the other main options from Microsoft, the advantage is having native code fast to execute and not requiring a runtime. With Delphi compiler code we have true xcopy deployment across most existing versions of Windows, with no runtime dependencies whatsoever. Also the code is fast and predictable in terms of response time, which is why Delphi is currently used a lot in industrial automation projects, where C# and java pose challenges in terms of predictability.
Entwickler Konferenz: In which direction do you think will Delphi develop in the future?
Marco Cantu: We are keen to keep Delphi a top tool for Windows client development, but also will keep offering multi-platform solutions and server side capabilities for Windows and Linux. Project Reunion offers us a unique opportunity to integrate all of the APIs and libraries Microsoft ships for the platform, unlike what happened over the last 15 or 20 years, and we are ready to support it in full. Desktop development tools have been challenged by JavaScript and HTML-based solutions, unifying web and client development, and we have seen huge small utilities consuming an insane amount of CPU and memory, not to mention hard disk space (and download bandwidth). When I see a chat client using asn many system resources as a development tool and compiler, as a user I’m unhappy. The technical advantage offered by a native solution (from us or Microsoft) is very significant, so I’m convinced that many will decide not to go that route or get back to native desktop solutions in the future.
The post Interview with Marco Cantu appeared first on Entwickler Konferenz.
]]>The post “Firestore/Firebase stellt eine sehr gute Lösung dar, um schnell und einfach eine globale User-Authentifizierung aufzubauen” appeared first on Entwickler Konferenz.
]]>Christoph Schneider: Firestore ist eine moderne NoSQL Cloud-Datenbank, die als einen von mehreren Services unter dem Namen Firebase von Google betrieben wird. Im Gegensatz zu anderen Cloud-Datenbanken können die Services von Firebase nicht auf eigenen Servern betrieben werden, sondern man setzt auf die Dienste von Google. Ab ab einem Datenvolumen von mehr als 1 GB oder bei mehr als 20.000 Schreibzugriffen oder 50.000 Lesezugriffen pro Tag muss man für die Nutzung von Firestore zahlen. Bis zu dieser Begrenzung können Datenbank-Projekte nach heutigem Stand kostenlos betrieben werden.
Frage: Wo liegt die größte Hürde für Umsteiger, die bereits andere Arten von Datenbanken genutzt haben?
Schneider: Der Umstieg von einer SQL Client/Server-Datenbank auf eine NoSQL Cloud Datenbank ist für Entwickler ein großer Schritt, denn die Daten müssen nach anderen Kriterien strukturiert werden. Auch können in Firestore wichtige Konzepte der relationalen Datenbanken, zum Beispiel Abfragen über mehrere Tabellen oder auch Transaction, nur noch begrenzt verwendet werden.
Während bei relationale Datenbanken galt, Redundanzen in den gespeicherten Daten durch einen geschickten Tabellenentwurf möglichst zu vermeiden, gilt es beim Einsatz von Firestore die Anzahl der Abfragen von Dokumente und die Größe der Dokumente möglichst zu minimieren. Generell eignet sich dieser Datenbanktyp eher für Anwendungen, wo viele Anwender lesend und nur wenige schreibend zugreifen.
Der Umstieg von einer SQL Client/Server-Datenbank auf eine NoSQL Cloud Datenbank ist für Entwickler ein großer Schritt
Frage: Mit FB4D hast du ja eine eigene Library für den Einsatz von Firebase mit Delphi geschrieben. Welche Plattformen unterstützt du damit?
Schneider: Während Google für diese Datenbank Mobil- und Webanwendungen im Fokus hat und mit diversen Plattform-SDKs bestens unterstützt, ist es mit der von mir entwickelten OpenSource-Library FB4D für Delphi-Entwickler möglich, auch von Desktop oder Server-Anwendungen auf diese Cloud-Datenbank zuzugreifen. Dabei kann FB4D sowohl in FMX- als auch in VCL-Applikationen zum Einsatz kommen. FB4D ist bei Verwendung des Firemonkey-Frameworks für alle heute unterstützen Plattformen (OSX, iOS, Android, Linux und Windows) vorbereitet.
Frage: Wem würdest du empfehlen, einen Blick auf FB4D zu werfen; für welche Arten von Projekten ist die Library geeignet?
Schneider: Natürlich muss man sich bei jedem neuen Technologie-Einsatz über die damit verbunden Abhängigkeiten zu den involvierten Dienstleistern Gedanken machen. Bei aktuell weltweit über 1.5 Million Mobile-Applikationen, hergestellt von mehr als 36.000 Firmen, ist Firebase ein wichtiger und verlässlicher Player im Cloud-Plattform-Markt.
Für mich stellt Firestore/Firebase eine sehr gute Lösung dar, um schnell und einfach eine globale User-Authentifizierung aufzubauen und damit den autorisierten Zugriff auf strukturierte Daten via Cloud Firestore oder auch ganzer Dateien via Cloud-Storage zu transferieren oder zwischen Applikation zu synchronisieren. Durch die weitere Möglichkeit, serverseitige Firebase-Funktionen aus Applikationen zu starten, die auf alle Services zugreifen können, wie bspw. Machine Learning für die Bildbearbeitung/Bildinterpretation und Spracherkennung, sind sehr unterschiedliche Anwendungen entwickelbar.
Wenn ich zwischen Ausbau und Stabilisierung wählen müsste, hätte für mich letzteres klar Priorität.
Frage: Was würdest du dir für die Zukunft von Delphi wünschen?
Schneider: Ich wünsche mir für die Zukunft mehr Stabilität im Firemonkey-Framework. Es gibt auch für FB4D einige Einsatzorte, wie beispielsweise Linux-64, wo aktuell noch selbstgebaute Patches verwendet werden müssen, damit FB4D korrekt läuft. Andererseits freue ich mich natürlich auch über die Unterstützung von weiteren Plattformen (ARM-CPU OSX/Windows). Wenn ich aber zwischen Ausbau und Stabilisierung wählen müsste, hätte für mich letzteres klar Priorität.
Danke für das Gespräch!
Die Fragen stellte Ann-Cathrin Klose.
The post “Firestore/Firebase stellt eine sehr gute Lösung dar, um schnell und einfach eine globale User-Authentifizierung aufzubauen” appeared first on Entwickler Konferenz.
]]>The post Machine Learning mit CAI appeared first on Entwickler Konferenz.
]]>CAI NEURAL API ist ein Pascal-basiertes neuronales Netzwerk-API, das für AVX-, AVX2 und AVX512-Befehlssätze sowie OpenCL-fähige Geräte wie AMD, Intel und NVIDIA für GPU-Funktionen optimiert ist. Das API wurde unter Windows und Linux getestet. Im Februar 2020 erhielten wir noch Delphi-Unterstützung für OpenCL und Threads. Dieses Projekt und das API sind ein Teilprojekt eines größeren und älteren Projekts namens CAI und seiner Schwester, das Keras/TensorFlow-basierte K-CAI NEURAL-API.
Die Bilderkennung hat in vielen Bereichen der Bildverarbeitung einen raschen revolutionären Wandel erlebt. (Abb. 1). Sein Anteil an der Kombination von Objektklassifizierung und Objekterkennung macht es zu einem der herausforderndsten Themen im Bereich des maschinellen Lernens.

Am Anfang steht die CAI-Bibliothek mit Modulen. Neural-API ist eine Pascal-Bibliothek, mit der man Systeme mit eigenständigen Deep-Learning- und Computer-Vision-Funktionen mit wenigen Zeilen kompakten Code erstellen und ausführen kann. Sie benötigen eine Lazarus- oder Delphi-Entwicklungsumgebung. Wenn Sie ein OpenCL-fähiges Gerät haben, benötigen Sie auch dessen OpenCL-GPU-Treiber. Um CAI zuerst zu verwenden, müssen jedoch einige Abhängigkeiten installiert werden, nämlich:
Nach der Installation von CAI ist eine einfache Dokumentation in einer Readme-Datei vorhanden. In Bezug auf Delphi werden einige Units mit Delphi kompiliert und Sie können mit Delphi – in meinem Fall mit der Community Edition 10.3 – neuronale Netze erstellen und ausführen (siehe Abb. 1 unten). Für Keras und Tensorflow ist auch ein git clone vorhanden.
Eine andere faszinierende Möglichkeit besteht darin, das gesamte System als Runtime-Virtualisierung mit Hilfe eines Jupyter-Notebooks, das unter Ubuntu in der Cloud ausgeführt wird, auf Google Colab oder Colab.research-Container auszuführen. Eingeschlossen ist der Build von Free Pascal mit Lazarus, wie man unter folgendem Link nachvollziehen kann: https://github.com/maxkleiner/maXbox/blob/master/EKON24_SimpleImageClassificationCPU.ipynb
!apt-get install fpc fpc-source lazarus git subversion
Jupyter ist ein Spin-off-Projekt von IPython, das darauf abzielt, interaktives Computing in allen Programmiersprachen zu standardisieren. Der Kernel bietet eine interaktive Umgebung, in der Benutzercode im Server ausgeführt wird, der mit einem Frontend-Through-Socket verbunden ist. Das Framework wie auch CAI ist Open Source. Es lässt sich unter den Bedingungen der GNU General Public License und der Free Software Foundation weitergeben und/oder ändern.
Als nächstes lade ich die CIFAR-Modelldatei (162 MB) herunter, die fünf Volumes als Verzeichnisse für das Klassifizierungsmodell enthält, das für das Objekttraining und die Objekterkennung verwendet wird.
Der CIFAR-10-Datensatz besteht aus 60000 32×32-Farbbildern in 10 Klassen mit 6000 Bildern pro Klasse. Es gibt 50000 Trainingsbilder und 10000 Testbilder. Der Datensatz ist in fünf Trainingsstapel (data_batch_1.bin – _5.bin) und einen Teststapel mit jeweils 10000 Bildern unterteilt. Der Teststapel enthält genau 1000 zufällig ausgewählte Bilder aus jeder Klasse. Die Trainingsstapel enthalten die verbleibenden Bilder in zufälliger Reihenfolge, aber einige Trainingsstapel enthalten möglicherweise mehr Bilder aus einer Klasse als aus einer anderen. Dazwischen enthalten die Trainingsstapel genau 5000 Bilder aus jeder Klasse.
Die Klassen schließen sich vollständig gegenseitig aus. Es gibt keine Überlappung zwischen Autos und Lastwagen oder Katze und Hund, man sagt auch die Klassen sind disjunkt. Die Klassen sind:
classes=(‘plane’,’car’,’bird’,’cat’,
‘deer’,’dog’,’frog’,’horse’,’ship’,’truck’)
Diese Ergebnisse resultieren aus einem Convolution-Netzwerk. Kurz gesagt, es sind 18% als Testfehler zu erkennen. Ein einzelnes Bild hat bewusst eine niedrige Auflösung zum Trainieren der Merkmalsträger (Features) (Abb. 2).

Nach dem Einrichten der Units und dem Beziehen der Bilddaten öffne ich den Code-Editor meiner Wahl (in meinem Fall maXbox, Jupyter Notebook und Delphi Community Edition) und lade die Dateibeispiele SimpleImageClassifier.lpi oder in Delphi die Datei SimpleImageClassifier_CPU_Cifar.pas (Abb. 3).

Dieses Beispiel enthält interessante Aspekte: Der Quellcode ist klein und die Ebenen werden als Layer nacheinander hinzugefügt. Anschließend lassen sich die Trainingshyperparameter definieren, bevor die Fit-Methode aufgerufen wird. Sie benötigen fit(), um das Modell zu trainieren! In Zeile 155 beginne ich mit der Testklasse aus der CAI-Bibliothek und erstelle auch die ersten neuronalen Schichten als Modelldefinition:
procedure TTestCifar10Algo;
var
NN: TNNet;
NeuralFit: TNeuralImageFit;
ImgTrainingVolumes, ImgValidationVolumes, ImgTestVolumes: TNNetVolumeList;
NumClasses: integer;
fLearningRate, fInertia: single;
begin
//This is how a sequential CNN array of layers is added:
NN:= TNNet.Create();
NumClasses:= 10;
fLearningRate:= 0.001;
fInertia:= 0.9;
NN.AddLayer(TNNetInput.Create(32, 32, 3)); //32x32x3 Input Image
NN.AddLayer(TNNetConvolutionReLU.Create({Features=}16, {FeatureSize=}5, {Padding=}0, {Stride=}1, {SuppressBias=}0));
NN.AddLayer(TNNetMaxPool.Create({Size=}2));
NN.AddLayer(TNNetConvolutionReLU.Create(32, 5, 0, {Stride=}1, 0));
NN.AddLayer(TNNetMaxPool.Create({Size=}2));
NN.AddLayer(TNNetConvolutionReLU.Create(32, 5, 0, {Stride=}1, 0));
NN.AddLayer(TNNetLayerFullConnectReLU.Create({Neurons=}32));
NN.AddLayer(TNNetFullConnectLinear.Create(NumClasses));
NN.AddLayer(TNNetSoftMax.Create());
writeln(NN.SaveDataToString);
//readln;
Dann lade ich die Datensets für das Training. Es gibt einen Trick, den Sie mit diesem API oder einem anderen API ausführen können, wenn Sie mit der Bildklassifizierung arbeiten: Sie können die Größe des Eingabebilds erhöhen. Gemäß dem folgenden Beispiel (Trainieren, Testen und Validieren) können Sie durch Erhöhen der CIFAR-10-Eingabebildgröße von 32 x 32 auf 48 x 48 die Klassifizierungsgenauigkeit um bis zu 2% steigern.
CreateCifar10Volumes(ImgTrainingVolumes, ImgValidationVolumes, ImgTestVolumes);
WriteLn
(
‘Training Images:’, ImgTrainingVolumes.Count,
‘ Validation Images:’, ImgValidationVolumes.Count,
‘ Test Images:’, ImgTestVolumes.Count
); //*)
WriteLn(‘Neural Network will minimize error with:’);
WriteLn(‘ Layers: ‘, NN.CountLayers());
WriteLn(‘ Neurons: ‘, NN.CountNeurons());
WriteLn(‘ Weights: ‘, NN.CountWeights());
writeln(‘Start Convolution Net…’);
readln;
Als Ausgabe auf der Shell sieht man, dass das Neuronale Netzwerk Fehler mit Hilfe einer Loss-Funktion und der Lernrate minimiert:
Layers: 9
Neurons: 122
Weights: 40944
Start Convolution Net…
NeuralFit:= TNeuralImageFit.Create;
//readln;
NeuralFit.FileNameBase:= ‘EKONSimpleImageClassifier2’;
NeuralFit.InitialLearningRate:= fLearningRate;
NeuralFit.Inertia:= fInertia;
NeuralFit.LearningRateDecay:= 0.005;
NeuralFit.StaircaseEpochs:= 17;
// NeuralFit.Inertia := 0.9;
NeuralFit.L2Decay:= 0.00001;
// best fit: batch 128 epochs 100
// just for test and evaluate the process – epochs = 1, otherwise 10 or 100!
NeuralFit.Fit(NN, ImgTrainingVolumes, ImgValidationVolumes, ImgTestVolumes, NumClasses, {batchsize}128, {epochs}1);
writeln(‘End Convolution Net…’);
readln;
NeuralFit.Free;
NN.Free;
ImgTestVolumes.Free;
ImgValidationVolumes.Free;
ImgTrainingVolumes.Free;
end;
Die Lernrate in NeuralFit.InitialLearningRate:= fLearningRate; ist ein wichtiger Hyperparameter, der steuert, wie stark der Algorithmus die Gewichte und Verbindungen im Netzwerk entsprechend dem Gradienten anpassen soll.
Wie in einem Gradienten Histogramm (HOG) handelt es sich im Grunde genommen um einen Merkmalsdeskriptor, der zum Erkennen von Objekten in der Bildverarbeitung und anderen Computer-Vision-Techniken verwendet wird. Das erzeugte Histogramm der Deskriptoren umfasst das Auftreten von Gradientenorientierung in lokalisierten Teilen eines Bildes, wie z.B. Erfassungsfenster, Region of Interest (ROI), Frames und andere. Der Vorteil von HOG-ähnlichen Funktionen liegt in ihrer Einfachheit und dem leichteren Verständnis der darin enthaltenen und gefundenen Information.

Im letzten Schritt sehen wir die Bilderkennung, die sich auf Menschen oder Personen spezialisiert hat. Überraschenderweise werden nach einem Bild (Die Nachtwache, Delft, Abb. 5) die Personen im Hintergrund eher erkannt als die reale Person im Vordergrund. Das hat mit dem Bildausschnitt im Sinne der Fokussierung des Rechtecks zu tun, da jeweils eine ganze Person trainiert wurde.
person : 11.248066276311874
person : 14.372693002223969
person : 19.247493147850037
person : 34.878602623939514
person : 77.2484838962555
image detector compute ends…
#loads model from path specified above using the setModelPath() class method.
detector.loadModel()

Wie lassen sich also die Validierungszeiten verkürzen? Mit einem vortrainierten Modell! Vorgefertigte Modelle sind eine wunderbare Hilfe für Entwickler und Entscheider, die einen Algorithmus erlernen oder ein vorhandenes Framework online oder offline ausprobieren möchten. Die Vorhersagen, die mit vorab trainierten Modellen getroffen wurden, wären jedoch nicht so effektiv, als wenn Sie das Modell mit Ihren eigenen Daten trainieren. Das ist der Kompromiss. Aus zeitlichen oder rechnerischen Gründen ist es nicht immer möglich, ein Modell von Grund auf neu zu erstellen (wie wir es getan haben), weshalb es vortrainierte Modelle wie das pretrained-yolov3.h5 und viele aus dem ImageNet gibt. Wer das beschriebene Beispiel nachvollziehen möchte, findet unter softwareschule.ch, sourceforge.net und sourceforge.net das Skript und die verwendeten Daten.
The post Machine Learning mit CAI appeared first on Entwickler Konferenz.
]]>The post “Delphi development is still going strong” appeared first on Entwickler Konferenz.
]]>Beside Windows, Embarcadero keeps focusing on creating a great multi-device experience with FireMonkey. FireMonkey is the only native compiled framework with single source applications for desktop and mobile.
Finally, we have been pushing our more recent multi-tier REST-based architecture, RAD Server, which wants to bring easy and fast development for web services. All of these solutions let developers reuse a lot of existing code if they’ve used Delphi in the past.
JAXenter: At EKON 22, you will give a session entitled “The Delphi Language Evolution“. Indeed, the landscape is in motion with themes such as Cloud, Mobile, IoT, Container, Machine Learning, etc. Which topics are currently the focus of the Delphi community?
Marco Cantu: The focus of this session is on the core language and its modernization. We are very happy with the overall features and power of the language. However, there are many areas which can be improved and we want to focus on that. While these features are not strictly related with the industry trends, they help reinforce Delphi position as a compiled and efficient language suitable for all modern needs.
Deep platform integration helps with Mobile and IoT. For IoT, we have extensive support for core connectivity and even ready to use IoT components. Native mobile helps performance and battery usage. But energy saving (or CPU cycles saving) is also becoming important for cloud architectures, so again compiled code has advantages.
JAXenter: From your point of view, are there any topics that should be covered even more in the future? Where is there still some catching up to do?
Marco Cantu: There are certainly many areas Delphi developers are just starting to tackle. Given many are focused on legacy existing large business apps (critical to keep many companies running) the adoption of new technologies like, say, blockchain or machine learning is a bit slower compared to other environments. But we are seeing many new libraries in these areas, and this is promising. We are very happy when we see our developers community help pushing the product in new directions.
JAXenter: In your keynote, you will present the development of REST and JSON web services with the RAD server. This also includes new web and JavaScript features. Can you give us an example?
Marco Cantu: How to best build a web application is a topic we could spend months debating. We could probably never reach consensus on what’s the best approach. Also, the JavaScript space is continually reinventing itself in terms of libraries.
Personally, I don’t believe Delphi should be used for building web UIs. There are many nice and clean technologies based on HTML, CSS, and JavaScript which get the job done nicely. I know some developers like using a single tool and not having to learn new ones, so I’m happy we have third party vendors offering integrated solutions.
For me, the best approach (for larger, public applications, at least) is to have a solid REST and JSON based backend, like RAD Server offers, and couple it with a JavaScript app. There are many alternatives there, from Angular to React to Vue. However, I’m likely going to demo the use of ExtJS, given our company owns this solid and stable JavaScript framework!
JAXenter: Another of your sessions is called “Building and Deploying Delphi Applications to Platform Stores”. What is your core message here?
Marco Cantu: The key concepts is App Stores have changed the way developers distribute and sell applications. They have also changed the way developers make money out of their work. This has been revolutionary for the mobile space. Microsoft is now trying to push and promote the same concept for Windows 10, something obvious if you consider the Windows 10 S release.
Delphi has integrated support in the IDE for building the artifacts and deployment files needed for iOS and Android mobile stores and for Windows Store, using the desktop bridge. I have personally deployed a few apps to these stores. This session would also focus on my personal experience and some gotchas with the process.
Thank you!
The post “Delphi development is still going strong” appeared first on Entwickler Konferenz.
]]>