Sprachen: English · Nederlands · Deutsch · Español · Français · Italiano · Português · Papiamentu · Frysk

Index / Beiträge / Entwicklung einer nativen iOS-App

Entwicklung einer nativen iOS-App

Einen Rad- und Lauf-Tracker bauen

Veröffentlicht
Aktualisiert
(erstellt )
Geschrieben von
Willem L. Middelkoop
Themen
AI · apple · Fahrrad · Erschaffen · Daten · Design · gran fondo · Gesundheit · Herz · minimalistisch · Programmierung · Laufen · Sensoren · Sport · Uhr
Menschliche Version dieses Beitrags
https://willem.com/de/2024-05-11_entwicklung-einer-nativen-ios-app/
English
Developing a native iOS app
Nederlands
Het ontwikkelen van een native iOS app
Español
Desarrollo de una app nativa para iOS
Français
Développer une appli iOS native
Italiano
Sviluppare un'app iOS nativa
Português
Desenvolver uma app iOS nativa
Papiamentu
Desaroyá un app iOS nativo
Frysk
In native iOS app ûntwikkelje
Sprachen
Aus dem englischen Original von einem Sprachmodell in zwei Durchgängen (Übersetzung und Korrektur) mit Glossar und Rechtschreibprüfung übersetzt; noch nicht von einem Muttersprachler gelesen.

Zusammenfassung

Als kleines Nebenprojekt, zwischen meine normale Arbeit gequetscht, habe ich an etwas gebastelt, das mich persönlich interessiert: eine native Workout-Tracking-App für iOS. Ich wollte meine Smartwatch überflüssig machen und stattdessen mit dem Smartphone Workouts aufzeichnen. Wie schwer kann es schon sein, mit den nativen Swift-APIs detaillierte Sensordaten zu sammeln?

Volltext

Hintergrund

Wenn du meinen Blog verfolgst, überrascht dich das vielleicht nicht: Ich liebe es, Fahrrad zu fahren, und habe vor Kurzem auch mit dem Laufen angefangen. Mit dem Aufzeichnen von Workouts kenne ich mich ziemlich gut aus: Garmin, Strava, Omata, Wahoo, Biostrap, Whoop und viele Apps und Sensoren habe ich ausprobiert. Gesundheits- und Fitnessdaten finde ich nützlich, um etwas über die eigene körperliche Leistung zu lernen und um sich selbst ein Stück weit in die Pflicht zu nehmen (zum Beispiel, um bei den Workouts dranzubleiben).

Nichts gibt dir so ein Gefühl von Lebendigkeit, wie rauszugehen und dich körperlich auszupowern. Ich liebe Training!
Nichts gibt dir so ein Gefühl von Lebendigkeit, wie rauszugehen und dich körperlich auszupowern. Ich liebe Training!

Der Nerd in mir liebt große Datensätze, und die vielen verschiedenen Sensortypen sind ein Fest für meine Neugier. Gleichzeitig beißt sich das mit meinem Wunsch nach Minimalismus und Einfachheit. Braucht man wirklich alle Trainingsdaten? Reicht es nicht, einfach auf den Körper zu hören? Ich weiß es nicht, aber ich schätze es, dass eine Smartwatch Workouts (fast) mühelos und sehr detailliert aufzeichnet. Mir gefällt, wie sich die Apple Watch zum Aufzeichnen von Trainingseinheiten nutzen lässt, neben ihren Qualitäten als moderne Werkzeuguhr und als Smartphone-Ersatz. Die meisten tragen einfach ihre Smartwatch und fertig, das verstehe ich. Ich mag aber auch altmodische mechanische Uhren wie eine Rolex, eine Tudor, eine Grand Seiko oder sogar etwas Maßgefertigtes. Ich schätze beide, aber wenn ich mich zwischen Smartwatch und mechanischer Uhr entscheiden muss, greife ich eher zur mechanischen.

Die Idee für die App: Gran Fondo

