<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Workshop Archives - Mobile USTP MKL</title>
	<atom:link href="https://mobile.fhstp.ac.at/category/workshop/feed/" rel="self" type="application/rss+xml" />
	<link>https://mobile.fhstp.ac.at/category/workshop/</link>
	<description>Die &#34;Mobile Forschungsgruppe&#34; der USTP, sie  sammelt hier alles zu den Themen Design, UX und Entwicklung mobiler Applikationen</description>
	<lastBuildDate>Mon, 23 Feb 2026 21:32:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://mobile.fhstp.ac.at/wp-content/uploads/2025/03/icon-120x120.webp</url>
	<title>Workshop Archives - Mobile USTP MKL</title>
	<link>https://mobile.fhstp.ac.at/category/workshop/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Workshop &#124; Astro</title>
		<link>https://mobile.fhstp.ac.at/workshop/workshop-astro/</link>
		
		<dc:creator><![CDATA[Caroline Labres]]></dc:creator>
		<pubDate>Sun, 16 Nov 2025 17:20:52 +0000</pubDate>
				<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[Astro]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15111</guid>

					<description><![CDATA[<p>Im 3. Semester habe ich einen Workshop zu Astro gehalten. Dabei habe ich erklärt, was das Webframework ausmacht, und anhand von einem praktischen Beispiel die wichtigsten Kernfunktionen demonstriert. Was ist Astro? Astro ist ein Framework für contentfokussierte Webprojekte, wie z.B. Blogs, E-Commerce- oder Marketing-Websites. Es setzt auf eine komponentenbasierte Web-Architektur, was bedeutet, dass das meiste <a class="read-more" href="https://mobile.fhstp.ac.at/workshop/workshop-astro/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-astro/">Workshop | Astro</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Im 3. Semester habe ich einen Workshop zu Astro gehalten. Dabei habe ich erklärt, was das Webframework ausmacht, und anhand von einem praktischen Beispiel die wichtigsten Kernfunktionen demonstriert.</p>



<h2 class="wp-block-heading">Was ist Astro?</h2>



<p>Astro ist ein Framework für contentfokussierte Webprojekte, wie z.B. Blogs, E-Commerce- oder Marketing-Websites. Es setzt auf eine <strong>komponentenbasierte Web-Architektur</strong>, was bedeutet, dass das meiste als statische HTML-Seite gerendert wird und man kleine Islands mit JavaScript für Interaktivität hinzufügen kann. Astro verfolgt einen <strong>Server-first-Ansatz</strong> und kommt standardmäßig <strong>ohne JavaScript</strong> am Client aus, liefert aber bei Bedarf <strong>Unterstützung für Frameworks</strong> wie React, Vue, Svelte, Solid etc. Darüber hinaus bietet Astro <strong>Content Collections</strong>, mit denen sich Markdown-Inhalte strukturiert organisieren und mithilfe von TypeScript typsicher validieren lassen.</p>



<h2 class="wp-block-heading">Projekt erstellen</h2>



<p><code>npm create astro@latest</code> (basic, helpful starter Projekt auswählen)</p>



<p>In VS Code gibt es eine Extension namens Astro, die hilfreich ist.</p>



<p> Ordnerstruktur (als Beispiel):</p>



<ul class="wp-block-list">
<li>assets</li>



<li>components</li>



<li>content (für Content Collections)</li>



<li>layouts</li>



<li>pages (file-based Routing)</li>



<li>styles</li>
</ul>



<h2 class="wp-block-heading">Dateiaufbau und Astro-Komponenten</h2>



<ul class="wp-block-list">
<li>Dateiendung: .astro</li>



<li>Codeausführung:
<ul class="wp-block-list">
<li>serverseitig: <code>--- ---</code> (Frontmatter)</li>



<li>clientseitig: <code>&lt;script>&lt;/script></code></li>
</ul>
</li>



<li>JSX-ähnliche Ausdrücke
<ul class="wp-block-list">
<li><code>{variable}</code> in HTML</li>



<li>Aber: Funktionen und Objekte können so nicht übergeben werden (wie z.B. bei React), stattdessen mit Script-Tag umsetzbar</li>
</ul>
</li>
</ul>



<p>Beispielsweise MyAstroComp.astro:</p>



<pre class="wp-block-code"><code>---
// Script mit JS, das am Server ausgeführt wird
const text = "Hello World";
---
&lt;!-- Hier Template der Komponente mit HTML, CSS und JS --&gt;
&lt;div&gt;{text}&lt;/div&gt;</code></pre>



<p>Was nicht funktioniert:</p>



<pre class="wp-block-code"><code>---
function handleClick() {
  console.log("clicked");
}
---
&lt;button onclick="handleClick()"&gt;{text}&lt;/button&gt;</code></pre>



<p>Komponente in index.astro verwenden:</p>



<pre class="wp-block-code"><code>---
import MyAstroComp from "../components/MyAstroComp.astro";
---
&lt;MyAstroComp /&gt;</code></pre>



<ul class="wp-block-list">
<li><code>&lt;slot /></code> für Children (wie {children} in React)</li>



<li>Mit <code>Astro.props</code> auf Properties zugreifen</li>
</ul>



<pre class="wp-block-code"><code>---
interface Props {
  name: string;
}
const { name } = Astro.props;
---
&lt;h2&gt;Hello {name}!&lt;/h2&gt;</code></pre>



<h2 class="wp-block-heading">Unterschiede Astro vs. JSX</h2>



<figure class="wp-block-table"><table class="has-black-color has-text-color has-link-color has-fixed-layout"><thead><tr><th></th><th>Astro</th><th>JSX</th></tr></thead><tbody><tr><td>Attribute</td><td>kebab-case</td><td>camelCase</td></tr><tr><td>Mehrere Elemente</td><td>Ohne Parent zulässig</td><td>Nur in einem einzelnen &lt;div&gt; oder &lt;&gt; zulässig</td></tr><tr><td>Kommentare</td><td>HTML- und JS-Kommentare</td><td>JS-Kommentare</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">React hinzufügen</h2>



<p>Interaktivität in Astro Komponenten einzubauen ist mühsam. Um mit einem Buttonklick umgehen zu können, müsste man ein &lt;script&gt; Tag hinzufügen. Stattdessen kann man aber auch ein beliebiges anderes Framework zum Projekt hinzufügen und so auch beispielsweise React-Komponenten bauen und nutzen.</p>



<p>Um React als Beispiel hinzuzufügen: <code>npx astro add react</code></p>



<p>Achtung: Komponente wird by default nur am Server gerendert!</p>



<p>Für Interaktivität braucht es Hydration und eine Client Directive.</p>



<h3 class="wp-block-heading">Client Directives</h3>



<p>Die client:* Directive gibt an, wann das JavaScript an den Browser geschickt werden soll. Die Komponente wird zuerst am Server gerendert (außer bei client:only), dann wird das JS gesendet und somit wird die Komponte hydrated und interaktiv.</p>



<ul class="wp-block-list">
<li><code>client: load</code>
<ul class="wp-block-list">
<li>JS: sofort beim Laden der Seite</li>
</ul>
</li>



<li><code>client: idle</code>
<ul class="wp-block-list">
<li>JS: nach initialem Ladeprozess und wenn requestIdleCallback-Event ausgelöst wird</li>
</ul>
</li>



<li><code>client: visible / client:visible={{rootMargin}}</code>
<ul class="wp-block-list">
<li>JS: sobald Komponente bzw. angegebener Margin sichtbar ist</li>
</ul>
</li>



<li><code>client:media={string}</code>
<ul class="wp-block-list">
<li>JS: wenn CSS media query erfüllt wird (z.B. nur für bestimmte Bildschirmgrößen)</li>
</ul>
</li>



<li><code>client:only={string}</code>
<ul class="wp-block-list">
<li>Überspringt SSR und rendert Komponente nur am Client. Framework muss als String übergeben werden.</li>
</ul>
</li>
</ul>



<p>Die Client Directive wird dort hinzufügt, wo die Komponente verwendet wird.</p>



<pre class="wp-block-code"><code>---
import MyReactButton from "../components/MyReactButton";
---
&lt;MyReactButton client:load /&gt;</code></pre>



<h2 class="wp-block-heading">Output Type für Build</h2>



<p>In der astro.config Datei kann der Output Type festgelegt werden. Dieser bestimmt, wann die Seiten standardmäßig gerendert werden (beim Builden oder on demand). Das gilt für alle Seiten, außer bei denen eine Ausnahme festgelegt ist.</p>



<p>In astro.config.mjs: <code>output: 'static'</code> oder <code>'server'</code></p>



<ul class="wp-block-list">
<li><code>static</code> (default): SSG, Seiten werden vorgerendert (<em>prerendered</em>); Ergebnis: statische Website</li>



<li><code>server</code>: SSR, Seiten werden on demand gerendert; Ergebnis: server-rendered Website</li>



<li>Für einzelne Seite ändern: <code>export const prerender = false</code>
<ul class="wp-block-list">
<li>wenn in config static: <code>false</code></li>



<li>wenn in config server: <code>true</code></li>
</ul>
</li>
</ul>



<p>Wichtig: Wenn eine Seite SSR verwendet, muss ein <strong>Server-Adapter</strong> (z.B. node) festgelegt werden: <code>npx astro add node</code></p>



<h2 class="wp-block-heading">Blog als Praxisbeispiel</h2>



<p>Als Beispiel wird ein kleiner, einfacher Blog programmiert. Dieser beinhaltet zwei Seiten, wobei auf einer alle Einträge mit Bild, Datum und Titel aufgelistet werden (Übersichtsseite) und auf der anderen die Informationen des jeweiligen Eintrags stehen (Detailseite). Die einzelnen Blogbeiträge sollen in Form von Markdown-Dateien erstellt, bearbeitet und verwaltet werden können. Auf das Styling wird bei diesem Beispiel nicht eingegangen.</p>



<h3 class="wp-block-heading">Content Collection erstellen</h3>



<p>Content Collections helfen dabei, Markdown-Dateien zu organisieren. Genau das wird für die Blogbeiträge benötigt. Um eine Collection zu erstellen, muss diese in src/content.config.ts definiert werden.</p>



<pre class="wp-block-code"><code>import { glob } from "astro/loaders";
import { defineCollection, z } from "astro:content";

const blog = defineCollection({
  loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
  schema: () =&gt;
    z.object({
      title: z.string(),
      date: z.coerce.date(),
      img: z.string(),
    }),
});

export const collections = { blog };</code></pre>



<p>Die Funktion <code>defineCollection()</code> verlangt dabei zwei Parameter, einerseits den Loader und andererseits optional das Schema. Der Loader legt fest, wie und von wo die Inhalte der Collection geladen werden. Astro stellt dabei zwei integrierte Varianten zur Verfügung:</p>



<ul class="wp-block-list">
<li><code>glob()</code>: erstellt Einträge aus Ordnern mit Dateien</li>



<li><code>file()</code>: erstellt Einträge basierend auf einer lokalen Datei (z.B. JSON-File)</li>
</ul>



<p>Das Schema wird mit zod erstellt. Wird ein Schema definiert, so werden die entsprechenden Markdown-Dateien dahingehend validiert. Außerdem können generierte Types verwendet werden (z.B. <code>type Props = CollectionEntry&lt;"blog"&gt;["data"];</code>). Wichtig ist nur, dass der Dev-Server neu gestartet wird, wenn sich Änderungen am Schema ergeben, sodass Astro das mitbekommt.</p>



<p>Ein Blogeintrag soll in diesem Fall immer einen Titel, ein Datum und ein Bild beinhalten, sodass diese Informationen auf der Übersichtsseite angezeigt und auf der Detailseite immer gleich formatiert werden können.</p>



<h3 class="wp-block-heading">Blogbeiträge hinzufügen</h3>



<p>Es können jetzt diverse Blogbeiträge in Form von Markdown-Dateien unter content/blog erstellt werden (Pfad in content.config.ts festgelegt).</p>



<p>Beispiel: first-entry.md</p>



<pre class="wp-block-code"><code>---
title: "First Entry"
date: "2025-10-30"
img: "/favicon.svg"
---
Hello, this is my first entry.

## H2

This is a paragraph.</code></pre>



<p>Im Frontmatter (innerhalb der drei Bindestriche) werden die drei Parameter angegeben, darunter folgt der Inhalt. Als Bild wird der Einfachheit halber das favicon im public-Ordner hergenommen. Der Blogbeitrag kann Überschriften, Absätze, Links, Codeteile, Tabellen und alles, was Markdown zu bieten hat, beinhalten. Wichtig ist nur, dass man das entsprechende Styling dafür definiert (h2, p, code, a etc.).</p>



<h4 class="wp-block-heading">MDX</h4>



<p>Es können nicht nur md-Dateien erstellt werden, sondern auch mdx-Dateien, in denen die eigenen Komponenten (egal ob Astro, React etc.) verwendet werden können. Es muss nur die entsprechende Astro-Integration installiert werden (<code>npx astro add mdx</code>) und mdx in der Definition der Content Collection berücksichtigt werden (wurde bereits getan).</p>



<p>Beispiel: second-entry.mdx</p>



<pre class="wp-block-code"><code>---
title: "Second Entry"
date: "2025-10-31"
img: "/favicon.svg"
---

This is my second entry.

import MyReactButton from "../../components/MyReactButton"

&lt;MyReactButton client:load /&gt;</code></pre>



<p>components/MyReactButton.tsx</p>



<pre class="wp-block-code"><code>export default function MyReactButton(){

    function handleClick(){
        console.log("Hello, you clicked me")
    }

    return (
        &lt;button onClick={handleClick}&gt;Click me&lt;/button&gt;
    )
}</code></pre>



<h3 class="wp-block-heading">Seiten erstellen</h3>



<p>Astro verwendet file-based Routing. Die Ordner- und Dateistruktur im pages-Ordner bestimmt somit automatisch, unter welchen URLs die Seiten aufgerufen werden können. Im pages-Ordner wird ein Unterordner blog und darin index.astro und [slug].astro angelegt. Der Blog ist somit unter /blog erreichbar. index.astro ist eine statische Route, während [slug].astro eine dynamische Route ist. Der Parameter slug kann dabei durch eine beliebige andere Bezeichnung ersetzt werden. Für mehr Tiefe kann auch ein Rest-Parameter verwendet werden: [&#8230;path].astro. </p>



<h4 class="wp-block-heading">Übersichtsseite</h4>



<p>Für die index Seite wird zuerst ein Layout erstellt. Ein Layout ist dabei nichts anderes als eine normale Astro-Komponente.</p>



<p>layouts/Layout.astro</p>



<pre class="wp-block-code"><code>---<br>import "../styles/global.css";<br>---<br><br>&lt;!doctype html&gt;<br>&lt;html lang="en"&gt;<br>  &lt;head&gt;<br>    &lt;meta charset="UTF-8" /&gt;<br>    &lt;meta name="viewport" content="width=device-width" /&gt;<br>    &lt;link rel="icon" type="image/svg+xml" href="/favicon.svg" /&gt;<br>    &lt;meta name="generator" content={Astro.generator} /&gt;<br>    &lt;title&gt;My Blog&lt;/title&gt;<br>  &lt;/head&gt;<br>  &lt;body&gt;<br>    &lt;slot /&gt;<br>  &lt;/body&gt;<br>&lt;/html&gt;<br><br>&lt;style&gt;<br>  html,<br>  body {<br>    margin: 0;<br>    width: 100%;<br>    height: 100%;<br>  }<br>&lt;/style&gt;</code></pre>



<p>Für den Header kann ebenso eine Astro-Komponente erstellt werden (components/Header.tsx).</p>



<pre class="wp-block-code"><code>&lt;header&gt;
  &lt;nav&gt;
    &lt;a href="/blog"&gt;My Blog&lt;/a&gt;
  &lt;/nav&gt;
&lt;/header&gt;
</code></pre>



<p>Nun kann index.astro befüllt werden:</p>



<pre class="wp-block-code"><code>---
import { getCollection } from "astro:content";
import Header from "../../components/Header.astro";
import Layout from "../../layouts/Layout.astro";

const posts = (await getCollection("blog")).sort((a, b) =&gt; {
  return b.data.date.valueOf() - a.data.date.valueOf();
});
---

&lt;Layout&gt;
  &lt;Header /&gt;
  &lt;ul&gt;
    {
      posts.map((post) =&gt; (
        &lt;li&gt;
          &lt;a href={"/blog/" + post.id}&gt;
            &lt;div&gt;
              &lt;img src={post.data.img} /&gt;
            &lt;/div&gt;
            &lt;div&gt;{post.data.title}&lt;/div&gt;
            &lt;div&gt;{post.data.date.toLocaleDateString()}&lt;/div&gt;
          &lt;/a&gt;
        &lt;/li&gt;
      ))
    }
  &lt;/ul&gt;
&lt;/Layout&gt;</code></pre>



<p>Mithilfe von <code>getCollection()</code> kann eine Collection, sprich ein Array von Einträgen, geholt werden. In diesem Beispiel werden die Einträge von der Blog-Collection zusätzlich nach dem Datum sortiert.</p>



<h4 class="wp-block-heading">Detailseite</h4>



<p>Für die Detailseite wird ebenso ein Layout erstellt, das den Titel, das Bild und das Datum übergeben bekommt und anzeigt.</p>



<p>layouts/BlogLayout.astro</p>



<pre class="wp-block-code"><code>---
import type { CollectionEntry } from "astro:content";
import Header from "../components/Header.astro";

type Props = CollectionEntry&lt;"blog"&gt;&#91;"data"];

const { title, date, img} = Astro.props;
---

&lt;!doctype html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;meta name="viewport" content="width=device-width" /&gt;
    &lt;link rel="icon" type="image/svg+xml" href="/favicon.svg" /&gt;
    &lt;meta name="generator" content={Astro.generator} /&gt;
    &lt;title&gt;My Blog&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;Header /&gt;
    &lt;main&gt;
      &lt;article&gt;
        &lt;div&gt;
          &lt;img src={img} /&gt;
        &lt;/div&gt;
        &lt;div&gt;{date.toLocaleDateString()}&lt;/div&gt;
        &lt;h1&gt;{title}&lt;/h1&gt;
        &lt;div&gt;
          &lt;slot /&gt;
        &lt;/div&gt;
      &lt;/article&gt;
    &lt;/main&gt;
  &lt;/body&gt;
&lt;/html&gt;

&lt;style&gt;
  html,
  body {
    margin: 0;
    width: 100%;
    height: 100%;
  }
&lt;/style&gt;</code></pre>



<p>Die Detailseite muss nun den Parameter slug auslesen und die entsprechenden Informationen dem BlogLayout übergeben. Es gibt zwei Varianten, das zu tun, je nachdem ob man SSR oder SSG verwenden möchte.</p>



<p><strong>Variante 1: SSR (on demand Rendering)</strong></p>



<pre class="wp-block-code"><code>---
import { render } from "astro:content";
import { getEntry } from "astro:content";
import BlogLayout from "../../layouts/BlogLayout.astro";

export const prerender = false;
const { slug } = Astro.params;

if (!slug) {
  return Astro.rewrite("/404");
}

const entry = await getEntry("blog", slug);

if (!entry) {
  return Astro.rewrite("/404");
}

const { Content } = await render(entry);
---

&lt;BlogLayout {...entry.data}&gt;
  &lt;Content /&gt;
&lt;/BlogLayout&gt;
</code></pre>



<p>Mithilfe von <code>Astro.params</code> kann der Parameter slug ausgelesen werden. Mit <code>getEntry()</code> wird dann der entsprechende Eintrag geholt. Wenn es keinen passenden Eintrag gibt, wird 404 angezeigt. Um den Inhalt der Zielseite anzuzeigen, ohne die URL zu verändern, wird <code>Astro.rewrite()</code> genutzt.</p>



<p><strong>Variante 2: SSG (statische Seite)</strong></p>



<pre class="wp-block-code"><code>---
import type { GetStaticPaths } from "astro";
import { render } from "astro:content";
import BlogLayout from "../../layouts/BlogLayout.astro";
import { getCollection } from "astro:content";

export const getStaticPaths = (async () =&gt; {
  const entries = await getCollection("blog");

  return entries.map((entry) =&gt; ({
    params: { slug: entry.id },
    props: entry,
  }));
}) satisfies GetStaticPaths;

const entry = Astro.props;

const { Content } = await render(entry);
---

&lt;BlogLayout {...entry.data}&gt;
  &lt;Content /&gt;
&lt;/BlogLayout&gt;
</code></pre>



<p>Soll eine dynamische Route statisch sein, so muss sie eine Funktion namens <code>getStaticPaths()</code> exportieren, die ein Array an Objekten mit dem property <code>params</code> zurückgibt. So werden alle möglichen Paths vordefiniert. In diesem Beispiel holt man sich also alle Einträge der Blog-Collection in der <code>getStaticPaths()</code>-Funktion und über die Properties (<code>Astro.props</code>) können dann die Informationen des einzelnen Eintrags ausgelesen werden.</p>



<h2 class="wp-block-heading">Fazit</h2>



<p>Mit Astro können schnelle Websites erstellt werden. Wenn man bereits Erfahrung mit HTML, JSX oder React hat, so fällt einem der Einstieg in das Framework besonders leicht, da man viele vertraute Konzepte wiederfindet. Nur bei komplexeren Websites stößt Astro irgendwann auf seine Grenzen.</p>



<h2 class="wp-block-heading">Quelle</h2>



<p><a href="https://docs.astro.build/en">https://docs.astro.build/en</a></p>



<p></p>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-astro/">Workshop | Astro</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Workshop &#124; .NET (MAUI/ASP.NET Core Blazor)</title>
		<link>https://mobile.fhstp.ac.at/allgemein/workshop-net-maui-asp-net-core-blazor/</link>
		
		<dc:creator><![CDATA[Andreas Kaiser]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 05:17:19 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Workshop]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=14385</guid>

					<description><![CDATA[<p>Nach meinem Workshop im 1. Semester habe ich mich Anfang des 2. Semesters erneut entschieden, einen eigenen (halben) Workshop zu gestalten. Bei der Themenwahl war mir diesmal wichtig, ein Thema zu wählen, dass mehr Coding-lastig und weniger Konfigurations-lastig ist. Ich habe diesen Workshop schlussendlich auf die Arbeit mit .NET ausgerichtet. Das Framework bietet durch seine <a class="read-more" href="https://mobile.fhstp.ac.at/allgemein/workshop-net-maui-asp-net-core-blazor/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/workshop-net-maui-asp-net-core-blazor/">Workshop | .NET (MAUI/ASP.NET Core Blazor)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Nach meinem Workshop im 1. Semester habe ich mich Anfang des 2. Semesters erneut entschieden, einen eigenen (halben) Workshop zu gestalten. Bei der Themenwahl war mir diesmal wichtig, ein Thema zu wählen, dass mehr Coding-lastig und weniger Konfigurations-lastig ist. Ich habe diesen Workshop schlussendlich auf die Arbeit mit .NET ausgerichtet. Das Framework bietet durch seine Vielseitigkeit eine geeignete Grundlage, um sich vertieft mit den programmiertechnischen Aspekten der nativen App-Entwicklung auf der Windows-Seite auseinanderzusetzen. Ziel war es, das Verständnis für Aufbau, Struktur und Zusammenspiel der Komponenten, die das .NET MAUI Framework mit sich bringt, aufzubauen und in einem kurzen Praxisbeispiel zu festigen. Gleichzeitig verstand ich den Workshop als eine Art Vorbereitung auf das 3. Semester, denn dort wird in der Masterklasse voraussichtlich noch tiefer in die Welt von .NET eingestiegen.</p>



<h1 class="wp-block-heading">Theoretische Grundlagen: </h1>



<h2 class="wp-block-heading">Was steckt hinter .NET?</h2>



<p>Der erste Teil des Workshops widmete sich die theoretischen Grundlagen meines Workshopthemas anzueignen. <strong>.NET</strong> wurde im Jahr 2000 von Microsoft eingeführt und hat sich seitdem von einer proprietären Lösung hin zu einer freien, quelloffenen und plattformübergreifenden Software-Plattform entwickelt. Heute (in Version 9/10) deckt .NET ein breites Spektrum an Einsatzmöglichkeiten ab. Dieses erstreckt sich vom Web über Desktop bis hin zu Mobile.</p>



<p>Zentral ist dabei die <strong>Common Language Runtime (CLR)</strong>, die als gemeinsame Laufzeitumgebung dient. Sie erlaubt es, unterschiedliche Programmiersprachen miteinander zu kombinieren, wobei <strong>C#</strong> die dominierende Sprache ist. Dieses Zusammenspiel sorgt für Effizienz, Konsistenz und Flexibilität in der Entwicklung.</p>



<h3 class="wp-block-heading" style="text-decoration:underline">Das .NET Ecosystem</h3>



<p>Um den Aufbau von .NET besser zu verstehen, lohnt sich ein Blick auf das <strong>Ecosystem</strong>:</p>



<ul class="wp-block-list">
<li><strong>Runtime &amp; Core Libraries</strong>: Basis für die Ausführung von .NET-Programmen, inklusive Garbage Collector, Just-in-Time-Compiler und Standardbibliotheken.</li>



<li><strong>Languages</strong>: Offiziell unterstützt werden C#, F# und VB.NET, wobei C# in der Praxis dominiert.</li>



<li><strong>Frameworks</strong>: Unterschiedliche Bereiche, z. B. ASP.NET Core für Web, Blazor für moderne Frontend-Entwicklung, .NET MAUI für Mobile/ Desktop oder WPF/WinForms für klassische Windows-Anwendungen.</li>



<li><strong>Tools &amp; IDEs</strong>: Visual Studio, Visual Studio Code, CLI-Werkzeuge.</li>



<li><strong>Community &amp; Packages</strong>: Über <strong>NuGet</strong> steht ein riesiges Paket-Ökosystem bereit, das von Microsoft und der Community gepflegt wird.</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" src="https://miro.medium.com/v2/resize:fit:1400/1*fA_R-yL4dtZxh77WnInznA.png" alt=""/></figure>



<p><strong>Exkurs: C# als Rückgrat von .NET</strong></p>



<p>Ein kurzer Exkurs führte in die Sprache <strong>C#</strong>, die als Rückgrat von .NET gilt. Sie kombiniert eine klare, objektorientierte Struktur mit modernen Sprachkonzepten. Besonders hervorzuheben sind Features wie <strong>LINQ</strong>, <strong>Lambda-Ausdrücke</strong> oder das asynchrone Programmiermodell mit <strong>async/await</strong>, die den Entwicklungsprozess spürbar vereinfachen.</p>



<h3 class="wp-block-heading" style="text-decoration:underline">Einsatzfelder von .NET in der Praxis</h3>



<p>Das .NET-Framework ist äußerst vielseitig und findet Anwendung in verschiedensten Bereichen:</p>



<p></p>



<ul class="wp-block-list">
<li><strong>Web</strong>: mit ASP.NET Core oder Blazor, wo sogar C# direkt im Browser laufen kann.</li>



<li><strong>Desktop</strong>: für klassische Anwendungen auf Windows und macOS.</li>



<li><strong>Mobile</strong>: plattformübergreifend mit .NET MAUI.</li>
</ul>



<h3 class="wp-block-heading" style="text-decoration:underline"><strong>ASP.NET Core Blazor</strong></h3>



<p>Ein besonders spannender Teil des .NET-Ökosystems und daher extra hervorzuheben ist <strong>Blazor</strong>. Mit Blazor stellt .NET ein Front-End-Webframework bereit, dass komplett auf C# setzt und JavaScript in vielen Szenarien überflüssig macht.</p>



<p>Es gibt zwei Hauptvarianten des Frameworks:</p>



<ul class="wp-block-list">
<li><strong>Blazor WebAssembly</strong>: Führt C#-Code direkt im Browser aus – clientseitig, ohne zusätzlichen Servercode.</li>



<li><strong>Blazor Server</strong>: Nutzt eine persistente Verbindung, bei der die Logik auf dem Server ausgeführt wird und die UI-Änderungen in Echtzeit an den Browser übertragen werden.</li>
</ul>



<p><strong>Die Vorteile von Blazor:</strong></p>



<ul class="wp-block-list">
<li>Einheitliche Codebasis für Front- und Backend (kein Sprachmix nötig).</li>



<li>Höhere Entwicklerproduktivität durch Wiederverwendung von Logik und Komponenten.</li>



<li>Engere Integration mit dem gesamten .NET-Ökosystem.</li>
</ul>



<h2 class="wp-block-heading">Native Entwicklung mit .NET MAUI</h2>



<p>Bevor es zur Umsetzung ging, habe ich im Workshop ausführlich <strong>.NET MAUI</strong> beleuchtet&#8230;</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="837" height="510" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/image.png" alt="" class="wp-image-14772"/></figure>



<p><br>&#8230; das Framework, mit dem sich native Anwendungen für Android, iOS, Windows und macOS aus einer einzigen Codebasis entwickeln lassen.</p>



<p>Das Grundprinzip:</p>



<ul class="wp-block-list">
<li>Die <strong>Benutzeroberfläche wird in XAML beschrieben</strong>,</li>



<li>die <strong>Logik in C#</strong> umgesetzt.</li>
</ul>



<p>Diese klare Trennung verbessert Übersichtlichkeit, Wartbarkeit und Wiederverwendbarkeit des Codes.</p>



<p>Ein wichtiges Architekturprinzip ist das <strong>MVVM-Pattern (Model–View–ViewModel)</strong>:</p>



<ul class="wp-block-list">
<li><strong>View</strong>: definiert Layout und Darstellung</li>



<li><strong>ViewModel</strong>: enthält Logik, Eigenschaften und Befehle</li>



<li><strong>Model</strong>: Datenmodell mit Geschäfts- und Validierungslogik</li>
</ul>



<p>Mit diesem erreicht man eine saubere und skalierbare App-Struktur.</p>



<h3 class="wp-block-heading" style="text-decoration:underline">Wichtige Konzepte in .NET MAUI</h3>



<p>Damit die Theorie greifbarer wird, habe ich im Workshop die wichtigsten Bausteine, mit denen .NET MAUI arbeitet vorgestellt – Konzepte, die auch später in der praktischen Umsetzung wiederkehren:</p>



<p>In .NET MAUI gibt es vier Ausführungszustände (<em>nicht ausgeführt</em>, <em>laufend</em>, <em>deaktiviert</em> und <em>gestoppt</em>), die den Lebenszyklus einer App beschreiben. Diese Zustände regeln, wann die Anwendung gestartet, pausiert, fortgesetzt oder beendet wird. Sie sind entscheidend für Ressourcenmanagement, Statusspeicherung und die Reaktion auf Benutzerinteraktionen oder Systemereignisse.</p>



<h4 class="wp-block-heading">Data Binding</h4>



<p>Das Data Binding in .NET MAUI sorgt für eine Synchronisation zwischen UI-Elementen und ViewModel-Eigenschaften. Es unterstützt verschiedene Bindungsmodi (etwa One-Way und Two-Way), wodurch Änderungen automatisch zwischen UI und Datenmodell ausgetauscht werden. Dadurch wird Boilerplate-Code reduziert und die Wartbarkeit deutlich verbessert. Außerdem erlaubt es ein dynamisches Update der Benutzeroberfläche, sobald sich Daten verändern.</p>



<h4 class="wp-block-heading">Dependency Injection (DI)</h4>



<p>Dependency Injection ermöglicht eine lose Kopplung zwischen Klassen und steigert damit die Testbarkeit der Anwendung. In .NET MAUI können verschiedene Lebenszyklen definiert werden, etwa Singleton, Transient oder Scoped. Die Registrierung der Dienste erfolgt zentral in der App-Initialisierung (App.xaml.cs), was die Verwaltung der Abhängigkeiten übersichtlich und einheitlich gestaltet.</p>



<h4 class="wp-block-heading">Bindable Properties</h4>



<p>Bindable Properties sind spezielle Eigenschaften, die eine Datenbindung in benutzerdefinierten Controls ermöglichen. Sie erleichtern das Erstellen wiederverwendbarer UI-Komponenten und sorgen dafür, dass sich die Oberfläche automatisch aktualisiert, sobald sich eine Eigenschaft ändert. So bleibt das UI stets im Einklang mit den zugrunde liegenden Daten.</p>



<h4 class="wp-block-heading">Behaviors</h4>



<p>Behaviors dienen in .NET MAUI dazu, UI-Elemente um wiederverwendbare Logik zu erweitern. Dadurch kann Verhalten wie Validierung, Animation oder Interaktion modular und flexibel hinzugefügt werden – ohne die zugrunde liegende Code-Behind-Struktur zu verändern.</p>



<h4 class="wp-block-heading">Shell-Navigation</h4>



<p>Die Shell in .NET MAUI vereinheitlicht die Navigationsstruktur einer App. Sie unterstützt deklaratives Routing und Parameterübergabe, was Navigation besonders einfach und klar macht. Zudem erlaubt sie eine bequeme Verwaltung von Flyout-Menüs, Tab-Bars und anderen Navigationselementen. So wird der Implementierungsaufwand bei komplexeren Navigationsszenarien deutlich reduziert.</p>



<h4 class="wp-block-heading">Components &amp; Layouting</h4>



<p>In .NET MAUI lassen sich wiederverwendbare Custom Controls erstellen, um die Benutzeroberfläche gezielt zu erweitern. Neben den Standardkomponenten können Custom Renderer und Community-Bibliotheken (über NuGet) eingebunden werden, um zusätzliche Funktionalität bereitzustellen. Das Layout basiert auf verschiedenen Pages wie ContentPage, NavigationPage und ShellPage, unterstützt Responsive Design und trennt Layout von Logik – was zu klar strukturierten, modularen Anwendungen führt.</p>



<h4 class="wp-block-heading">Essentials</h4>



<p>NET MAUI Essentials bieten eine einheitliche API für den Zugriff auf native Gerätefunktionen. Damit können Funktionen wie Kamera, GPS, Akku oder Sensoren genutzt werden, ohne plattformabhängigen Code schreiben zu müssen.</p>



<h1 class="wp-block-heading">Praxisteil: WeatherApp (.NET MAUI)</h1>



<p>Nach der ausführlichen Theorie folgte die praktische Auseinandersetzung mit dem .NET MAUI Framework, bei der wir die zentralen Konzepte in einer kleinen bzw. einfach gehaltenen Anwendung erprobt und umgesetzt haben. Entstanden ist dabei eine WeatherApp, die aktuelle Wetterdaten über eine API lädt, den Standort des Geräts berücksichtigen kann und über eine einfache Navigation verfügt. Die App ist so aufgebaut, dass es drei zentrale Seiten gibt: eine Startseite, die als Einstieg dient und erklärt, was die App macht, eine Einstellungsseite, auf der der gewünschte Standort festgelegt und gespeichert werden kann, und eine Wetterseite, die die eigentlichen Daten anzeigt. Hier die graphische Ansicht:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_welcome.png"><img decoding="async" width="1422" height="800" data-id="14795" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_welcome-1422x800.png" alt="" class="wp-image-14795"/></a></figure>
</figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-large"><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_settings-1.png"><img decoding="async" width="1422" height="800" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_settings-1-1422x800.png" alt="" class="wp-image-14797"/></a></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-large"><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_weather.png"><img loading="lazy" decoding="async" width="1417" height="800" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_page_weather-1417x800.png" alt="" class="wp-image-14798"/></a></figure>
</div>
</div>



<p>Der eigentliche Abruf der Daten ist im WeatherService gekapselt. Er ruft die API mit dem eingegebenen Stadtnamen oder den ermittelten Koordinaten auf, verarbeitet die JSON-Antwort und gibt ein eigenes Datenmodell zurück. Dadurch bleibt die Logik von der Oberfläche getrennt, und das Modell kann im gesamten Projekt wiederverwendet werden. Auf der Wetterseite bindet das ViewModel die Daten an die Oberfläche. Sobald über den Button „Wetter abfragen“ ein Request ausgelöst wird, landet das Ergebnis in einer Property des ViewModels. Über Data Binding wird diese Property automatisch im UI angezeigt, ohne dass zusätzlicher Code für die Aktualisierung nötig ist.</p>



<p>Eine weitere Funktion ist die Standortabfrage über MAUI Essentials. Mit <code>Geolocation.GetLocationAsync</code> wird die aktuelle Position ermittelt und als Koordinaten an die API übergeben. Dadurch lassen sich exakte Wetterwerte für die aktuelle Position anzeigen. Um beim Testen nachvollziehen zu können, welche Werte vom Gerät oder Emulator zurückkommen, habe ich Logging eingebaut. Damit sieht man direkt, ob die Koordinaten plausibel sind und welche Wetterdaten von der API zurückgeliefert werden.</p>



<p>In den Einstellungen kann der Nutzer einen Standardort hinterlegen. Dieser wird über Preferences dauerhaft gespeichert, sodass die App beim nächsten Start direkt darauf zurückgreifen kann. Das Eingabefeld ist dabei direkt an eine Property im SettingsViewModel gebunden. Wird ein Ort eingetragen, landet der Wert sofort im Code, beim Speichern zusätzlich in den Preferences.</p>



<p>Die Navigation zwischen den Seiten läuft über Blazor-Routen. So bleibt die Struktur klar und konsistent: Startseite, Einstellungen, Wetteranzeige. Damit ist die App modular aufgebaut und kann jederzeit um weitere Seiten erweitert werden.</p>



<p>Der Source-Code des Praxis-Projektes kann hier abgerufen werden:</p>



<div class="wp-block-file"><a id="wp-block-file--media-6d98ceca-ea3b-42fa-ad56-124c900e4398" href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_.NET_Workshop.zip">WApp_.NET_Workshop</a><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/10/WApp_.NET_Workshop.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-6d98ceca-ea3b-42fa-ad56-124c900e4398">Download</a></div>



<h1 class="wp-block-heading">Fazit</h1>



<p>Zu Beginn hat vor allem die Grundeinrichtung eines neuen .NET-Projekts mit MAUI mehr Zeit in Anspruch genommen als geplant. Künftig werde ich diesen Schritt vorab erledigen, um im Workshop mehr Zeit zu haben und hektisches Coden zu vermeiden, das am Ende nur zusätzliches Bugfixing erfordert. Gleichzeitig konnte ich erste praktische Erfahrungen mit C# und der Windows-nativen Umgebung sammeln und habe gemerkt, dass mir die Wissensvermittlung in diesem Workshop jedenfalls leichter gefallen ist, als beim allerersten Mal. Insgesamt stimmt mich das zuversichtlich, hier eine gute Grundlage geschaffen zu haben, um im 3. Semester noch tiefer in die .NET-Entwicklung einzusteigen.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Folien der Präsentation:</strong></p>



<div class="wp-block-file"><a id="wp-block-file--media-09bbe319-7a18-42f6-b4f3-ad199ad93bad" href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/06/NET_Workshop_Kaiser_Final.pptx"><strong>.NET_Workshop_Kaiser_Final</strong></a><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/06/NET_Workshop_Kaiser_Final.pptx" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-09bbe319-7a18-42f6-b4f3-ad199ad93bad">Herunterladen</a></div>



<p><strong>Lehrreiche weiterführende Links:</strong><br><a href="https://docs.typo3.org/">https://dotnet.microsoft.com/en-us/learn</a><br><a href="https://docs.typo3.org/">https://learn.microsoft.com/de-de/dotnet/core/introduction</a><br><a href="https://docs.typo3.org/">https://learn.microsoft.com/de-de/dotnet/maui/?view=net-maui-9.0</a><br><a href="https://docs.typo3.org/">https://learn.microsoft.com/de-de/dotnet/csharp/</a><br><a href="https://docs.typo3.org/">https://www.it-schulungen.com/wir-ueber-uns/wissensblog/was-ist-net-maui-9-das-plattformuebergreifende-ui-framework-im-detail.html</a><br><a href="https://medium.com/quick-code/understanding-the-net-ecosystem-f60f571e1152">https://medium.com/quick-code/understanding-the-net-ecosystem-f60f571e1152</a></p>



<p>Beitragsbild: <a href="https://www.unimedia.tech/wp-content/uploads/2023/11/Maui-1.webp">https://www.unimedia.tech/wp-content/uploads/2023/11/Maui-1.webp</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/workshop-net-maui-asp-net-core-blazor/">Workshop | .NET (MAUI/ASP.NET Core Blazor)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Workshop &#124; Expo (React Native)</title>
		<link>https://mobile.fhstp.ac.at/workshop/workshop-expo-react-native/</link>
		
		<dc:creator><![CDATA[David Grünberger]]></dc:creator>
		<pubDate>Sun, 21 Sep 2025 21:27:23 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Cross Plattform]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Trends]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Expo]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Mobile apps]]></category>
		<category><![CDATA[react native]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=14722</guid>

					<description><![CDATA[<p>Die mobile App-Welt wächst stetig. Unternehmen stehen heute vor der Herausforderung, ihre Anwendungen gleichzeitig für iOS und Android zu entwickeln, dabei aber Zeit, Kosten und Personalaufwand im Blick zu behalten. Klassische native Entwicklung bedeutet: zwei Codebasen, zwei Entwicklerteams und doppelte Wartung. Hier setzt React Native an – ein Framework, das es erlaubt, mit JavaScript und <a class="read-more" href="https://mobile.fhstp.ac.at/workshop/workshop-expo-react-native/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-expo-react-native/">Workshop | Expo (React Native)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Die mobile App-Welt wächst stetig. Unternehmen stehen heute vor der Herausforderung, ihre Anwendungen gleichzeitig für <strong>iOS</strong> und <strong>Android</strong> zu entwickeln, dabei aber Zeit, Kosten und Personalaufwand im Blick zu behalten. Klassische native Entwicklung bedeutet: zwei Codebasen, zwei Entwicklerteams und doppelte Wartung. Hier setzt <strong>React Native</strong> an – ein Framework, das es erlaubt, mit <strong>JavaScript und React</strong> native Apps für beide Plattformen zu entwickeln.</p>



<p>Doch React Native allein ist nicht immer der einfachste Startpunkt. Wer sich den Einstieg erleichtern und viele wiederkehrende Aufgaben automatisieren möchte, kommt an <strong>Expo</strong> kaum vorbei.</p>



<p>Im 2. Semester meines Masterstudiums in Interactive Technologies hielt ich in der Masterklasse Mobile einen Workshop ab, der eine Einführung in die App-Entwicklung mit React Native und Expo gab:</p>



<h2 class="wp-block-heading">React Native – die Basis</h2>



<p>React Native wurde 2015 von <strong>Meta (Facebook)</strong> veröffentlicht und ist seither ein fester Bestandteil der mobilen App-Entwicklung. Ziel ist es, die aus dem Web bekannte <strong>React-Philosophie</strong> auch auf mobile Plattformen zu bringen: Komponentenbasiert, wiederverwendbar und flexibel.</p>



<h3 class="wp-block-heading">Vorteile von React Native</h3>



<ul class="wp-block-list">
<li><strong>Plattformübergreifend</strong>: Eine Codebasis für Android und iOS</li>



<li><strong>Performance</strong>: Native UI-Komponenten, keine WebViews</li>



<li><strong>Entwicklerfreundlich</strong>: Hot Reloading beschleunigt den Entwicklungsprozess</li>



<li><strong>Ökosystem</strong>: Riesige Community und viele Open-Source-Bibliotheken</li>



<li><strong>Erfolgreiche Einsätze</strong>: Unternehmen wie Facebook, Uber, Airbnb oder Tesla setzen auf React Native</li>
</ul>



<p>Im Vergleich zu Frameworks wie <strong>Ionic</strong> oder <strong>Flutter</strong> zeigt sich ein klarer Unterschied:</p>



<ul class="wp-block-list">
<li>Ionic nutzt stark Web-Technologien und WebViews, was aufwändige Apps schnell an Grenzen bringt.</li>



<li>Flutter verwendet eine eigene Rendering-Engine und ein komplett eigenes UI-System. Das bietet Flexibilität, geht aber zulasten von App-Größe und Integration in die nativen Systeme.</li>



<li>React Native dagegen greift direkt auf <strong>native APIs</strong> zu und integriert sich harmonisch in iOS und Android.</li>
</ul>



<h2 class="wp-block-heading">Expo – das Turbo-Framework für React Native</h2>



<p>Wer mit React Native arbeitet, merkt schnell: Obwohl es in vielen Fällen einfacher ist als native Entwicklung, braucht man dennoch viel Konfiguration. Build-Tools, Signierungen, App-Store-Prozesse – all das kostet Zeit und Nerven.</p>



<p>Genau hier kommt <strong>Expo</strong> ins Spiel. Expo ist ein <strong>Open-Source-Framework</strong>, das wie eine Art <strong>„Abkürzung“</strong> für React-Native-Projekte funktioniert.</p>



<h3 class="wp-block-heading">Was Expo bietet</h3>



<ul class="wp-block-list">
<li><strong>Vorgefertigtes SDK</strong> mit Zugriff auf Kamera, Standort, Push-Notifications u. v. m.</li>



<li><strong>Expo Go App</strong>: Einfach QR-Code scannen und die App direkt auf dem Smartphone testen – ohne Build-Prozess.</li>



<li><strong>OTA-Updates</strong> (Over-the-Air): Apps können direkt aktualisiert werden, ohne dass der App Store durchlaufen werden muss.</li>



<li><strong>Schneller Start</strong>: Keine komplizierte native Konfiguration notwendig – besonders für Einsteiger ein riesiger Vorteil.</li>
</ul>



<p>Ein praktischer Vergleich:<br>Während man bei klassischem React Native oft erstmal eine komplexe iOS- oder Android-Konfiguration anlegen muss, startet man mit Expo praktisch „out of the box“ – fast so, als würde man ein neues React-Webprojekt mit Next.js beginnen.</p>



<h2 class="wp-block-heading">Expo Go – Entwickeln ohne Hürden</h2>



<p>Ein Highlight von Expo ist <strong>Expo Go</strong>. Statt bei jeder Änderung die App neu bauen zu müssen, scannt man mit der Expo-Go-App auf dem Smartphone einfach einen QR-Code und testet die Anwendung sofort live.</p>



<p>Für Entwickler bedeutet das:</p>



<ul class="wp-block-list">
<li>Sofortiges Feedback bei Änderungen</li>



<li>Weniger Zeitverlust durch Builds</li>



<li>Schnelleres Prototyping</li>
</ul>



<p>Besonders im Teamwork oder bei Präsentationen vor Kunden ist das ein enormer Vorteil, weil Feedback in Echtzeit umgesetzt werden kann.</p>



<h2 class="wp-block-heading">Expo Application Service (EAS) – Von der Idee in den Store</h2>



<p>Früher war der Weg von einer funktionierenden App zum Eintrag im App Store oft eine große Hürde. Mit <strong>EAS (Expo Application Service)</strong> nimmt Expo Entwicklern auch diesen Teil ab.</p>



<h3 class="wp-block-heading">Die wichtigsten Funktionen:</h3>



<ul class="wp-block-list">
<li><strong>EAS Build</strong>: Der Code wird auf Expo-Servern in native Apps für iOS und Android kompiliert. Auch das Signieren übernimmt Expo.</li>



<li><strong>EAS Submit</strong>: Der automatische Upload in den Apple App Store und Google Play Store spart enorm viel Zeit.</li>
</ul>



<p>Ein besonderer Vorteil: <strong>Windows-Nutzer benötigen keinen Mac</strong>, um iOS-Apps zu bauen und hochzuladen – eine Einschränkung, die viele Entwickler bisher blockiert hat.</p>



<h2 class="wp-block-heading">Praxisbeispiel: TODO-App</h2>



<p>Ein klassischer Einstieg in die App-Entwicklung ist eine <strong>TODO-App</strong>. Im Zuge des Workshops wurde eine solche erfolgreich mit den Studenten umgesetzt:</p>



<ul class="wp-block-list">
<li>Nutzer können Aufgaben anlegen, abhaken und löschen</li>



<li>Die Daten werden lokal gespeichert</li>
</ul>



<p>Das klingt simpel, zeigt aber: Schon mit wenigen Zeilen Code lassen sich funktionale und plattformübergreifende Apps erstellen – ohne tief in die nativen Eigenheiten von iOS oder Android einzusteigen.</p>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" width="535" height="807" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/image.png" alt="" class="wp-image-14726" style="width:267px;height:auto"/><figcaption class="wp-element-caption"><em><strong>Screenshot: TODO App</strong></em></figcaption></figure>



<p>Der vollständige Sourcecode der App aus dem Workshop kann hier heruntergeladen werden:</p>



<div class="wp-block-file"><a id="wp-block-file--media-c4684de0-6a6a-4cca-b611-253025fa0db0" href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Expo_Example_ToDoList_App.zip">Expo_Example_ToDoList_App</a><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Expo_Example_ToDoList_App.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-c4684de0-6a6a-4cca-b611-253025fa0db0">Herunterladen</a></div>



<h2 class="wp-block-heading">Fazit – Warum Expo?</h2>



<p>React Native ist schon für sich ein mächtiges Framework. Doch <strong>Expo</strong> hebt die Effizienz und Benutzerfreundlichkeit noch einmal auf ein neues Level. Besonders für kleinere Teams, Start-ups oder Einzelentwickler bedeutet das: schneller Ergebnisse, weniger technische Hürden und ein klarer Fokus auf die eigentliche App-Idee.</p>



<p>Ob für <strong>Prototypen</strong>, <strong>MVPs</strong> oder vollwertige Produktions-Apps – Expo bietet eine moderne, schlanke und praxisnahe Lösung, die den gesamten Entwicklungszyklus abdeckt:<br>Von der ersten Zeile Code über das Testen auf dem Smartphone bis hin zur Veröffentlichung im App Store.</p>



<p>Wer also nach einem Weg sucht, mobile Apps ohne Umwege zu entwickeln, findet in <strong>React Native mit Expo</strong> einen idealen Einstieg.</p>



<h2 class="wp-block-heading">Downloads</h2>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Presentation_Expo_DGruenberger.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Presentation_Expo_DGruenberger."></object><a id="wp-block-file--media-25194fd7-9b47-457e-b495-3aeee5fe064f" href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Presentation_Expo_DGruenberger.pdf">Presentation_Expo_DGruenberger</a><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Presentation_Expo_DGruenberger.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-25194fd7-9b47-457e-b495-3aeee5fe064f">Herunterladen</a></div>



<div class="wp-block-file"><a id="wp-block-file--media-d43b083c-c6cc-4034-963c-41dc6179c063" href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Expo_Example_ToDoList_App.zip">Expo_Example_ToDoList_App</a><a href="https://mobile.fhstp.ac.at/wp-content/uploads/2025/09/Expo_Example_ToDoList_App.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-d43b083c-c6cc-4034-963c-41dc6179c063">Herunterladen</a></div>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-expo-react-native/">Workshop | Expo (React Native)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Blog &#124; MoveMates</title>
		<link>https://mobile.fhstp.ac.at/development/blog-movemates/</link>
		
		<dc:creator><![CDATA[David Grünberger]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 18:34:10 +0000</pubDate>
				<category><![CDATA[Cross Plattform]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Dokumentation]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tests]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Extreme Programming Week]]></category>
		<category><![CDATA[Gitlab]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Sensoren]]></category>
		<category><![CDATA[websockets]]></category>
		<category><![CDATA[Wild Week]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=14255</guid>

					<description><![CDATA[<p>Am Anfang des 2. Semesters des Master-Studiengangs Interactive Technologies (Masterklasse Mobile) fand die “Extreme Programming Week” statt (auch “Wild Week” genannt). Für diese Woche bekamen wir die Challenge, als ganze Masterklasse gemeinsam (insgesamt 8 Personen) innerhalb von 5 Tagen (Montag bis Freitag) eine App zu entwickeln. Die konkrete Aufgabenstellung erhielten wir erst am Montag, und <a class="read-more" href="https://mobile.fhstp.ac.at/development/blog-movemates/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/blog-movemates/">Blog | MoveMates</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Am Anfang des 2. Semesters des Master-Studiengangs Interactive Technologies (Masterklasse Mobile) fand die “Extreme Programming Week” statt (auch “Wild Week” genannt). Für diese Woche bekamen wir die Challenge, als ganze Masterklasse gemeinsam (insgesamt 8 Personen) innerhalb von 5 Tagen (Montag bis Freitag) eine App zu entwickeln. Die konkrete Aufgabenstellung erhielten wir erst am Montag, und am Freitagnachmittag sollte die MVP-Version präsentiert werden.</p>



<h2 class="wp-block-heading">Aufgabenstellung</h2>



<p>Die Aufgabenstellung und das MVP wurde uns größtenteils vorgegeben, wobei wir vor allem bei den optionalen zusätzlichen Features mitreden konnten. Prinzipiell war die Idee, eine App zu entwickeln, über die man gewisse Echtzeitdaten wie Standort, Geschwindigkeit, Herzfrequenz etc. mit einer Gruppe austauscht. Einsatzbereiche gibt es dabei mehrere. Beispielsweise könnte man sich auf den Sport- (Laufen, Radfahren etc.) oder auf den Gesundheitsbereich (inkl. Fallerkennung) fokussieren. Letztendlich haben wir uns für den Bereich &#8220;gegeneinander Laufen&#8221; entschieden.</p>



<h3 class="wp-block-heading">MVP (Minimum Viable Product)</h3>



<p>Um am Ende sagen zu können, dass wir die Aufgabe gemeistert haben, wurde ein MVP (Minimum Viable Product) mit den grundlegendsten Funktionen definiert. Was den Client betrifft, waren das Auslesen und sinnvolle Übertragen von Sensor-Daten, Login und Teambildung aber auch eine “coole Darstellung” wichtig. Vor allem beim letzten Punkt sollten wir uns wirklich Gedanken machen, was im Kontext gut funktioniert, anstatt einfach nur alle Daten in Zahlenform anzuzeigen.<br>Serverseitig lag der Fokus auf der Verteilung der Daten in Echtzeit im Team.<br>Außerdem sollte die App auf mindestens einer Plattform nativ im Testmodus verfügbar sein.</p>



<h3 class="wp-block-heading">NTH (Nice to Have)</h3>



<p>Neben dem MVP wurden auch optionale Features notiert, genannt “Nice to Haves”, die dann umgesetzt werden sollten, sobald das MVP fertig ist. Diese Liste wurde auch während der Woche erweitert.<br>Dazu gehörte die Distribution auf beiden Plattformen (iOS und Android) oder das Einführen eines Handicaps, welches dazu genutzt werden kann, dass unterschiedlich starke Leute in einer Sportart gegeneinander antreten können. Eine History vergangener Sessions, eine Exportmöglichkeit der Daten, Gamification, das Laufen der App im Hintergrund, Micro-Interactions und Vibration waren ebenso Punkte auf dieser Liste. Andere Ideen waren die Berechnung eines Leistungswerts, Tests oder die Verwendung eines QR-Codes zur Gruppenbildung.</p>



<h2 class="wp-block-heading">Verwendete Technologien</h2>



<p>Im Projekt setzten wir auf Technologien, die wir bereits im vorherigen Semester kennenlernen durften bzw. mit denen einige unserer Gruppenmitglieder*innen bereits Erfahrung hatten. Von Anfang an war klar, dass sich eine native Umsetzung unserer App für sowohl Android als auch iOS wohl zeitlich nicht ausgehen würde, weshalb wir im Frontend auf eine Cross-Plattform Technologie setzten.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="5831" height="1080" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/tech_stack_diagram.jpg" alt="" class="wp-image-14288" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/tech_stack_diagram.jpg 5831w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/tech_stack_diagram-1536x284.jpg 1536w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/tech_stack_diagram-2048x379.jpg 2048w" sizes="auto, (max-width: 5831px) 100vw, 5831px" /><figcaption class="wp-element-caption"><strong>Zusammenspiel der verwendeten Technologien und Infrastruktur</strong></figcaption></figure>



<h3 class="wp-block-heading">Frontend</h3>



<p>Im Frontend arbeiteten wir mit dem Cross-Platform Framework Ionic (Capacitor), in Kombination mit der Frontend-Technologie React &#8211; geschrieben in Typescript. Die Wahl fiel darauf, da wir im 1. Semester unseres Studiums sowohl ein Projekt mit React umsetzen mussten, als auch in unserer Masterklasse mit dem Ionic Framework arbeiteten.</p>



<p>Die ersten Screen-Prototypes designten wir mit der Design-Software Figma.</p>



<h3 class="wp-block-heading">Backend</h3>



<p>Im Backend verwendeten wir NestJS, ebenfalls in Kombination mit Typescript, da wir diese Backend-Technologie ebenfalls im 1. Semester unserer Masterklasse in einem Projekt verwendeten und so die Einstiegshürde wegfiel.</p>



<p>Da unsere App sehr stark auf Live-Daten angewiesen ist (sowohl das Senden der aktuellen Sensordaten eines Users, als auch das Erhalten der Live-Daten anderer User während einer Aktivität), entschieden wir uns, hierfür auf Websockets zurückzugreifen, welche nahtlos in NestJS unterstützt wurden. Beim Erstellen einer Session für alle Teilnehmer*innen wurde ein Websocket &#8220;Topic&#8221; erstellt, welches in den Apps aller Nutzer*innen subscribed werden konnte und mit welchem immer die aktuellen Live-Daten in einem fest definierten Intervall ausgetauscht wurden.</p>



<h4 class="wp-block-heading">Datenbank</h4>



<p>Für die Persistenz unserer Daten setzten wir auf eine PostgreSQL Datenbank, ergänzt durch den Object-Relational Mapper (ORM) TypeORM. Wir wählten PostgreSQL aufgrund seiner Zuverlässigkeit und weiten Verbreitung als relationale Datenbank, was uns eine solide Basis für unsere Anwendung bot und zukünftige Skalierbarkeit ermöglichte. Ein weiterer ausschlaggebender Faktor war die exzellente Kompatibilität mit NestJS und die vorhandene Teamerfahrung mit TypeORM.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1111" height="651" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/06/ER-Modell-Komplett.drawio-1.png" alt="" class="wp-image-14372"/><figcaption class="wp-element-caption"><strong>ER-Diagramm der movemates DB</strong></figcaption></figure>



<p>Die Struktur unserer Datenbank wird ist in diesem ER-Diagramm veranschaulicht. Die Kernentitäten bilden  User, Session und Messerwerte. Zwischen :</p>



<ul class="wp-block-list">
<li>User<strong>:</strong> Hier hinterlegen wir alle notwendigen Benutzerinformationen, darunter Id, Vorname, Nachname, Email, Passwort und physiologische Daten wie Geburtsdatum, Groesse, Gewicht und Geschlecht. Diese Informationen sind essenziell, insbesondere das Geburtsdatum für die Berechnung der individuellen Herzfrequenzzonen.</li>



<li>Session<strong>:</strong> Diese Entität verwaltet die Details der Lauf-Sessions, wie Id, Status, Enddatum, Typ und Startdatum.</li>



<li>User_Session<strong>:</strong> Als Verbindungstabelle stellt sie die Beziehung zwischen Benutzern und Sessions dar und speichert die Rolle des Teilnehmers innerhalb einer Session.</li>



<li>Messwerte<strong>:</strong> Diese zentrale Entität ist für die Speicherung der während einer aktiven Session gesammelten Sensordaten zuständig. Dazu gehören Zeitstempel, Geschwindigkeit, Breitengrad, Längengrad, Lage, Richtung, Herzfrequenz und Schrittfrequenz. Diese Daten bilden die Grundlage für unsere Echtzeitanzeigen und potenzielle historische Analysen.</li>
</ul>



<p>Mit unserer PostgreSQL DB wird somit das Rückgrat unserer App, indem alle statischen Benutzer- und Sitzungsdaten sowie die dynamischen Sensordaten gespeichert sind, die für die Kernfunktionen und die Visualisierung notwendig sind, gebildet.</p>



<p>Um diese DB stabil und einfach zu handhaben, nutzten wir Docker. Das erlaubte uns, die PostgreSQL-Datenbank in einem eigenen, isolierten &#8220;Container&#8221; laufen zu lassen. Dies vereinfacht nicht nur die Einrichtung erheblich, sondern stellt auch sicher, dass die Datenbank immer in einer konsistenten Umgebung läuft und ihre Daten sicher verwahrt bleiben. Dank dieser Docker-Einrichtung konnte sich unser Backend-Service problemlos und zuverlässig mit der Datenbank verbinden, sobald diese bereit war. Die Konfiguration mit TypeORM wiederum sorgte dafür, dass unsere App die Daten korrekt lesen, schreiben und verwalten konnte. Besonders wichtig dabei waren unsere TypeORM Datenbank-Migrationen. Diese funktionieren wie kleine, versionierte Skripte, die es uns ermöglichten, die Struktur der Datenbank (wie z.B. neue Spalten hinzufügen oder bestehende ändern) im Laufe der Entwicklung schrittweise und kontrolliert anzupassen, ohne Daten zu verlieren.</p>



<h4 class="wp-block-heading">OpenAPI</h4>



<p>Damit wir in unserem Frontend nicht noch einmal alle Backend Objekte doppelt anführen müssen und um Zeit zu sparen, haben wir uns dazu entscheiden, den OpenAPI Generator zu verwenden. Die grundsätzliche Funktion von diesem ist, dass man im Backend mithilfe eines Decorators, wie Swagger, die Endpunkte definiert und dokumentiert. Mithilfe dieser Dokumentation, kann man dann für das Frontend Client-Funktionen erstellen lassen, welche mit dem Backend konsistent und typensicher sind. In unserem Backend haben wir Swagger verwendet, um per Decorator die Endpoint Spezifikationen anzugeben. Im Frontend haben wir dann die <em>@openapitools/openapi-generator-cli</em> installiert, welche einen Befehl bereitstellt, mit welchem man die API erstellen kann. Davor ist noch eine OpenAPI Spec Datei benötigt, welche openapitool.json heißt, in welcher man die Einstellungen für die API angibt. Danach kann man jederzeit die API generieren lassen und sie verwenden.</p>



<h3 class="wp-block-heading">CI/CD</h3>



<p>Für unsere Backend-Applikation wurde uns ein Server auf unserer FH-Cloud zur Verfügung gestellt. Haben wir nun unsere NestJS Applikation per FTP auf diesen Server geladen? Natürlich nicht! Haben wir stattdessen viel Zeit in Continuous Integration und Deployment (CI/CD) investiert? Selbstverständlich! Schon am ersten Tag der Woche haben wir ein docker-compose.yml geschrieben. Damit ließ sich die Backend-Applikation mit einer Postgres Datenbank starten. Mit&nbsp;der Unterstützung unseres Masterklassenleiters Armin haben wir am Morgen des zweiten Tages Docker auf unserem Server installiert. Dann haben wir einen GitLab Runner mit dem Shell Executor eingerichtet und das .gitlab-ci.yml geschrieben. Darin haben wir einen Deploy Job definiert, der bei einem Commit auf den “main” Branch docker-compose ausführt und damit die neueste Version der Anwendung auf unserem Server startet. Ebenfalls haben wir den Build unserer Android-App automatisiert. Dafür brauchte es einen Job um die Dependencies der Ionic App zu installieren, einen Job um die Frontend-Applikation zu bauen, einen um das .apk zu bauen und schließlich einen Job um das .apk zu publishen. Damit wir reproduzierbare Builds und einen sauberen Server haben, wollten wir all diese Jobs in Containern ausführen. Dazu mussten wir einen weiteren GitLab Runner aufsetzen, der dieses Mal den Docker Executor verwendet. Der Build der Android App verwendet das Image alvrme/alpine-android und die anderen ein simples Node.js Image. Continuous Deployment war geschafft, Continuous Integration folgte.</p>



<p>Wenn man ein neues NestJS-Projekt startet, werden automatisch <a href="https://eslint.org/">Eslint</a> mit <a href="https://prettier.io/">Prettier</a> und <a href="https://jestjs.io/">Jest</a> eingerichtet. Damit das Code-Linting/Formatting und die Tests auch in der Pipeline ausgeführt werden, haben wir dafür jeweils einen Job in einem “test” Step in unsere Pipeline erstellt. Vorgelagert findet ein Job statt, der die Dependencies installiert. Alle drei Jobs werden in einem Node.js Image ausgeführt. Hätten wir noch mehr Zeit gehabt, hätten wir noch für das Frontend einen Linting- und Test-Job erstellt.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1383" height="158" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/image2.png" alt="" class="wp-image-14285" style="object-fit:cover"/><figcaption class="wp-element-caption"><strong>Visualisierung unserer GitLab CI/CD Pipeline</strong></figcaption></figure>



<p>Im Hinblick auf CI war zwar die Basis für Unit Tests im Backend gelegt, aber leider fehlten uns die Tests, um wirklich Nutzen davon zu haben. Der <a href="https://docs.gitlab.com/ci/testing/unit_test_reports/">GitLab Test Reporter</a> zeigt die traurige Situation unserer Unit Tests (siehe folgenden Screenshot). Um das zu kompensieren, haben wir End-To-End-Tests geschrieben, die zumindest einen Teil der User Flows abdecken. Mit <a href="https://www.cypress.io/">Cypress</a> durchlaufen wir den Registrierungs- und Anmeldeprozess und starten einen neuen Gruppenaktivität. Die Cypress Tests werden leider nicht in der Pipeline ausgeführt, da unsere GitLab Runner mit den existierenden Jobs bereits alle Hände voll zu tun hatten. Gegen Ende der Woche, als der Zeitdruck stieg, mussten wir sogar manche Pipeline Steps deaktivieren, um das Deployment zu beschleunigen.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="952" height="615" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/image3.png" alt="" class="wp-image-14286"/><figcaption class="wp-element-caption"><strong>Erfolgreich durchgelaufene Pipeline (32 Minuten!)</strong></figcaption></figure>



<h4 class="wp-block-heading">Internes App-Publishing</h4>



<p>Eine der Anforderungen unserer Auftraggeber war es, die fertige App auch auf zumindest einer der beiden Plattformen auf eine beliebige Weise öffentlich zur Verfügung zu stellen. Wir entschieden uns dafür Firebase App Distribution zu verwenden, um unsere Android App einer fest definierten Personengruppe ausliefern zu können. Es wurde ein Build Job in unserer GitLab Pipeline eingerichtet, der uns ein APK-File gebaut hat und dieses über die Firebase CLI in einen geschlossenen Test hochgeladen hat, in denen sowohl alle Teammitglieder*innen als auch unsere Dozenten eingeladen wurden. So wurde nach jedem Commit auf unseren master-branch eine neue App-Version veröffentlicht, die mit einem Klick in der Firebase App Distribution App heruntergeladen werden konnte.</p>



<h3 class="wp-block-heading">Sensoren</h3>



<p>In Bezug auf Sensoren wurden wir mit verschiedenen Heart Rate Monitors (HRMs) wie Wahoo Tickr Fit und einem Modell von Moofit ausgestattet. Um diese Daten auslesen zu können, haben wir das Capacitor Community Plugin “Bluetooth Low Energy” verwendet.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="3024" height="4032" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/hrm-rotated.jpeg" alt="" class="wp-image-14278" style="width:auto;height:400px" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/hrm-rotated.jpeg 3024w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/hrm-1152x1536.jpeg 1152w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/hrm-1536x2048.jpeg 1536w" sizes="auto, (max-width: 3024px) 100vw, 3024px" /><figcaption class="wp-element-caption"><strong>Beispiel: Einer der verwendeten Herzfrequenzsensoren</strong></figcaption></figure>



<h2 class="wp-block-heading">Arbeitsablauf</h2>



<p>Generell haben wir beschlossen, dass wir jeden Tag um 9 Uhr mit der Arbeit beginnen werden. Wir haben auch die gesamte Woche vor Ort gearbeitet, da wir es als die bessere Option empfunden haben und gehört haben, wie schlecht es der Gruppe ging, welche nur im Home Office gearbeitet hat. Um uns besser organisieren zu können, haben wir jeden Tag um 10:00 ein Daily Standup abgehalten, wo wir unseren derzeitigen Stand den Dozenten gezeigt und erklärt haben und wir Feedback auf diesen erhalten haben. Bei diesen Standups haben wir auch unsere Ziele für den Tag festgelegt, damit wir wissen, auf was wir uns fokussieren werden.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="4624" height="3468" data-id="14281" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup1.jpg" alt="" class="wp-image-14281" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup1.jpg 4624w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup1-1536x1152.jpg 1536w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup1-2048x1536.jpg 2048w" sizes="auto, (max-width: 4624px) 100vw, 4624px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="3472" height="4624" data-id="14282" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup2.jpg" alt="" class="wp-image-14282" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup2.jpg 3472w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup2-1153x1536.jpg 1153w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/standup2-1538x2048.jpg 1538w" sizes="auto, (max-width: 3472px) 100vw, 3472px" /></figure>
<figcaption class="blocks-gallery-caption wp-element-caption"><strong>Daily Standup: Zieldefinition für den Arbeitstag</strong></figcaption></figure>



<p></p>



<p>Ziel des ersten Tages war es, ein Monorepo auf GitLab anzulegen und das Projekt zu initialisieren. Im Frontend beschäftigten wir uns mit den ersten Sensoren, und im Backend wurde die Datenbank aufgesetzt und mit den Websockets begonnen. Weiters richteten wir Firebase App Distribution für die Android Plattform ein.</p>



<p>Am Dienstag besprochen wir, wie unsere Entities/Daten aussehen würden. Das Feature “User Registrierung und Login” wurde implementiert, und wir machten uns Gedanken über das UI-Konzept und die Datenvisualisierung. Zusätzlich überlegten wir uns die Verwendung und Berechnung der Rohdaten der Sensoren, und implementierten automatisierte Android Builds.</p>



<p>Am Mittwoch, nachdem wir Feedback zu unserem UI-Konzept erhielten, verfeinerten wir dieses und überlegten uns ein bestimmtes Szenario für die Datenvisualisierung. Danach machten wir uns daran, die UI umzusetzen, ClientSDK zu generieren und Endpoints und Services im Backend zu erstellen. Weitere Ziele waren, Sensordaten über Websockets schicken und empfangen zu können, und eine Session sowohl im Frontend als auch im Backend erstellen zu können.</p>



<p>In den letzten beiden Tagen ging es darum, alle Features des MVP fertigzustellen und letzte Bugs zu fixen. Dazu gehörten: Auth (Route Guard, Token, …), alles rund um Sessions (Create, Join, End, Leave), die Kommunikation der Daten über Websockets, Edit Profile, Datenvalidierung (null, -1, …), Loading Indicator, und mehr.</p>



<p>Am Freitagnachmittag wurde das Endprodukt präsentiert &#8211; mehr dazu etwas später in diesem Blogbeitrag.</p>



<p>Neben der Arbeit kam aber auch nicht der Spaß zu kurz. Darum nutzten wir als Team am 4. Tag der Wild Week (Donnerstag) die Möglichkeit, beim FH internen “IMFix” Event vorbeizuschauen. Neben Snacks, Bier und guter Laune konnten wir uns bei mehreren Multiplayer Spielen entspannen, bevor es dann in die heiße Endphase des Projektes ging.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1080" height="1920" data-id="14259" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_1.jpg" alt="" class="wp-image-14259" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_1.jpg 1080w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_1-864x1536.jpg 864w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="3024" height="4032" data-id="14262" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_2-2-rotated.jpeg" alt="" class="wp-image-14262" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_2-2-rotated.jpeg 3024w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_2-2-1152x1536.jpeg 1152w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/imfix_2-2-1536x2048.jpeg 1536w" sizes="auto, (max-width: 3024px) 100vw, 3024px" /></figure>
<figcaption class="blocks-gallery-caption wp-element-caption"><strong>Kurze Verschnaufpause beim IMFix Event &#8211; <em>&#8220;Don&#8217;t drink and drive&#8221;</em> wurde hier ausnahmsweise mal nicht ganz ernst genommen.</strong></figcaption></figure>



<h2 class="wp-block-heading">Abgeliefertes Endprodukt</h2>



<p>Unsere App ist in mehrere übersichtliche Screens unterteilt, die den User Schritt für Schritt durch den gesamten Ablauf führen. Von der Anmeldung über die Erstellung oder Teilnahme an einer Session bis hin zur aktiven Nutzung während eines Laufs sind alle Funktionen klar strukturiert. Im Mittelpunkt stehen dabei das Dashboard als zentrale Steuerzentrale, der WaitingScreen zur Organisation der Teilnehmer*innen, sowie das Userprofil, in dem persönliche Daten verwaltet werden können. Während einer aktiven Session rücken das Leaderboard und die Kartenansicht in den Vordergrund. Hier werden in Echtzeit alle relevanten Informationen der Teilnehmer*innen angezeigt.&nbsp;<br>Bevor jedoch der eigentliche Ablauf startet, erfolgt der Einstieg über den Login oder die Registrierung.</p>



<h3 class="wp-block-heading">Login und Registrierung</h3>



<p>Beim ersten Öffnen der App wird der User auf den Login-Screen weitergeleitet. Hier kann man sich entweder mit bestehenden Zugangsdaten anmelden oder sich neu registrieren. Die Registrierung erfolgt über ein kurzes Formular, bei dem grundlegende Daten wie Benutzername, E-Mail-Adresse und Passwort abgefragt werden.</p>



<h3 class="wp-block-heading">Dashboard</h3>



<p>Sobald der Login oder die Registrierung abgeschlossen ist, gelangt der User auf das Dashboard. Hier stehen zwei Optionen zur Verfügung: Entweder eine neue Session zu erstellen oder einer bestehenden Session beizutreten. Diese Optionen sind jedoch zu Beginn ausgegraut dargestellt und können erst genutzt werden, wenn bestimmte Voraussetzungen erfüllt sind.</p>



<p>Auf dem Dashboard befinden sich drei Buttons zur Aktivierung der benötigten Sensoren:</p>



<ul class="wp-block-list">
<li><strong>GPS</strong></li>



<li><strong>Herzfrequenzsensor</strong> (inkl. Bluetooth-Verbindung zu einem Wearable)</li>



<li><strong>Heading-Sensor</strong></li>
</ul>



<p>Zu Beginn sind alle drei Buttons rot eingefärbt, um anzuzeigen, dass die jeweiligen Sensoren noch nicht aktiv sind. Nach dem erfolgreichen Aktivieren – sei es durch das Einschalten eines Gerätesensors oder die Herstellung einer Verbindung – wechselt die Farbe auf grün, was visuell signalisiert, dass der jeweilige Sensor nun einsatzbereit ist.</p>



<p>Erst wenn entweder das GPS-Signal oder der Herzfrequenzsensor aktiviert wurde, werden die beiden Optionen „Session erstellen“ und „Session beitreten“ freigeschaltet und können ausgewählt werden. Optional kann zusätzlich der Heading-Sensor aktiviert werden, der später auf der Karte eine genauere Bewegungsrichtung ermöglicht.</p>



<p>Beim Beitritt zu einer Session muss zuvor die Session-ID, die man über einen QR-Code oder eine Nachricht erhalten hat, in ein Inputfeld eingegeben werden. Danach geht es automatisch weiter zum nächsten Screen.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1170" height="2532" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/dashboard.png" alt="" class="wp-image-14272" style="width:auto;height:400px" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/dashboard.png 1170w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/dashboard-710x1536.png 710w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/dashboard-946x2048.png 946w" sizes="auto, (max-width: 1170px) 100vw, 1170px" /><figcaption class="wp-element-caption"><strong>Screenshot: Dashboard</strong></figcaption></figure>



<h3 class="wp-block-heading">WaitingScreen</h3>



<p>Am WaitingScreen wird die aktuelle Teilnehmerliste angezeigt. Dort sieht der User, wer sich bereits angemeldet hat. Die Liste aktualisiert sich automatisch, sobald weitere Personen hinzukommen.</p>



<p>Über den Abmelde-Button kann sich der User jederzeit wieder von der Session entfernen. Man wird dabei direkt zurück ins Dashboard geleitet. Sollte jedoch der Host selbst auf „Abmelden“ klicken, wird nicht nur die eigene Verbindung getrennt, sondern die komplette Session gelöscht, inklusive aller Teilnehmerinnen. Auch in diesem Fall gelangen alle automatisch zurück ins Dashboard.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1170" height="2532" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/waitingscreen.jpg" alt="" class="wp-image-14273" style="width:auto;height:400px" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/waitingscreen.jpg 1170w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/waitingscreen-710x1536.jpg 710w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/waitingscreen-946x2048.jpg 946w" sizes="auto, (max-width: 1170px) 100vw, 1170px" /><figcaption class="wp-element-caption"><strong>Screenshot: WaitingScreen</strong></figcaption></figure>



<h3 class="wp-block-heading">QR-Modal</h3>



<p>Für den Ersteller der Session gibt es die Möglichkeit, einen QR-Code zu generieren. Dieser Button befindet sich oberhalb der Teilnehmerliste. Nach dem Klick öffnet sich ein Modal, in dem der QR-Code angezeigt wird. Dieser enthält die Session-ID und kann über einen Button ebenso in die Zwischenablage kopiert werden. Zusätzlich gibt es die Möglichkeit, die Session-ID direkt per Nachricht oder Social Media zu teilen. Wenn der Host entscheidet, dass alle bereit sind, kann die Session jederzeit über den Start-Button gestartet werden.</p>



<p>Sobald der Host einer Session auf “Start” klickt, kommen alle User*innen einer Session auf das Leaderboard. Dort befindet sich das Grundkonzept unserer App. Ganz oben am Screen findet man zwei Tabs, um zwischen 2 Ansichten zu wechseln: das Leaderboard und die Kartenansicht.</p>



<h3 class="wp-block-heading">Leaderboard</h3>



<p>Oben am Bildschirm findet der*die User*in die Ranganzeige. Der eigene Rang wird ziemlich groß dargestellt, damit man sofort erkennt, wo man sich am Leaderboard befindet. Gleich darunter findet sich das eigentlich wichtigste Feature unserer App, nämlich die visuelle Anzeige der Herzfrequenz und der Geschwindigkeit. Die Herzfrequenz wird bei uns in 3 Zonen eingeteilt. In der mittleren Zone befindet sich die &#8220;ideale Herzfrequenz&#8221; für den*die User*in für die aktuelle Aktivität. Sobald man sich in der linken oder in der rechten Zone befindet, bedeutet das, dass die Herzfrequenz zu niedrig bzw. zu hoch ist. Die &#8220;ideale Herzfrequenz&#8221; berechnet sich aus dem Alter des Users bzw. der Userin, damit die Fairness bei Teilnehmer*innen unterschiedlichen Alters erhalten bleibt. Die visuelle Darstellung wurde als Balken gelöst, da wir so die 3 Zonen in Farben unterteilen konnten und die aktive Herzfrequenz auf diesem Balken hin- und herwandern kann. Innerhalb der Balken befindet sich auch die Anzahl der Punkte, die man bekommt, je nachdem, in welcher Zone man sich befindet. Das Punktesystem für die Herzfrequenz wurde so gelöst, dass nur die mittlere Zone, also Zone 2, die meisten Punkte (+5 Punkte) bekommt. Die anderen zwei Zonen bekommen jeweils +2 Punkte. Somit bekommt der*die Nutzer*in alle 3 Sekunden, je nach Zone, die Punkte gutgeschrieben.&nbsp;</p>



<p>Unterhalb des Herzfrequenz-Balkens befindet sich der Geschwindigkeits-Balken, dieser basiert auf dem gleichen Prinzip. Je nach Geschwindigkeit gehen die Punkte nach oben, je schneller desto mehr Punkte. Auch hier wurde der Balken in mehrere Zonen unterteilt, die farblich markiert sind.</p>



<p>Unterhalb der beiden Balken befindet sich auch schon das Leaderboard. Dort werden alle Teilnehmer*innen angezeigt, sowie deren Punktzahl. Alle Punkte werden permanent alle 3 Sekunden geupdatet, damit das Board ständig in Bewegung ist. Wenn sich Plätze ändern, passiert dies in einer überlappenden Animation. Außerdem werden Plätze 1-3 in den klassischen Farben Gold, Silber, Bronze dargestellt.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1170" height="2532" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/leaderboard.jpg" alt="" class="wp-image-14274" style="width:185px;height:auto" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/leaderboard.jpg 1170w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/leaderboard-710x1536.jpg 710w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/leaderboard-946x2048.jpg 946w" sizes="auto, (max-width: 1170px) 100vw, 1170px" /><figcaption class="wp-element-caption"><strong>Screenshot: Leaderboard</strong></figcaption></figure>



<h3 class="wp-block-heading">Kartenansicht</h3>



<p>Auf dieser Seite befindet sich eine Karte von &#8220;Leaflet&#8221;, die in voller Bildschirmgröße dargestellt wird. Sie dient dazu, dass man jederzeit alle Teilnehmer*innen aktiv auf der Karte verfolgen kann, sollte sich beispielsweise ein*e User*in in einer anderen Stadt befinden. Alle Teilnehmer*innen werden jeweils als Dreieck, in einer individuellen Farbe, dargestellt. Wir haben uns für Dreiecke entschieden, weil wir so die Richtung anzeigen können, in die sich ein*e Nutzer*in bewegt. Aufgrund zeitlicher Begrenzung war das auch schon die Funktion unserer Karte.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1170" height="2532" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/map.jpg" alt="" class="wp-image-14275" style="width:auto;height:400px" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/map.jpg 1170w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/map-710x1536.jpg 710w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/map-946x2048.jpg 946w" sizes="auto, (max-width: 1170px) 100vw, 1170px" /><figcaption class="wp-element-caption"><strong>Screenshot: Kartenansicht</strong></figcaption></figure>



<h3 class="wp-block-heading">User-Profil</h3>



<p>Das Userprofile ist sehr simpel gehalten und bietet nur die Möglichkeit, Daten der Nutzer*innen zu ändern, wie zum Beispiel das Alter. Außerdem befindet sich dort der Logout Button.</p>



<h2 class="wp-block-heading">Endpräsentation und Feedback</h2>



<h3 class="wp-block-heading">Ablauf der Präsentation / Abgabe</h3>



<p>Am Nachmittag des fünften und letzten Tags der Extreme Programming Week war es soweit: das Produkt der Woche sollte präsentiert werden. Kurz vor dem ausgemachten Termin mit unseren Masterklasseleitern war es noch recht stressig, da noch einige kleine Bugs aufkamen, die gefixt werden mussten. Trotzdem schafften wir es recht pünktlich, mit der App-Demo anzufangen.</p>



<p>Zuerst installierten wir die App auf unseren Handys: auf Android via Firebase App Distribution und für iOS direkt von Xcode am Laptop auf das iPhone via USB-Kabel. Danach zeigten wir unseren Masterklasseleitern, wie man sich in der App registrieren und einloggen kann, und wie das Dashboard und die Account-Seite aussehen, sobald man eingeloggt ist. Die Herzfrequenz-Sensoren, welche wir zur Verfügung hatten, wurden unterschiedlichen Personen angelegt und mit Handys verbunden.</p>



<p>Schließlich war es Zeit für eine Demonstration der App in einem echten Szenario: eine Person unter uns erstellte eine Session und alle anderen traten dieser bei. Sobald alle drinnen waren, machten wir uns auf den Weg. Während einem Spaziergang rund um das Gebäude (der Rückweg wurde sogar gelaufen!) probierten wir die App aus und beobachteten dabei unsere eigenen Werte (Herzfrequenz, Position, Geschwindigkeit), sowie die Punkte auf dem Leaderboard.</p>



<p>Als wir zu dem Raum der Lehrveranstaltung zurückkehrten, gaben unsere Masterklasseleitern ihr Feedback zu unserem Endprodukt. Dadurch, dass wir die Anforderungen des MVP erfüllten, und auch noch einige Nice-To-Have-Funktionalitäten einbauten, war unser Projekt erfolgreich. Wir freuten uns über die positiven Rückmeldungen und über Ideen für mögliche Erweiterungen und Verbesserungen der App.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="4032" height="3024" data-id="14267" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo1.jpg" alt="" class="wp-image-14267" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo1.jpg 4032w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo1-1536x1152.jpg 1536w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo1-2048x1536.jpg 2048w" sizes="auto, (max-width: 4032px) 100vw, 4032px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="3024" height="4032" data-id="14268" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo2.jpg" alt="" class="wp-image-14268" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo2.jpg 3024w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo2-1152x1536.jpg 1152w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo2-1536x2048.jpg 1536w" sizes="auto, (max-width: 3024px) 100vw, 3024px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="3024" height="4032" data-id="14269" src="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo3.jpg" alt="" class="wp-image-14269" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo3.jpg 3024w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo3-1152x1536.jpg 1152w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/05/demo3-1536x2048.jpg 1536w" sizes="auto, (max-width: 3024px) 100vw, 3024px" /></figure>
<figcaption class="blocks-gallery-caption wp-element-caption"><strong>Interaktive Live-Demo am Parkplatz der FH St. Pölten</strong></figcaption></figure>



<h3 class="wp-block-heading">Erhaltenes Feedback: Verbesserungspotenzial</h3>



<p>Im Laufe der interaktiven Live-Demo und im Anschluss zur Präsentation erhielten wir folgendes Feedback:</p>



<ul class="wp-block-list">
<li>Die WebSocket-Verbindung bricht öfters ab (z.B. beim Wechsel von WLAN zu Mobilen Daten, und auch nach einer Weile von Inaktivität). Eine Möglichkeit, sich (automatisch) wieder verbinden zu können, sollte implementiert werden.</li>



<li>Die Berechnung der Daten (Punkte für das Leaderboard) wird momentan clientseitig durchgeführt. Die Berechnung sollte serverseitig passieren.</li>



<li>Wenn sowohl die Herzfrequenz, als auch die GPS-Daten null sind, verschwindet der visuelle Balken dieser Person im Leaderboard.</li>



<li>Der Code, der eingegeben werden muss, um einer Session beizutreten, sollte kürzer sein. Zusätzlich wäre ein eingebauter QR-Code-Reader cool. (Dies hatten wir eigentlich vor, es ist sich zeitlich aber leider nicht ganz ausgegangen)</li>



<li>Es wäre gut, während der Session sehen zu können…
<ul class="wp-block-list">
<li>…wie akkurat die Daten sind (z.B. Position).</li>



<li>…ob eine Person einen Herzfrequenz-Sensor verbunden hat. (Zusätzlich wäre es von Vorteil, sich während der Session auch später noch mit einem Herzfrequenz-Sensor verbinden zu können.)</li>



<li>…ob eine Person momentan disconnected ist.</li>
</ul>
</li>



<li>Ein Nice-To-Have wäre noch, dass man in dem Leaderboard während der Session auf einzelne User*innen draufklicken kann, um Detaildaten zu der Person zu sehen. Eventuell könnten in der View die Daten der anderen Person auch gleich mit den eigenen verglichen werden.</li>
</ul>



<h2 class="wp-block-heading">Fazit aller Teilnehmer*innen</h2>



<p>Im folgenden Abschnitt möchten wir noch unser Fazit und unsere Erfahrungen teilen, die wir während der Extreme Programming Week sammeln konnten.</p>



<h3 class="wp-block-heading">Katharina</h3>



<p>Ich bin sehr stolz auf das, was wir in diesen fünf Tagen geleistet haben. Die Extreme Programming Week hat nicht nur unsere Zeitmanagement-Skills, sondern auch zum ersten Mal unsere koordinierte Zusammenarbeit als Team auf die Probe gestellt. Ich war positiv überrascht, wie gut dies funktioniert hat &#8211; ich glaube, die täglichen Meetings haben sehr stark zu unserem Erfolg beigetragen.</p>



<p>Meine Aufgaben während der Woche waren unter anderem das Leiten der Meetings, das Testen und Debuggen der nativen Funktionalitäten (insbesondere auf dem iPhone) und Frontend Development. Dabei habe ich mich zum Beispiel intensiv mit Device-Daten (Geolocation, Accelerometer, Gyroskop, etc.) beschäftigt, um diese einerseits in der App anzuzeigen, und andererseits, um sie zur Berechnung von Herzfrequenzzonen, Kalorienverbrauch und sogar einem Schrittzähler zu verwenden. Letzteres hat es aus Zeitgründen leider nicht in das Endprodukt geschafft, aber die Erfahrungen, welche ich dabei gesammelt habe, bleiben mir erhalten.</p>



<p>Im Laufe der Woche hatte ich auch die Möglichkeit, gemeinsam mit Caro im Pair-Programming-Stil an der Authentifizierung im Frontend zu arbeiten. Diese Art des Arbeitens war recht neu für mich, aber ich muss sagen, dass ich eine sehr positive Erfahrung damit gemacht habe &#8211; wenn zwei kreative Köpfe zusammenkommen, kann so einiges entstehen!</p>



<p>Zusammenfassend kann man sagen, dass die Woche recht stressig war, besonders gegen Ende hin, aber ich habe sehr viel dabei gelernt. Vom technischen Know-how bis hin zu Leadership, Zeitmanagement und Team-Skills war alles dabei. Ich wünschte, ich hätte noch mehr Einblick in das Backend und den CI/CD-Prozess bekommen können, aber aus Zeitgründen war das nicht möglich. Alles in allem blicke ich positiv auf die Extreme Programming Week zurück: es war eine spannende Woche voller wertvoller Erfahrungen, welche uns als Team noch enger zusammengeschweißt hat, und aus der ich viel neues Wissen für die Zukunft mitnehme.</p>



<h3 class="wp-block-heading">David</h3>



<p>Ich blicke gerne auf die Wild Week zurück und bin stolz auf das Endprodukt, das wir als Team in der Woche geschaffen haben. Es war schön zu sehen, wie jedes Teammitglied seine bisherigen technischen Erfahrungen bei den verschiedenen Teilaufgaben des Projekts einbringen konnte. Durch das Setup (alle Teammitglieder ständig in einem Raum) konnten wir das Know-How auch sehr gut mit allen teilen.</p>



<p>Sehr motivierend fand ich auch die Aufteilung in tägliche Sprints mit einem Meeting in der Früh, in dem wir immer die Aufgaben definierten und zwischen den Teammitgliedern verteilten, da man so ein festes Ziel für den Tag vor Augen hatte, auf das man hinarbeiten konnte.</p>



<p>Ich konnte auf jeden Fall ein paar persönliche Learnings aus der Wild Week mitnehmen: Da das zu entwickelnde Produkt ja am Freitag zu präsentieren war und dadurch die Zeit ein extrem limitierender Faktor, war es essentiell, sich auf das MVP zu konzentrieren und sich nicht in Details zu verlieren. Das hat im Laufe der Woche mal mehr, mal weniger gut geklappt. Es ist auch gar nicht so leicht, stets den Fokus auf die Grundfunktionalität zu behalten, da man bei Projekten mit kompletter Entscheidungsfreiheit als Entwickler automatisch darüber nachdenkt, welche Features man nicht noch hinzufügen könnte. Gegen Ende der Woche hat sich das Pareto-Prinzip aus meiner Sicht auch wieder zum Teil bewahrheitet. Durch Erfolgsmomente am Anfang des Projekts ist man leicht dazu verleitet anzunehmen, dass die Entwicklungsgeschwindigkeit im selben Tempo bis zum Abschluss beibehalten werden kann &#8211; was sich nicht bewahrheitet hat. In einem zukünftigen Projekt dieser Art wäre es für mich wichtig, mehr Fokus darauf zu legen, wirklich beim MVP zu bleiben und den ganzen Entscheidungsprozess über zusätzliche Features erst gar nicht aufkommen zu lassen.</p>



<p>Aus technischer Sicht fand ich super, mich wieder mehr mit React beschäftigen zu können. Hier habe ich einiges an Know-How aus der Woche mitnehmen können. Zusätzlich fand ich die Diskussionen mit meinen TeamkollegInnen über Architekturentscheidungen sehr spannend und fand es super, das ganze Tech Setup inkl. CI/CD für ein Projekt dieser Art von Grund auf einzurichten. Es war auch das erste Mal, dass ich an einer App gearbeitet habe, die hauptsächlich Websockets als Kommunikationskanal verwendet &#8211; es war spannend, mal mit einem anderen Schnittstelle als REST zu arbeiten.</p>



<h3 class="wp-block-heading">Andreas</h3>



<p>8 Teammitglieder, fast 5 Tage Entwicklungszeit und eine gemeinsame App-Idee realisieren – das war unser intensives und lehrreiches Projekt am Anfang des 2. Semesters, aus dem ich persönlich viel mitnehmen konnte. Die Woche war geprägt von enger Teamkommunikation, klarer Aufgabenverteilung und vielen kleinen Abstimmungen, die am Ende zu einem funktionierenden Gesamtprodukt geführt haben. Besonders interessant war für mich, wie unterschiedlich einzelne Teammitglieder an Aufgaben herangegangen sind – sowohl inhaltlich als auch methodisch. Dabei habe ich nicht nur verschiedene Denkansätze kennengelernt, sondern auch praktische Coding-Tipps und Lösungsstrategien aufgeschnappt, die mir in Zukunft sicher weiterhelfen werden.</p>



<p>Mein Fokus lag zu Beginn auf der Planung unserer Datenbank. Zusammen mit Matthias habe ich verschiedene Datenbanktypen – wie z.B. relationale, NoSQL und Time-Series DBs – hinsichtlich ihrer Eignung für unseren Use Case bewertet. Auf Basis dieser Überlegungen sind wird bei einer klassischen relationalen DB geblieben, für die Matthias und ich ein erstes ER-Diagramm entworfen haben, das wir anschließend im Team besprochen und gemeinsam überarbeitet haben. Auch wenn dieser Prozess Zeit gekostet hat, konnten wir dadurch eine saubere, tragfähige Struktur aufsetzen, die sich später fast vollständig problemlos in NestJS integrieren ließ. Im weiteren Verlauf (nachdem der technische Aufbau der DB gestanden ist) habe ich mich verstärkt dem Frontend gewidmet, insbesondere der Nebenmaske für die User*innendaten, die noch nicht von meinen Kolleg*innen bearbeitet wurden. Dort konnte ich eigenständig erste Komponenten entwickeln, gerade bei Bereichen mit direktem Bezug zur Datenbank. Bei komplexeren Problemen habe ich auf Pair Programming gesetzt, um gemeinsam mit dem gebündelten Stärken meiner Kolleg*innen gezielte Lösungen zu finden.</p>



<p>Eine besondere Herausforderung war auch für mich der Umgang mit dem begrenzten Zeitrahmen bei gleichzeitigem Anspruch auf sauberen, wartbaren Code. Ich habe gelernt, wie entscheidend es ist, in der Entwicklung frühzeitig sinnvolle Prioritäten zu setzen – also die „richtige“ Reihenfolge zu finden: Was muss funktionieren, was ist optional, und was kann man notfalls zurückstellen? Diese Balance war nicht immer einfach, aber essenziell, um alle Kernfunktionen zuverlässig umzusetzen. Mein Versuch, am Ende noch die Safe-Area technisch sauber zu integrieren, ist trotz mehrerer Ansätze gescheitert – aber genau daraus habe ich am meisten gelernt: Nicht jede Idee lässt sich unter Zeitdruck noch sinnvoll umsetzen, und pragmatisches Handeln ist oft wichtiger als Perfektion im Detail.<br><br>Um mein Fazit abzurunden, möchte ich gerne festhalten, dass dieses Projekt nicht nur meine technischen Fähigkeiten weiterentwickelt, sondern auch mein Verständnis für effiziente Teamarbeit unter Druck geschärft hat. Besonders der Umgang mit begrenzter Zeit und die bewusste Fokussierung auf das Wesentliche haben mir gezeigt, worauf es in realen Entwicklungsprozessen wirklich ankommt.</p>



<h3 class="wp-block-heading">Felix</h3>



<p>Die Programming Week war für mich auf jeden Fall ein Highlight. In einer relativ großen Gruppe so ein Projekt in nur 5 Tagen umzusetzen war nicht nur super anstrengend, sondern auch spannend und lustig. Ich muss echt sagen, dass ich sehr viel gelernt habe, auch wenn ich leider von manchen Bereichen des Projekts nicht so viel mitbekommen habe, was aber durchaus verständlich ist, wenn man unter diesem Zeitdruck steht.</p>



<p>Ich habe viel im Pair-Programming gearbeitet und das vor allem am Frontend. Das war für mich echt nützlich, da ich so schneller in das Projekt und in React reinfinden konnte. Ich habe mit Caro zuallererst begonnen, dass wir den Heart-Rate-Sensor mit Bluetooth verbinden können und die Daten auslesen können, das hat Anfangs ein bisschen schwierig funktioniert, aber dann haben wir zusammen auch schnell eine Lösung gefunden, was gerade am ersten Tag super motivierend war. Auch sonst war das gesamte Projekt sehr gut aufgebaut, weil wir jeden Tag mit einem Meeting begonnen haben, um die heutigen Ziele festzulegen. Anfangs dachte ich, dass wird ja dann echt einfach am Freitag fertig zu werden, wenn alles so schnell weitergeht, aber wie so oft unterschätzt man dann den Stress der letzten Tage. Wie ich schon einmal erwähnt habe, hätte ich noch sehr gerne mehr in das Backend und in die Websockets geschaut, aber leider war das zeitlich nicht mehr ganz möglich, aber dafür konnte ich im Frontend fast überall mitarbeiten, was natürlich auch dort mein Wissen verbessert hat.</p>



<p>Das gesamte Projekt haben wir echt gut als Gruppe gemeistert. Wir hatten Spaß, waren gestresst und haben alle glaube ich sehr viel dabei gelernt. Das Endprodukt konnte sich bei der Präsentation auch sehen lassen, außer vielleicht ein paar kleine Bugs. Ich konnte auf jeden Fall sehr viel lernen und würde diese Art von Projekt gerne wiederholen, auch wenn eine Pause nach dieser Woche sehr gut getan hat.&nbsp;</p>



<h3 class="wp-block-heading">Caroline</h3>



<p>Es war sehr spannend zu sehen, wie viel man zu acht in einer Woche bzw. 5 Tagen schafft zu entwickeln. Ich habe mich vor allem mit dem Frontend beschäftigt und dabei meist Pair Programming mit verschiedenen Personen betrieben. Dieses Konzept ist mir bereits aus dem Bachelor bekannt und mir persönlich gefällt es sehr gut, da man so schneller Fehler bemerkt.</p>



<p>Montags habe ich mich mit Felix um die Verbindung zum Heart Rate Sensor gekümmert. Anfangs gab es ein paar Schwierigkeiten, doch dann folgte das Erfolgserlebnis. Die Verwendung von HRMs und Bluetooth LE war für mich neu, aber sehr interessant. Dienstags habe ich mich vor allem mit dem Login- und Registrierungs-Screen beschäftigt und dafür anfangs Farben und Schriftarten global definiert und Tailwind aufgesetzt. In Bezug auf die Formulare auf den zwei Screens nutze ich React Hook Form, wobei ich die Library zu einem späteren Zeitpunkt ersetzt habe, da der State nicht immer aktualisiert wurde. Nachdem wir am Mittwoch unser UI-Konzept und die Datenvisualisierung überarbeitet hatten, habe ich mit Felix die Umsetzung des LiveActivity-Screens begonnen. Donnerstags war ich mit Katharina für den Authentifizierungscheck beim Aufruf gewisser Routen verantwortlich und habe Andi beim Bearbeiten der Profilinformationen geholfen. Am letzten Tag war Endspurt angesagt und somit auch Bug Fixing. Dabei habe ich einerseits David bei der Verwendung der WebSockets im Frontend unterstützt, andererseits Matthias bei der Session Erstellung/Teilnahme.</p>



<p>Ich finde, wir haben das als Gruppe sehr gut gemeistert, mit dem Daily Planning am Anfang war klar definiert, was gemacht wird, und das Endprodukt (bis auf die paar Bugs) kann sich sehen lassen. Vor allem was die Verbindung mit den Sensoren und die Erstellung eigener sogenannter Guarded Routes betrifft, habe ich einiges gelernt, was auch in Zukunft hilfreich sein könnte. Neben den technischen Aspekten habe ich nochmals gesehen, wie wichtig es ist, sich zuerst auf das MVP zu konzentrieren und sicherzustellen, dass das die anderen auch tun, da man sonst Zeit verliert und sich verrennen kann.</p>



<h3 class="wp-block-heading">Sebastian</h3>



<p>Die Wild Week war ein wirklich interessantes und spannendes Erlebnis. Ein ganzes Projekt in nicht einmal 5 Tagen auf die Beine zu stellen war extremst stressig, aber auch wirklich toll zu sehen, was man eigentlich in so kurzer Zeit auf die Beine stellen kann, wenn man sich wirklich ins Zeug lägt. Auch konnte ich einiges aus dieser Woche mitnehmen.</p>



<p>Zum einen hatte ich bisher noch keine Erfahrung mit Ionic in Verbindung mit React. Ich habe nur Ionic und Angular oder React Native verwendet, aber nicht beide zusammen. Auch habe ich einiges über die Verwendung von Herz Sensoren erfahren, auch wenn meine Erfahrung hier etwas kurz gekommen ist, da ich größtenteils im Backend zuständig war. Ich hätte sehr gerne auch andere Bereiche mir angeschaut, aber aufgrund des Zeitstresses ist es verständlich, dass dies nicht wirklich möglich war. In der Woche habe ich manchmal allein gearbeitet, zum Beispiel für die Erforschung, wie das Accelerometer im Handy funktioniert oder im Backend die Datenspeicherung über die passenden Endpoints zu ermöglichen, habe aber auch einiges im Pair Programming gemacht. Auf beiden Seiten. Auch wenn ich diese Technik schon aus dem Bachelor kannte, ist es trotzdem immer interessant zu sehen, wie gut Pair Programming funktioniert. Eine weitere Person neben sich zu haben, die sich nur darauf konzentrieren kann, was geschrieben wird und sofort erkennen kann, wenn man eine Sache vergisst oder welche einem bei Problemen hilft, ist sehr wertvoll, vor allem wenn nicht jede Person im Team an einer eignen Sache arbeiten kann.</p>



<p>Im großen und ganzem finde ich das die Wild Week wirklich toll gelaufen ist. Wir haben uns viel vorgenommen, dies aber auch toll hinbekommen. Mit den Daily Stand-ups, welche wir immer in der Früh gemacht haben, konnten wir uns jeden Tag auf unsere Ziele festlegen und auf diese fokussieren. Man konnte auch wirklich gut erkenne, weshalb das Prinzip eines MVPs existiertet. Ich hätte nichts dagegen, einmal wieder so ein Projekt zu wiederholen.</p>



<h3 class="wp-block-heading">Jan</h3>



<p>Es war eine spannende Woche! In fünf Tagen haben wir viel diskutiert, Entscheidungen getroffen und fleißig in die Tasten gehauen. Das Ergebnis ist ein Proof of Concept, der unsere interessante App-Idee greifbar macht. Mit diesem Ergebnis sind wir insgesamt sehr zufrieden. Allerdings schwingt beim „insgesamt“ auch ein kleiner Vorbehalt mit: Hätten wir vielleicht noch mehr aus dieser Woche herausholen können?</p>



<p>Viel Zeit hat unser Team zur Konzeption der App aufgewendet. Diese Zeit scheint mir rückblickend gut investiert. Es war wichtig, eine Idee auszuarbeiten, die wir spannend und sinnvoll fanden. Erst mit dieser klaren Vorstellung konnten wir mit Elan loslegen. Unsere Schwächen sehe ich eher bei der Aufteilung und Priorisierung der Arbeit. Die Features der App haben wir in Backend und Frontend unterteilt und zu unabhängig voneinander umgesetzt. Das führte dazu, dass im Backend Funktionen implementiert wurden, die im Frontend letztlich keine Verwendung fanden. Wie im Kapitel zu CI/CD erwähnt, haben wir außerdem zu viel Energie in unsere Pipelines gesteckt. Ein weiteres Problem der Aufteilung war, dass das Zusammenführen der Arbeiten erst spät erfolgte, wodurch wir auch erst spät auf Probleme aufmerksam wurden. Sinnvoller wäre es wohl gewesen, wenn Sub-Teams End-to-End an einzelnen Features gearbeitet hätten, sodass die App schrittweise gewachsen wäre.</p>



<p>Insgesamt war es jedoch eine produktive Woche, in der wir als Team nicht nur viel geschafft, sondern auch viel Spaß gehabt haben. Es war wirklich schön, sich fünf Tage lang intensiv in ein völlig neues Thema zu vertiefen – eine willkommene Abwechslung! Die Erfahrungen aus dieser Woche und das gestärkte Teamgefühl werden uns im nächsten Projektsemester mit Sicherheit zugutekommen.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/blog-movemates/">Blog | MoveMates</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Workshop &#124; Einführung in Svelte</title>
		<link>https://mobile.fhstp.ac.at/workshop/workshop-einfuehrung-in-svelte/</link>
		
		<dc:creator><![CDATA[Matthias Frankowski]]></dc:creator>
		<pubDate>Sun, 16 Mar 2025 14:31:24 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Trends]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=14002</guid>

					<description><![CDATA[<p>Im Rahmen meines Workshops in der Masterklasse Mobile im 1. Semester des Studiengangs Interactive Technologies habe ich einen ersten Überblick über Svelte und SvelteKit gegeben. Diese Technologien bieten eine spannende Alternative, besonders wenn es um die schnelle Entwicklung von Prototypen geht. Viele Studierende haben bereits mit Frameworks wie Ionic, Angular, Vue oder React gearbeitet, weshalb <a class="read-more" href="https://mobile.fhstp.ac.at/workshop/workshop-einfuehrung-in-svelte/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-einfuehrung-in-svelte/">Workshop | Einführung in Svelte</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Im Rahmen meines Workshops in der Masterklasse Mobile im 1. Semester des Studiengangs Interactive Technologies habe ich einen ersten Überblick über Svelte und SvelteKit gegeben. Diese Technologien bieten eine spannende Alternative, besonders wenn es um die schnelle Entwicklung von Prototypen geht. Viele Studierende haben bereits mit Frameworks wie Ionic, Angular, Vue oder React gearbeitet, weshalb ich auch den Vergleich zu diesen Ansätzen kurz beleuchtet habe. Zunächst stellte ich in einer kompakten Präsentation die zentralen Punkte vor, bevor wir im praktischen Teil des Workshops gemeinsam eine kleine Anwendung entwickelten, um den direkten Nutzen von SvelteKit zu demonstrieren.</p>



<h2 class="wp-block-heading"><strong>Was ist Svelte?</strong></h2>



<p>Svelte ist ein modernes Frontend-Framework, das anders arbeitet als traditionelle Webentwicklungs-Bibliotheken. Der große Unterschied: Während viele andere Frameworks während der Ausführung im Browser mit einer virtuellen DOM-Struktur arbeiten, verwandelt Svelte den Code bereits beim Erstellen (dem sogenannten Build-Prozess) in reines JavaScript. Dadurch entstehen Webseiten, die meistens schneller und effizienter funktionieren, weil sie unnötigen Zusatzaufwand vermeiden.</p>



<h2 class="wp-block-heading"><strong>Was ist SvelteKit?</strong></h2>



<p>SvelteKit baut auf dieser Grundlage von Svelte auf und ist ein umfassendes Application Framework, das die Webentwicklung noch leichter macht. Mit SvelteKit kann man moderne Webanwendungen schneller umsetzen, da es bereits nützliche Funktionen mitbringt: ein durchdachtes Routing-System für die Navigation zwischen Seiten, serverseitiges Rendering (die Seite wird schon auf dem Server zusammengebaut) und die Möglichkeit, statische Seiten zu erzeugen.</p>



<h2 class="wp-block-heading"><strong>Entstehung und Versionen</strong></h2>



<p>Die Geschichte von Svelte begann 2016 mit der ersten Version, die schon damals einen neuen, einfacheren Ansatz für Webentwicklung bot. Im Laufe der Zeit wurden mit jeder neuen Version die Komponenten und die Programmiersprache immer besser. Besonders mit Version 3 im Jahr 2019 schaffte Svelte den Durchbruch, indem es eine komplett neue Art der Reaktivität (wie Elemente auf Änderungen reagieren) einführte. Die Einführung von SvelteKit im Jahr 2020 und die neuesten Entwicklungen in Svelte 5 (2024) zeigen, dass sich das Framework ständig weiterentwickelt und immer neue Funktionen und Verbesserungen bekommt.</p>



<h2 class="wp-block-heading"><strong>Warum Svelte?</strong></h2>



<p>Im Vergleich zu Frameworks wie React und Vue hat Svelte den Vorteil, dass es direkter und einfacher zu nutzen ist. Während du bei React und Vue oft komplizierte Lösungen für die Zustandsverwaltung (State Management) und man zusätzliche Bibliotheken braucht, bietet Svelte eine unkomplizierte und sofortige Reaktivität. Das bedeutet weniger &#8220;Füllcode&#8221; (Boilerplate-Code), was den Einstieg und die tägliche Arbeit deutlich vereinfacht. Auch die in SvelteKit eingebaute Navigation zwischen Seiten hilft dabei, den Entwicklungsaufwand gering zu halten.</p>



<p class="has-medium-font-size"><strong>Einsatzbereiche</strong>:</p>



<p>Svelte kann in verschiedenen Bereichen eingesetzt werden: für Single Page Applications, für serverseitig gerenderte Anwendungen, für statische Websites sowie für mobile Anwendungen und Progressive Web Apps. Die Vielseitigkeit und Einfachheit dieser Technologien machen sie zu einem idealen Werkzeug für schnelle Prototypen oder innovative Webprojekte.</p>



<p class="has-medium-font-size"><strong>Vor- und Nachteile</strong>:</p>



<p>Natürlich hat jedes Framework seine Stärken und Schwächen. Zu den Vorteilen von Svelte gehören die einfache und intuitive Programmiersprache sowie der reduzierte Füllcode, was zu schnelleren Ladezeiten und einer besseren Performance führt. Auf der anderen Seite ist das Ökosystem um Svelte noch nicht so groß wie bei etablierten Frameworks wie React oder Vue. Das bedeutet, dass es weniger Community-Ressourcen und verfügbare Erweiterungen gibt. Bei sehr komplexen Anwendungen könnte es außerdem nötig sein, zusätzliche Werkzeuge einzusetzen, um alle Anforderungen zu erfüllen.</p>



<div style="height:35px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><strong>Übungsbeispiel: Mini Quiz App</strong></h2>



<p>Da wir in der Masterklasse eine Quiz-App mithilfe von Ionic und Angular umsetzten, entschied ich mich, eine vereinfachte Version dieses Projekts mit Svelte zu realisieren – so konnten die besonderen Vorzüge dieser Alternative klar hervorgehoben werden. Um den Aufwand nicht unnötig zu steigern, wurde auf ein detailliertes Styling verzichtet, da der Unterschied lediglich darin liegt, dass das CSS direkt in der jeweiligen Komponente definiert wird, während die Syntax ansonsten identisch bleibt.<br><br>Zu Beginn wurde ein neues Projekt erstellt und konfiguriert. Mit wenigen Befehlen wie:</p>



<p class="has-text-align-center"><code>npx sv create new-quiz-app&nbsp;</code><br><code>cd my-quiz-app&nbsp;</code><br><code>npm install&nbsp;</code><br><code>npm run dev -- --open&nbsp;</code></p>



<p class="has-text-align-left">konnte das Grundgerüst der App schnell aufgesetzt werden. Im Anschluss erklärte ich die grundlegende Verzeichnisstruktur des Projekts und was beim Routing zu beachten ist.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>Fragen-Daten erstellen</strong></li>
</ul>



<p>Nachdem die Struktur klar war, zeigte ich, wie man in der Datei&nbsp;src/lib/data.js&nbsp;die Quiz-Daten anlegt. Hier wurden die Fragen und Antwortoptionen direkt als Export definiert – ein Ansatz, der den Verzicht auf zusätzliche Services oder Dependency Injection ermöglicht und somit die einfache Handhabung unterstreicht.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="642" height="493" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Bildschirmfoto-2025-03-15-um-22.25.48.png" alt="" class="wp-image-14004"/></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>Landing-Page erstellen</strong></li>
</ul>



<p>Die nächste Etappe war die Erstellung der Landing Page in <em>src/routes/+page.svelte</em>. Diese Startseite enthält einen Button, der über die eingebaute goto()-Funktion den Nutzer zur Quiz-Seite weiterleitet – ein Beispiel für die unkomplizierte Navigation in SvelteKit.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="563" height="175" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Bildschirmfoto-2025-03-15-um-22.34.06.png" alt="" class="wp-image-14010"/></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>Quiz-Seite erstellen</strong></li>
</ul>



<p>Auf der eigentlichen Quiz-Seite, realisiert in<em> src/routes/quiz/+page.svelte</em>, wurden die Fragen dynamisch dargestellt. Mittels einer Schleife wurden die Antwortoptionen gerendert und durch reaktive Variablen konnte das UI sofort auf Nutzereingaben reagieren. Nach Beantwortung der letzten Frage wurde der Punktestand an die Ergebnis-Seite übergeben, was durch die Reaktivität ermöglicht wird.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="633" height="391" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Bildschirmfoto-2025-03-15-um-22.34.20.png" alt="" class="wp-image-14011"/></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>Ergebnis Seite erstellen</strong></li>
</ul>



<p>Auf der Ergebnis-Seite in <em>src/routes/result/+page.svelte</em> wird abschließend der finale Punktestand angezeigt. Durch den Einsatz von optionalem Chaining wird sichergestellt, dass bei fehlenden Daten ein Standardwert genutzt wird. Zudem gibt es hier einen Button, der es ermöglicht, das Quiz neu zu starten.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="578" height="239" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Bildschirmfoto-2025-03-15-um-22.34.58.png" alt="" class="wp-image-14012"/></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li><strong>Einsatz eines Stores</strong></li>
</ul>



<p>Als Erweiterung zur Datenübergabe zwischen den Seiten habe ich einen zentralen Store in&nbsp;src/lib/stores.jseingerichtet. Dieser speichert den Score und stellt sicher, dass der Punktestand auch bei Navigationen zwischen den Komponenten erhalten bleibt – ein klarer Vorteil gegenüber Frameworks, die häufig komplexere Lösungen erfordern.</p>



<div style="height:35px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Fazit</h2>



<p>Das Übungsbeispiel wurde gut umgesetzt – die Mitwirkenden waren sehr aufmerksam und haben eine eingebaute Challenge zügig gelöst. Es hat mich positiv überrascht, wie reibungslos die Zeit genutzt werden konnte. Durch Beobachtungen aus früheren Workshops habe ich gelernt, das Tempo den Bedürfnissen der Teilnehmer anzupassen. Daher habe ich den praktischen Teil bewusst einfacher gehalten und zusätzliche Aufgaben vorbereitet, falls mehr Zeit zur Verfügung gestanden hätte. Insgesamt konnten wir den Ablauf in einem ruhigen und strukturierten Rahmen durchgehen.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Es hat mir viel Freude bereitet und war zugleich sehr lehrreich. Ich hoffe, ich konnte einen guten Einblick in Svelte vermitteln, der uns als wertvoller Anstoß für unsere künftigen Entscheidungen bei der Framework-Auswahl dient. Im Folgenden finden sich die Folien, die während der theoretischen Einführung im Workshop verwendet wurden:</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Workshop_Svelte_Frankowski.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Presentation_Workshop_Svelte_Frankowski."></object><a id="wp-block-file--media-cfd9b11e-5d40-490a-8f99-71ece383fa93" href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Workshop_Svelte_Frankowski.pdf">Presentation_Workshop_Svelte_Frankowski</a><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Workshop_Svelte_Frankowski.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-cfd9b11e-5d40-490a-8f99-71ece383fa93">Herunterladen</a></div>



<p>Weitere Informationen und praxisnahe Einblicke in Svelte finden sich auf der <a href="https://svelte.dev/">offiziellen Svelte Homepage</a>. Besonders empfehlenswert ist das <a href="https://svelte.dev/tutorial">interaktive Svelte Tutorial</a>, das einen gut strukturierten Einstieg in das Framework bietet.</p>



<p></p>
<p>The post <a href="https://mobile.fhstp.ac.at/workshop/workshop-einfuehrung-in-svelte/">Workshop | Einführung in Svelte</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Workshop &#124; CMS-System Typo3</title>
		<link>https://mobile.fhstp.ac.at/allgemein/workshop-cms-system-typo3/</link>
		
		<dc:creator><![CDATA[Andreas Kaiser]]></dc:creator>
		<pubDate>Thu, 06 Mar 2025 08:09:05 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Workshop]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=13297</guid>

					<description><![CDATA[<p>Im Rahmen meines Workshops, den ich im 1. Semester des Masterstudiengangs Interactive Technologies (Mobile) gehalten habe, habe ich eine Kurzvorstellung des CMS-Systems Typo3 gegeben.Um den Wissensstand meiner Kolleg:innen bezüglich CMS-Systemen und insbesondere Typo3 besser einzuschätzen, führte ich zu Beginn eine kurze Umfrage durch. Das Ergebnis zeigte, dass ein grundsätzliches Verständnis über CMS-Systeme vorhanden war, jedoch <a class="read-more" href="https://mobile.fhstp.ac.at/allgemein/workshop-cms-system-typo3/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/workshop-cms-system-typo3/">Workshop | CMS-System Typo3</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Im Rahmen meines Workshops, den ich im 1. Semester des Masterstudiengangs Interactive Technologies (Mobile) gehalten habe, habe ich eine Kurzvorstellung des CMS-Systems Typo3 gegeben.<br>Um den Wissensstand meiner Kolleg:innen bezüglich CMS-Systemen und insbesondere Typo3 besser einzuschätzen, führte ich zu Beginn eine kurze Umfrage durch. Das Ergebnis zeigte, dass ein grundsätzliches Verständnis über CMS-Systeme vorhanden war, jedoch Typo3 weitgehend unbekannt blieb. Daher entschied ich mich, mich auf die wesentlichen Grundlagen zu konzentrieren – von der Installation, die sich als herausfordernd erweisen kann, bis hin zur Bedienung der CMS-Oberfläche.</p>



<h1 class="wp-block-heading">Theorie</h1>



<p>Die wesentlichen theoretischen Inputs, die damals vermittelt wurden, sind hier zusammengefasst:</p>



<p>Typo3 ist eines der leistungsfähigsten Open-Source-Content-Management-Systeme (CMS) und bietet eine Vielzahl an Funktionen, die es besonders für große Webprojekte und Unternehmensseiten attraktiv machen. Als CMS ermöglicht es eine klare Trennung zwischen Inhalt und Design, sodass Redakteure und Administratoren Inhalte flexibel verwalten können, ohne in das technische Grundgerüst eingreifen zu müssen. Die Struktur eines CMS basiert auf mehreren Schichten, darunter die Anwendungs-, Verwaltungs-, Logik-, Präsentations-, Datenhaltungs- und Nutzerschicht, die gemeinsam ein stabiles und skalierbares System bilden. Das Backend von Typo3 ist dabei das zentrale Steuerungselement, das den Zugriff auf verschiedene Module, den hierarchischen Seitenbaum und die Verwaltung der Inhalte ermöglicht. Besonders wichtig ist die Konfigurationssprache TypoScript, mit der sich das Erscheinungsbild und die Funktionalität der Webseite individuell anpassen lassen, indem Templates eingebunden und dynamische Elemente wie Menüs oder Bilder gesteuert werden. Typo3 zeichnet sich durch eine hohe Skalierbarkeit, eine umfangreiche Mehrsprachigkeitsunterstützung und hohe Sicherheitsstandards aus, jedoch erfordert es auch eine gewisse Einarbeitungszeit, da die Lernkurve insbesondere für Neueinsteiger steil ist. Zudem bringt die regelmäßige Wartung und Aktualisierung des Systems einen gewissen Aufwand mit sich, weshalb individuelle Anpassungen meist tiefergehende Kenntnisse und Entwicklungsarbeit erfordern. Ein besonders wichtiger Aspekt von Typo3 sind die sogenannten Extensions, mit denen sich die Funktionalität des CMS erweitern lässt. Diese können entweder direkt aus dem offiziellen Typo3 Extension Repository installiert oder durch eigene Entwicklungen mithilfe von Extbase, einem PHP-Framework, und Fluid, einer leistungsstarken Template-Engine, erstellt werden. Durch die hohe Anpassungsfähigkeit eignet sich Typo3 vor allem für komplexe Webprojekte, die besondere Anforderungen an Struktur, Mehrsprachigkeit und Sicherheit stellen.</p>



<h1 class="wp-block-heading">Praxis</h1>



<p>Im praktischen Teil verfolgte ich das Ziel meinen Kolleg:innen von Grund auf eine Typo3 Installation und das Zurechtfinden auf der Typo3 Oberfläche zu zeigen. </p>



<h2 class="wp-block-heading">Erste Schritte </h2>



<p>Typo3 kann direkt von der offiziellen Webseite (<a href="https://typo3.org">https://typo3.org</a>) heruntergeladen werden. Für den Workshop haben wir die aktuelle Long-Term-Support (LTS) Version genutzt. Nach dem Download lag die gezippte Datei vor, die zunächst entpackt und in das htdocs-Verzeichnis vom Tool &#8220;xampp&#8221; verschoben werden musste. <br>Wichtig: Damit Typo3 später reibungslos läuft, muss sichergestellt werden, dass der Server die nötigen Voraussetzungen erfüllt: PHP in der richtigen Version, MySQL oder MariaDB als Datenbank, &#8230;</p>



<h2 class="wp-block-heading">Installation</h2>



<p>Nach dem Platzieren des entzippten Folders im htdocs-Verzeichnis und dem Anlegen einer leeren Datenbank in phpmyadmin haben wir die Installation über den Browser gestartet (Apache muss dabei über xampp laufen). Dabei traten einige typische Warnings/Errors auf (nicht aktive PHP-Module aktivieren oder z.B. das Memory-Limit fielen darunter), die es nur bei der Erstinstallation gibt. Diese haben wir gemeinsam gelöst (man findet zu all den Warnings/Errors Lösungsansätze im Internet). Danach musst nur noch die leere DB (vorhin angelegt) dem System mitgeteilt werden und für den späteren Login ein User Account angelegt werden.</p>



<h2 class="wp-block-heading"><strong>CMS-Oberfläche und erste Schritte</strong></h2>



<p>Nach dem ersten Login ins Backend haben wir uns die Struktur von Typo3 genauer angesehen. Besonders wichtig war der Seitenbaum, der die hierarchische Struktur der Webseite darstellt und das zentrale Element für die Verwaltung ist. Wir haben eine erste Seite erstellt, Inhalte hinzugefügt und die grundlegenden Funktionen der Typo3-Module kennengelernt. Dabei wurde schnell deutlich, dass Typo3 eine Vielzahl an Einstellungsmöglichkeiten bietet, aber dadurch auch eine gewisse Einarbeitungszeit erfordert.</p>



<h2 class="wp-block-heading"><strong>Extensions und TypoScript</strong></h2>



<p>Um einen ersten praktischen Einblick in TypoScript zu gewinnen, wurde anhand eines kleinen Codebeispiels grundlegende auf die Syntax eingegangen &#8211; dieses kann man sich gut in meiner (unten angeführten) Installation anschauen. Abschließend kamen wir noch zu den Extensions (ein wichtiges Tyo3 Feature). Über das Extension Repository<strong> </strong>(siehe Abschnitt Extensions) wollten wir eine einfache Erweiterung installieren, um sie in das System einzubinden. Leider war die ausgewählte Extension fehlerhaft, sodass eine weitere praktische Auseinandersetzung nicht möglich war.</p>



<h2 class="wp-block-heading">Resümee</h2>



<p>Der Workshop an sich war eine sehr lehrreiche Erfahrung, da ich zuvor noch nie selbst in der Situation war einen Workshop abzuhalten. Die Herangehensweise erforderte viel Kreativität, um bestmöglich Theorie und Praxis an meine Kolleg:innen zu vermitteln. Auch Plan und Realität kann schnell auseinander driften. Das konnte ich bei meinem Workshop feststellen, da im Praxisteil mehr geplant war als sich dann ausging. Dann reicht auch nur eine Situation, wo meine Kolleg:innen noch mehr Probleme bei der Installation hatten, als ich eigentlich angenommen hatte. Im Endeffekt konnte ich den Workshop dann aber auch in der etwas abgespeckten Version über die Runde bringen &#8211; jeder hatte am Schluss eine lauffähiges CMS-System und konnte Typo3&#8217;s Eigenheiten wahrnehmen bzw. sich mit der ein oder anderen Konfig. vertraut machen.</p>



<p>Anbei sind die Folien, die ich während des Workshops genutzt habe, zum Nachlesen:</p>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2024/12/Typo3_Workshop_Kaiser.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Typo3_Workshop_Kaiser."></object><a id="wp-block-file--media-bfd4d808-71fb-46bc-8e5f-2ede2fb77557" href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2024/12/Typo3_Workshop_Kaiser.pdf">Typo3_Workshop_Kaiser</a><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2024/12/Typo3_Workshop_Kaiser.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-bfd4d808-71fb-46bc-8e5f-2ede2fb77557">Herunterladen</a></div>



<p>Hier ist der .zip Ordner meiner damaligen Typo3 Installation: folgt</p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/workshop-cms-system-typo3/">Workshop | CMS-System Typo3</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Workshop &#124; Kotlin Multiplatform mit Compose</title>
		<link>https://mobile.fhstp.ac.at/development/workshop-kotlin-multiplatform-mit-compose/</link>
		
		<dc:creator><![CDATA[David Grünberger]]></dc:creator>
		<pubDate>Mon, 03 Mar 2025 21:12:15 +0000</pubDate>
				<category><![CDATA[Cross Plattform]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Native Development]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Trends]]></category>
		<category><![CDATA[Workshop]]></category>
		<category><![CDATA[Compose]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Kotlin Multiplatform]]></category>
		<guid isPermaLink="false">https://akirchknopf-21110.php.fhstp.cc/?p=13841</guid>

					<description><![CDATA[<p>Meinen erster Workshop in der Masterklasse Mobile im 1. Semester hielt ich zum Thema Kotlin Multiplatform mit Compose.Ziel dieses Workshops war es, den Teilnehmern sowohl eine kurze Einführung in die Programmiersprache Kotlin zu geben, als auch einen groben Überblick über die Cross-Platform-Technologie Kotlin Multiplatform inklusive dem deklarativen Design-Toolkit Compose.Nachdem die Teilnehmer schon mit der Programmiersprache <a class="read-more" href="https://mobile.fhstp.ac.at/development/workshop-kotlin-multiplatform-mit-compose/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/workshop-kotlin-multiplatform-mit-compose/">Workshop | Kotlin Multiplatform mit Compose</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Meinen erster Workshop in der Masterklasse Mobile im 1. Semester hielt ich zum Thema Kotlin Multiplatform mit Compose.<br>Ziel dieses Workshops war es, den Teilnehmern sowohl eine kurze Einführung in die Programmiersprache Kotlin zu geben, als auch einen groben Überblick über die Cross-Platform-Technologie Kotlin Multiplatform inklusive dem deklarativen Design-Toolkit Compose.<br>Nachdem die Teilnehmer schon mit der Programmiersprache Java vertraut waren, konzentrierte ich mich bei der Theorie zu Kotlin hauptsächlich auf die Unterschiede und Vorteile in der Sprache im Vergleich zu Java.<br>Nach dem Theorieteil zu den drei Themen wurde gemeinsam mit den Teilnehmern eine Übung am Projektor durchgeführt.</p>



<h2 class="wp-block-heading">Kotlin</h2>



<h3 class="wp-block-heading">Einführung: was ist Kotlin?</h3>



<p>Kotlin ist eine Open-Source-Programmiersprache, die von JetBrains entwickelt wurde und seit der stabilen Version von 2016 verfügbar ist. Seit 2017 wird sie offiziell für die Android-Entwicklung unterstützt und 2021 zur bevorzugten Sprache für diese Plattform erklärt. Kotlin hat eine wachsende Community, was sich unter anderem in den Stack Overflow Surveys zeigt. Die Sprache wird sowohl von JetBrains als auch von Google unterstützt, was ihre Weiterentwicklung und Verbreitung fördert.</p>



<h3 class="wp-block-heading">Einsatzbereiche</h3>



<p>Kotlin wird in verschiedenen Bereichen der Softwareentwicklung eingesetzt. Besonders verbreitet ist die Nutzung in der Android-Entwicklung, aber auch im Server-Backend, wo es mit Frameworks wie Ktor, das speziell für Kotlin entwickelt wurde, und Spring Boot verwendet wird. Für die Web-Entwicklung gibt es Kotlin/JS, das die Nutzung von Kotlin im Frontend ermöglicht. Zudem kann Kotlin für Desktop-Anwendungen eingesetzt werden, beispielsweise mit JavaFX. Ein weiteres wichtiges Merkmal ist die Unterstützung für Multiplatform-Entwicklung, wodurch Kotlin-Code plattformübergreifend genutzt werden kann.</p>



<h3 class="wp-block-heading">Warum Kotlin (statt Java)?</h3>



<p>Kotlin bietet im Vergleich zu Java eine einfachere, aber zugleich mächtigere Syntax, die weniger Boilerplate-Code erfordert und dadurch kürzer, prägnanter und besser lesbar ist. Die integrierte Null-Safety reduziert das Risiko von NullPointerExceptions, was die Zuverlässigkeit des Codes erhöht. Besonders in großen Projekten erleichtert Kotlin die Wartbarkeit und verbessert die Code-Qualität. Zudem ist Kotlin vollständig interoperabel mit Java, da der Code zu Java-Bytecode kompiliert wird, was eine nahtlose Integration in bestehende Java-Projekte ermöglicht.</p>



<h3 class="wp-block-heading">Nützliche Sprachfeatures</h3>



<p>Kotlin bietet eine Vielzahl nützlicher Sprachfeatures, die die Entwicklung effizienter und übersichtlicher machen. Automatische Getter und Setter vereinfachen den Umgang mit Klassen, indem sie Standardmethoden für den Zugriff auf Eigenschaften automatisch generieren. Die integrierte Null-Safety verhindert NullPointerExceptions, indem sie eine explizite Behandlung von null-Werten erzwingt. Dank der Typinferenz muss der Datentyp oft nicht explizit angegeben werden, da Kotlin ihn automatisch ableitet. Default-Parameter ermöglichen es, Funktionen mit voreingestellten Werten zu definieren, wodurch überladene Methoden reduziert werden. Mit Extension-Functions lassen sich bestehende Klassen um neue Funktionen erweitern, ohne sie direkt zu verändern. Zudem unterstützen Lambdas und High-Order Functions eine funktionale Programmierweise, indem sie Funktionen als Parameter übergeben oder zurückgeben können, was den Code flexibler und ausdrucksstärker macht.<br><strong>Codebeispiele hierzu können in den Folien betrachtet werden, angehängt weiter unten.</strong></p>



<h2 class="wp-block-heading">Kotlin Multiplatform</h2>



<h3 class="wp-block-heading">Einführung: Was ist Kotlin Multiplatform?</h3>



<p>Kotlin Multiplatform ist ein natives Cross-Platform-Framework, das 2017 von JetBrains veröffentlicht wurde. Es ermöglicht die Entwicklung für Android, iOS, Web und Desktop mit einer flexiblen Codebasis. Dabei wird hauptsächlich die geschäftslogische Logik zwischen den Plattformen geteilt, während die UI individuell gestaltet werden kann. Mit Compose ist es jedoch auch möglich, UI-Komponenten plattformübergreifend zu nutzen. Der <em>expect/actual</em>-Mechanismus erlaubt die Implementierung plattformspezifischen Codes, wenn bestimmte Funktionen für eine Plattform individuell angepasst werden müssen.</p>



<h2 class="wp-block-heading">Compose</h2>



<h3 class="wp-block-heading">Einführung: Was ist Compose?</h3>



<p>Compose ist ein modernes, deklaratives UI-Toolkit, das von JetBrains entwickelt wurde und keine Trennung zwischen Layout und Logik erfordert. Es ist Teil des Jetpack-Toolkits auf Android (<em>Jetpack Compose</em>) und gilt als state-of-the-art Methode zur UI-Entwicklung, da es das bisherige View-System mit separaten XML-Layout-Dateien abgelöst hat. Darüber hinaus ist Compose in Kotlin Multiplatform nutzbar, wobei <em>Compose Multiplatform</em> eine erweiterte, plattformübergreifende Version bietet, mit der sich UIs für verschiedene Plattformen effizient entwickeln lassen.</p>



<h3 class="wp-block-heading">Composables</h3>



<p>Composables sind die grundlegenden Bausteine einer UI in Compose. Sie sind spezielle Funktionen, die mit der Annotation <code>@Composable</code> versehen sind und dazu dienen, UI-Elemente deklarativ zu erstellen. Anstatt eine separate Layout-Struktur zu verwenden, ermöglichen Composables eine direkte und flexible Gestaltung der Benutzeroberfläche innerhalb des Kotlin-Codes. <strong>(Codebeispiel in den Folien)</strong></p>



<h3 class="wp-block-heading">State Changes</h3>



<p>In Jetpack Compose reagieren Composables dynamisch auf Änderungen von States. Wenn sich ein State ändert, wird die betroffene Composable-Funktion automatisch neu ausgeführt (<em>re-composed</em>), um die UI entsprechend zu aktualisieren. Dadurch bleibt die Benutzeroberfläche stets synchron mit den aktuellen Daten, ohne dass manuell UI-Elemente geändert oder aktualisiert werden müssen. <strong>(Codebeispiel in den Folien)</strong></p>



<h3 class="wp-block-heading">Layouts</h3>



<p>Jetpack Compose bietet flexible Layout-Komponenten wie <code>Column</code>, <code>Row</code> und <code>Box</code>, die zur strukturierten Anordnung von UI-Elementen verwendet werden. Diese Layouts können beliebig verschachtelt werden, um komplexe Benutzeroberflächen effizient zu gestalten. Durch das deklarative Konzept lassen sich Layouts intuitiv definieren und dynamisch anpassen.</p>



<h2 class="wp-block-heading">Übungsbeispiel: Notizen-App</h2>



<p>Als Übungsbeispiel, das mit allen Teilnehmern des Workshops gemeinsam durchgemacht wurde, habe ich eine simple Notizen-App ausgewählt.</p>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" width="766" height="1598" src="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/uebungsbeispiel_screenshot.jpg" alt="" class="wp-image-13863" style="width:auto;height:400px" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2025/03/uebungsbeispiel_screenshot.jpg 766w, https://mobile.fhstp.ac.at/wp-content/uploads/2025/03/uebungsbeispiel_screenshot-736x1536.jpg 736w" sizes="auto, (max-width: 766px) 100vw, 766px" /></figure>



<p>Durch die Übung wurde demonstriert, wie schnell man mit Hilfe von Kotlin Multiplatform eine App für Android, iOS und das Web erstellen kann.<br>Als Beispiel für den expected/actual-Mechanismus, um plattformspezifischen Code zum Projekt hinzuzufügen, wurden die Notizen in einem lokalen Speicher persistiert. (z.B. SharedPreferences auf Android, LocalStorage im Web).</p>



<p><br><strong>Der Sourcecode der während dem Workshop implementierten App kann hier heruntergeladen werden: </strong></p>



<div class="wp-block-file"><a id="wp-block-file--media-9e95ea9f-be9f-440c-b11e-5f6f8e8fe755" href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/KotlinMultiplatform_FinishedExampleProject_DGruenberger.zip">KotlinMultiplatform_FinishedExampleProject_DGruenberger</a><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/KotlinMultiplatform_FinishedExampleProject_DGruenberger.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-9e95ea9f-be9f-440c-b11e-5f6f8e8fe755">Herunterladen</a></div>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Kotlin_Multiplatform_DGruenberger.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of Presentation_Kotlin_Multiplatform_DGruenberger."></object><a id="wp-block-file--media-1f62ebcd-ca58-4545-8bd6-8447a552e522" href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Kotlin_Multiplatform_DGruenberger.pdf">Presentation_Kotlin_Multiplatform_DGruenberger</a><a href="https://akirchknopf-21110.php.fhstp.cc/wp-content/uploads/2025/03/Presentation_Kotlin_Multiplatform_DGruenberger.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-1f62ebcd-ca58-4545-8bd6-8447a552e522">Herunterladen</a></div>



<p></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/workshop-kotlin-multiplatform-mit-compose/">Workshop | Kotlin Multiplatform mit Compose</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