Was wäre, wenn es eine Smartphone-App gäbe, die alle Trainingsdaten sammelt, die du willst, ohne Aufwand und Schnickschnack? Ich stellte mir die App so vor:

  • Einfach: Sie soll dir nicht im Weg sein und "einfach funktionieren", ohne dass du mit endlosen Einstellungen und Optionen herumfummeln musst. Du drückst "Start" und legst los.
  • Flexibel: Du kannst sie auf verschiedene Arten nutzen: Befestige oder trage das Smartphone gut sichtbar für Echtzeitdaten, oder steck es in die Tasche und lass die App im Hintergrund laufen.
  • Leistungsstark: Per Bluetooth verbindet sie sich mit Sensoren für Herzfrequenz, Trittfrequenz, Leistung und Geschwindigkeit. Mehrere Sensoren werden unterstützt, ideal, wenn du mehrere Räder fährst.
  • Apple-Health-freundlich: Alle Daten werden in maximaler Detailtiefe in Apple Health gespeichert, mit Trainingsrouten und einzelnen Messwerten für Leistung, Trittfrequenz und Geschwindigkeit. So kannst du Aufzeichnungen in jeder App auswerten, die Apple Health unterstützt, etwa Strava, WHOOP, HealthFit und viele andere.
  • Ehrlich: Keine Werbung, kein Datenverkauf. Keine Konten, keine Registrierung. Deine Daten bleiben privat, sicher und auf deinem Gerät.

Keine der bestehenden Sport- und Fitness-Apps für Smartphones erfüllt alle diese Punkte. Die meisten sind unnötig kompliziert oder irgendwie darauf angelegt, deine Daten zu nutzen, um dem App-Anbieter oder seiner Plattform zu dienen. Könnte ich es besser machen?

Die App bauen

Nachdem ich wusste, warum und was ich wollte, musste ich mich für eine Methode entscheiden, die App zu bauen.

Nativ oder Hybrid-/Web-App

Bei den meisten meiner Arbeiten setze ich am liebsten auf offene und freie (im Sinne von libre) Webtechnologien wie HTML, JavaScript und CSS oder auf Serversoftware unter einer freien Softwarelizenz, zum Beispiel GPL. Für diesen Fall musste die App extrem energieeffizient sein und sich tief in das Betriebssystem meines Smartphones einklinken. Beim iPhone geht das am besten, wenn man Apples Software Development Kit voll nutzt: die App nativ in Swift mit SwiftUI bauen und die technischen Vorgaben und Design-Richtlinien so genau wie möglich befolgen.

KI-gestütztes Programmieren

Ich habe zwar meine Vorbehalte, aber Programmieren mit KI steht gerade im Rampenlicht. Manche behaupten sogar, Copilot oder ChatGPT machten Programmierer überflüssig. Ich kenne mich mit KI aus: Ich habe damit Code erzeugt und bringe anderen bei, wie man sie nutzt. Eine komplette iOS-App hatte ich damit aber noch nie gebaut. Ich fand es die perfekte Gelegenheit zu testen, wie gut KI bei etwas Komplexerem als einem kleinen Skript-Schnipsel funktioniert. Mal sehen, wie überflüssig ich als Programmierer im modernen KI-Zeitalter bin...

GPS und Bluetooth-Low-Energy-Sensoren

Nachdem ich meine Xcode-Umgebung eingerichtet hatte, bat ich ChatGPT von OpenAI um Code zum Auslesen der GPS-Standortdaten und um die nötigen Swift-Klassen, um Bluetooth-Sensoren zu erkennen und zu verbinden. Mann, bin ich da in den sprichwörtlichen Kaninchenbau gefallen!

Mein Fahrrad mit Bluetooth-Sensoren, verbunden mit meinem MacBook, auf dem Xcode läuft
Mein Fahrrad mit Bluetooth-Sensoren, verbunden mit meinem MacBook, auf dem Xcode läuft

Das Ding mit KI-gestütztem Programmieren: JA, es funktioniert, aber nur TEILWEISE. Du bekommst funktionierende Einzelteile, die aber nicht perfekt zusammenpassen und nicht unbedingt zusammenarbeiten. Der Code, den sie ausspuckt, ist wie das Echo eines großartigen Songs: Du erkennst, dass es nach etwas klingt, aber es ist nicht dasselbe, wie die Band live zu hören, geschweige denn, selbst zu singen!

Ich nahm die Teile der KI und las selbst die Dokumentation. Das war viel effektiver, weil ich so wirklich verstand, was der Mechanismus tun sollte. Die KI hat mir geholfen, herauszufinden, was ich lernen musste. GPS-Standortdaten aufzuzeichnen war mit Apples CoreLocation überraschend einfach. Den Bluetooth-Sensor mit der App zu verbinden war viel schwieriger, denn es besteht aus vielen einzelnen Schritten:

  • Bluetooth-Geräte erkennen: die Umgebung nach Geräten absuchen, die verfügbar sind und senden
  • Mit einem Bluetooth-Gerät verbinden: eine Verbindung zwischen App und Gerät herstellen und halten
  • Eigenschaften des Geräts ermitteln: Ein einfaches Bluetooth-Gerät gibt es nicht, du musst die Fähigkeiten und Funktionen eines Geräts selbst "entdecken". Viele Geräte senden mehrere verschiedene Signale für Sensordaten, Steuerung und Betriebswerte wie den Akkustand.
  • Eigenschaften abonnieren: Am Ende abonnierst du einen Datenstrom, indem du das Bluetooth-Funkmodul auf eine bestimmte Eigenschaft einstellst.
  • Daten dekodieren: Weil Bluetooth auf Energiesparen ausgelegt ist, bekommst du minimale Daten in rohen Bits. Die Datenpakete musst du selbst dekodieren. Schwierig ist, dass jeder Sensor jedes Herstellers die Daten anders kodiert.

Nimm zum Beispiel einen relativ "einfachen" Sensor wie einen Trittfrequenzsensor am Pedal, mit dem du die Umdrehungen pro Minute beim Radfahren bestimmen kannst. Wie schwer kann das sein? Ich dachte, die offizielle Bluetooth-Spezifikation liefert mir alle nötigen Details... FALSCH! Ein simpler Trittfrequenzsensor ist überraschend komplex:

  • Gemeinsames Bluetooth-Profil für Geschwindigkeit und Trittfrequenz: Jeder Trittfrequenzsensor meldet sich immer als Geschwindigkeits- und Trittfrequenzsensor an, seine Fähigkeiten musst du spontan herausfinden.
  • Unterschiedliche Datenpakete: Der Inhalt der Daten hängt davon ab, was der Sensor gerade kann (zum Beispiel, ob er etwas erkannt hat). Du musst das Datenpaket Bit für Bit auswerten und anhand von Flags prüfen, was das nächste Bit bedeutet.
  • Nicht triviale Daten: Erwarte keinen klaren Wert für "Trittfrequenz". Der Sensor liefert dir eine kumulierte Zahl der Umdrehungen und einen groben Zeitstempel der letzten erkannten Änderung. Aus diesen Werten musst du die gesuchte Größe selbst berechnen.

Die KI lieferte mir Beispielcode, der mit meinem Sensor aber nicht funktionierte. Mit der Bluetooth-Debugging-App Bluefy verstand ich besser, welche Daten der Sensor sendet. Im offiziellen Bluetooth-Blog fand ich ein Stück Java-Code, das mir Hinweise gab, wie man die Sensordaten deutet. Ich habe diesen Code an verschiedene Sensorprofile angepasst und in Swift übersetzt. So entstand ein erster funktionierender Prototyp.

Früher Prototyp der App mit einem Bluetooth-Herzfrequenzsensor. Die ersten Daten sind in einer anderen App (HealthFit) zu sehen, die daraus hübsche Grafiken macht
Früher Prototyp der App mit einem Bluetooth-Herzfrequenzsensor. Die ersten Daten sind in einer anderen App (HealthFit) zu sehen, die daraus hübsche Grafiken macht

UI/UX-Design

Einer der Hauptgründe, warum ich die Workout-App der Apple Watch mag: Ihre Benutzeroberfläche (UI) ist so gestaltet, dass die Bedienung (UX) angenehm ist. Die App auf der Uhr hat ziemlich große Tasten, mit denen du eine Aufzeichnung startest, und das war's im Wesentlichen. Die App hat wenige Optionen, ihr Design ist eigenwillig, aber gut durchdacht. Das ist ein starker Kontrast zu Geräten wie Garmin mit ihren unzähligen Anpassungsmöglichkeiten. Der Trick ist eine gute Balance zwischen Flexibilität bei den Einsatzzwecken und einer Grundeinstellung, die gut funktioniert.

Die Workout-App der Apple Watch zeigt große Tasten zum Starten eines Trainings, ganz ohne zusätzliche Konfiguration
Die Workout-App der Apple Watch zeigt große Tasten zum Starten eines Trainings, ganz ohne zusätzliche Konfiguration

Mit einer Halterung wie QuadLock befestigst du dein Smartphone fest am Lenker. Dann kann das iPhone deinen Garmin als Fahrradcomputer ersetzen. Moderne iPhones haben ein Always-on-Display, das Informationen energiesparend anzeigen kann, wenn du das Apple Software Development Kit mit seinen eingebauten Optimierungen nutzt. Nach vielen, vielen Kilometern mit meinem Garmin-Fahrradcomputer habe ich mich für eine Ansicht mit Echtzeit-Feldern für Geschwindigkeit, Leistung und Herzfrequenz entschieden. An den besseren Garmin-Edge-Geräten mag ich, dass sie ein Diagramm zeichnen können. So behältst du die Straße im Blick, wenn es darauf ankommt, und schaust erst etwas später auf den bisherigen Verlauf.

Das Datenlayout meines Garmin Edge diente mir als Inspiration für das Layout der App, wenn sie als montierter Fahrradcomputer läuft
Das Datenlayout meines Garmin Edge diente mir als Inspiration für das Layout der App, wenn sie als montierter Fahrradcomputer läuft
Designskizze mit dem gewünschten Layout
Designskizze mit dem gewünschten Layout
Test der App auf dem Rad mit QuadLock-Hülle und -Halterung
Test der App auf dem Rad mit QuadLock-Hülle und -Halterung

Um möglichst energieeffizient zu sein, habe ich mich für Apples eigene Bibliothek für Diagramme entschieden: Swift Charts. Ein Problem bei der Entwicklung: Die Messwerte der Sensoren kommen in unterschiedlichen Abständen und zu unterschiedlichen Zeiten an. Du brauchst eine Art Synchronisierung, damit die Datenpunkte gemeinsame Zeitstempel haben und du Werte vergleichen und in Beziehung setzen kannst. Diesen Mechanismus habe ich so gebaut, dass er auch die UI-Updates synchronisiert. So werden alle Diagramme und Datenpunkte mit einem einzigen Refresh aktualisiert, was CPU- und Grafikleistung (und damit den Akku) schont. Als Bonus unterstützt die App verschiedene Zeitfenster: Die Diagramme zeigen die letzte Minute, 5 Minuten, 15 Minuten, die letzte Stunde oder das ganze Workout.

Verschiedene Konfigurationen der Echtzeitdaten
Verschiedene Konfigurationen der Echtzeitdaten

Die App zeigt automatisch die Diagramme an, die zu den verbundenen Sensoren passen. Wenn du mehr als ein Rad hast, musst du also nicht jedes Mal etwas neu einstellen. Tippst du auf ein Diagramm, wird es größer oder kleiner. Tippst du auf das Zeitfenster (zum Beispiel "letzte 5 Minuten"), wechselst du zwischen den Fenstern. Die App merkt sich deine Konfiguration und stellt dich für das nächste Workout automatisch richtig ein. Alle Touchflächen und Tasten sind ziemlich groß, sodass sie auch mit verschwitzten Händen oder Handschuhen gut funktionieren.

Hosentaschentauglich: Optimierung für den Hintergrundbetrieb und den Energieverbrauch

Ich wollte die App auch aus der Tasche heraus nutzen können, als Hintergrund-App. So zeichnet sie unauffällig Daten auf: App starten, Telefon wegstecken. Ich liebe die Idee, einen "vollständigen Datensatz" für alle meine Fahrten und Läufe zu haben, ohne dass die App die ganze Zeit im Mittelpunkt stehen muss. Viele Trainingsläufe und -fahrten sind nämlich nicht so spannend.

Ich habe Magie in der Tasche: Die App zeichnet Workouts im Hintergrund auf. Während der Aufzeichnung erscheint nur ein Widget auf dem Homescreen
Ich habe Magie in der Tasche: Die App zeichnet Workouts im Hintergrund auf. Während der Aufzeichnung erscheint nur ein Widget auf dem Homescreen

Standardmäßig schränkt Apples Betriebssystem iOS stark ein, was Apps im Hintergrund tun dürfen. Das schont den Akku und schützt die Privatsphäre. Wenn du dich an Apples Richtlinien hältst und die nötigen Berechtigungen korrekt anfragst, kann deine App aber hervorragend im Hintergrund arbeiten. Ich habe Apples Arbeit an der Optimierung des gesamten Stacks richtig schätzen gelernt, denn sie macht deine App energieeffizienter. Vereinfacht gesagt gilt das Motto "Ruf uns nicht an, wir rufen dich an": Das Betriebssystem bestimmt, wann deine App ihre Arbeit macht. So kann es verschiedene Aufgaben auf den verfügbaren (sparsamen) Kernen der Apple-Silicon-Chips synchronisieren, bündeln und gesammelt abarbeiten.

Bei einem Test mit einer Prototyp-Version der App habe ich auf einer 8 Stunden langen Langstreckenfahrt mit einer einzigen iPhone-Akkuladung über 127 Tausend (!!) Datenpunkte gesammelt, bei dauerhaft eingeschaltetem Bildschirm. Wer nach Apples Regeln spielt, hat wirklich die Power (sozusagen). Die Entwicklung dieser App hat mich echt weitergebracht, ha!

Die Extrameile gehen: 8 Stunden auf dem Rad, um den Akkuverbrauch zu testen (Hinweis: Es sind noch 23 % Akku übrig!)
Die Extrameile gehen: 8 Stunden auf dem Rad, um den Akkuverbrauch zu testen (Hinweis: Es sind noch 23 % Akku übrig!)

Echte Künstler liefern ab

Der Weg zur Hölle ist mit guten Vorsätzen gepflastert, heißt es... Deshalb bringe ich meine Projekte gern zu Ende. Bei einer App heißt das: Sie gehört in den App Store. Sie für Apples Prüfung fertig zu machen und von den App-Store-Prüfern genehmigen zu lassen, ist ein zusätzlicher Meilenstein. Das ist wichtig, denn es zwingt dich, über das Onboarding (neuer Nutzer) und das Einnahmemodell nachzudenken.

Onboarding

Eine besonders knifflige Aufgabe beim App-Bau: Leuten, die deine App noch nicht kennen, zu zeigen, wie sie funktioniert. Eine gute Benutzeroberfläche hilft, aber weil die App so tief mit Apple Health, Standortdaten und Bluetooth-Sensoren verzahnt ist, muss sie zusätzlich höflich um Berechtigungen bitten.

Screenshots vom Onboarding der App: Berechtigungen anfragen und neue Nutzer anleiten
Screenshots vom Onboarding der App: Berechtigungen anfragen und neue Nutzer anleiten

Den Ablauf musst du so gestalten, dass nichts kaputtgeht, wenn Nutzer bestimmte Berechtigungen ablehnen. Apple ist hier sehr streng: Menschen haben das Recht, abzulehnen. Deine Aufgabe ist es, die App auch ohne oder mit nur teilweisen Berechtigungen zum Laufen zu bringen. Das ist eine zusätzliche Herausforderung.

Einnahmemodell zur Finanzierung der Entwicklung

Freie Software im Sinne von libre kann ich gar nicht hoch genug schätzen, aber ich habe auch eine Familie zu ernähren. Außerdem kann es deine Idee zusätzlich bestätigen, wenn du Leute findest, die bereit sind, für dein Produkt zu bezahlen. Sei offen und ehrlich bei deinem Einnahmemodell, dann hilft es dir, dein Projekt selbst zu finanzieren. Verlass dich nicht auf Investoren oder Risikokapital, entwickle aus eigener Kraft!

Eine Paywall für meine App entwerfen: nicht meine Lieblingsaufgabe, aber eine sehr wichtige
Eine Paywall für meine App entwerfen: nicht meine Lieblingsaufgabe, aber eine sehr wichtige

Um die App auszuprobieren, musst du nichts bezahlen. Der Bezahlbildschirm erscheint erst, wenn Leute die App wirklich nutzen (und du kannst ihn jederzeit wegtippen). Probier sie doch selbst aus, hier findest du die App.

Zukunft

"Eat your own dogfood", sagt man. Ich entwickle die App weiter, indem ich sie selbst benutze. Ich erwarte nicht, dass dieses Projekt schnell Geld bringt. Aber wenn es mir selbst praktisch etwas nützt, finden vielleicht auch andere es nützlich.

Keine normale Debugging-Session: Fietselfstedentocht 2024
Keine normale Debugging-Session: Fietselfstedentocht 2024

An diesem Projekt mag ich, dass es kaum Mühe kostet, dranzubleiben, weil ich gern trainiere. Neue Versionen der App zu debuggen heißt oft, laufen oder Rad fahren zu gehen. Wer hat eigentlich behauptet, Softwareentwicklung sei ein Bürojob im Sitzen?!

Fazit

Viele Leute haben "tolle Ideen", wenige setzen sie wirklich um. Das unterscheidet die Macher vom Rest. Ich mache gern Dinge, denn dabei musst du dich richtig in die Materie hineinarbeiten. Du lernst eine Menge und sammelst Erfahrung, die andere nicht haben. Mach's doch selbst, bau dir dein eigenes Ding!

Maschinenformate dieser Seite