docs: Uebergabe und README sagen nicht mehr, dass es kein Xcode gibt

Die wichtigste Aussage der Uebergabe war ueberholt: auf dieser Maschine liegt
Xcode 27, Stufe 1 ist gebaut, getestet und im Simulator gestartet. Wer das
nicht weiss, schreibt weiter blind und hinterlaesst dem Nutzer Fehler.

Dazu neu festgehalten: der Befehl nach jeder neuen Datei (xcodegen generate),
was beim Bauen auffiel (nur Swift 5, nicht Swift 6), und der naechste
Stolperstein - App Transport Security laesst nur https zu, auch kein
http://localhost. Ueber die Verbindung geht die Geraetemarke, ein Vollzugang;
die Ausnahme ist deshalb eine Entscheidung des Nutzers, keine Nebensache.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-10-21 05:47:23 +02:00
co-authored by Claude Opus 5
parent ffe1870bb8
commit e2f4e755f1
3 changed files with 89 additions and 49 deletions
+4 -2
View File
@@ -51,7 +51,9 @@ Gerät, kein 30-Tage-Ablauf, einzeln widerrufbar). Deutsch und Englisch, iPad
zweispaltig, offline der letzte Stand mit Datum.
Stufe 1 ✅: Gerüst, Netzwerkschicht, Anmeldung samt zweitem Faktor und
Pflicht-Passwortwechsel, Kontenliste. Stufen 2–7 (Lesen, Schreiben,
Arbeitsliste, Nebenräume, Erweiterungen, voller CSV-Import) stehen aus.
Pflicht-Passwortwechsel, Kontenliste. Übersetzt fehlerfrei, 28 Tests grün,
läuft im Simulator; das Xcode-Projekt entsteht aus `ios/project.yml`.
Stufen 2–7 (Lesen, Schreiben, Arbeitsliste, Nebenräume, Erweiterungen, voller
CSV-Import) stehen aus.
**Stand, Entscheidungen und offene Punkte: `ios/UEBERGABE.md`.**
+36 -21
View File
@@ -1,28 +1,38 @@
# Certain für iOS
Native App zum Certain-Backend. Der Code hier ist **nie übersetzt worden** — auf
der Maschine, auf der er entstanden ist, gibt es kein Xcode. Rechne beim ersten
Bauen mit Fehlern und schick sie mir; das ist eingeplant.
Native App zum Certain-Backend.
> **Wer hier weiterarbeitet, liest zuerst [UEBERGABE.md](UEBERGABE.md).** Dort
> steht, was entschieden ist, was fertig ist, was als Nächstes dran ist und
> welche Eigenheiten das Backend hat. Dieses README erklärt nur, wie man den
> Code ins Projekt bekommt.
> welche Eigenheiten das Backend hat. Dieses README erklärt nur das Projekt.
## Projekt anlegen
## Bauen und starten
1. Xcode → neues Projekt → **App**, Schnittstelle **SwiftUI**, Sprache **Swift**.
2. Mindestversion auf **iOS 26** stellen.
3. Als Geräte **iPhone und iPad** ankreuzen.
4. Die Datei `ContentView.swift`, die Xcode anlegt, **löschen** — `App/` bringt
einen eigenen Einstiegspunkt mit.
5. Die Ordner aus `ios/` per Ziehen ins Projekt übernehmen, mit *Create groups*
(nicht *folder references*).
6. `Texte/de.lproj` und `Texte/en.lproj` übernehmen und unter
*Project → Info → Localizations* **Deutsch** und **Englisch** eintragen.
Deutsch ist die Grundsprache.
Einfach `Certain.xcodeproj` öffnen — es liegt mit im Repository.
Der Ordner `Tests/` gehört in ein Test-Ziel, nicht in das App-Ziel.
Die Wahrheit ist aber `project.yml`: eine XcodeGen-Spezifikation, aus der das
Projekt entsteht. **Wer eine Swift-Datei anlegt, läuft danach einmal
`xcodegen generate`**, sonst kennt Xcode sie nicht. Ein neuer *Ordner* will
ausserdem eine Zeile unter `sources:`.
```
brew install xcodegen # einmalig
cd ios && xcodegen generate
xcodebuild -project Certain.xcodeproj -scheme Certain \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
xcodebuild -project Certain.xcodeproj -scheme Certain \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' test
```
Festgelegt sind dort: Bündelkennung `com.scarriffle.certain`, Team
`PP34X97WS3`, iPhone und iPad, Grundsprache Deutsch, **iOS 26** als
Mindestversion, Sprachfassung Swift 5. Wer mit einem anderen Apple-Konto baut,
trägt seine Team-ID in `project.yml` ein.
**Nur https.** App Transport Security steht auf der Voreinstellung, ein Server
unter `http://…` wird also abgewiesen — auch `http://localhost` beim
Entwickeln. Das ist Absicht: über die Verbindung geht die Gerätemarke, ein
Vollzugang. Wer eine Ausnahme braucht, trägt sie bewusst in `project.yml` ein.
## Was wohin gehört
@@ -90,12 +100,17 @@ heraus, dass `created_at` ohne Zeitzone und mit Mikrosekunden kommt
(`2026-10-20T14:18:15.780705`) — dafür hat `Zeitpunkt` einen dritten Leser,
und `GrundlagenTests` deckt den Fall ab.
**Nicht geprüft:** Ob das Ganze übersetzt. Kein Xcode auf der Maschine, auf
der es entstanden ist.
**Ebenfalls geprüft:** Dass es übersetzt. Ein einziger Fehler in 2600 blind
geschriebenen Zeilen (`[:]` statt `[]` in `CertainClient.schickeDatei`), danach
keine Warnung im eigenen Code, 28 Tests grün, Start im Simulator bis zur
Serverabfrage.
### Wo es beim ersten Bauen am ehesten klemmt
**Nicht geprüft:** Der Weg gegen ein echtes Backend — anmelden, zweiter Faktor,
Marke anlegen, Konten laden.
Nach abnehmender Wahrscheinlichkeit:
### Wo es beim ersten Bauen am ehesten klemmte
Nichts davon trat ein; die Liste bleibt als Landkarte der heiklen Stellen.
1. **`@testable import Certain`** in `Tests/GrundlagenTests.swift` — muss auf
den Namen deines App-Ziels zeigen. Heisst es anders, anpassen.
+49 -26
View File
@@ -6,7 +6,7 @@ haben: was entschieden ist, was fertig ist, was als Nächstes dran ist, und was
ich über das Backend herausgefunden habe. Lies sie ganz, bevor du anfängst —
die Abschnitte „Was das Backend vorgibt" und „Fallen" ersparen dir Tage.
Stand: 20.10.2026, Commit `6b86a6b`. Alles committet und gepusht.
Stand: 21.10.2026, Commit `ffe1870`. Alles committet und gepusht.
---
@@ -21,15 +21,23 @@ native iOS-App in `ios/`, die sich über eine eingegebene Server-Adresse (wie
Dashboard, Arbeitsliste, Kategorien, Tags, Einstellungen, Bankabruf und der
volle CSV-Import.
### Die wichtigste Rahmenbedingung
### Die Rahmenbedingung, die es nicht mehr gibt
Auf der Maschine, auf der der Code entsteht, **gibt es kein Xcode**. Der Swift-
Code wird blind geschrieben und nie übersetzt. Der Nutzer legt das Projekt an,
übersetzt und meldet die Fehler zurück.
Bis zum 21.10.2026 stand hier: es gibt kein Xcode, der Swift-Code wird blind
geschrieben und nie übersetzt. **Das gilt nicht mehr.** Auf dieser Maschine
liegt Xcode 27 mit Simulatoren für iOS 26.5 und 27, und `ios/project.yml`
erzeugt das Projekt. Übersetzen, Tests und Starten im Simulator gehen hier
direkt:
Daraus folgt die Arbeitsweise: **kleine Stufen, jede für sich übersetzbar.**
Nicht zehntausend Zeilen schreiben und dann einen Berg Fehlermeldungen
hinterlassen. Nach jeder Stufe übersetzt der Nutzer.
```
cd ios && xcodegen generate # nach jeder neuen Datei
xcodebuild -project Certain.xcodeproj -scheme Certain \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' build # oder test
```
**Übersetze nach jeder Stufe selbst, statt dem Nutzer Fehler zu hinterlassen.**
Die kleinen Stufen bleiben trotzdem richtig — nicht wegen der Fehlersuche,
sondern damit jede Stufe für sich benutzbar ist.
---
@@ -44,7 +52,7 @@ Alle schon gefallen. **Nicht erneut fragen.**
| Zusätzlicher Umfang | Arbeitsliste/Eingang, Kategorien und Tags, Einstellungen, Bankabruf anstossen |
| Dashboard | Feste iOS-Ansicht, kein Raster |
| iOS-Mindestversion | **iOS 26** |
| Ablieferung | Flache Ordner unter `ios/`, der Nutzer legt das Xcode-Projekt an |
| Ablieferung | Flache Ordner unter `ios/`; das Projekt entsteht seit dem 21.10. aus `project.yml` |
| Anmeldung | App-Token (im Backend ergänzt, siehe unten) |
| Erweiterungen | Teilen-Menü für Dateien, Kurzbefehle/Siri |
| Sprachen | Deutsch **und** Englisch |
@@ -224,7 +232,8 @@ sie beide Richtungen anbietet. Nötig für Stufe 3.
| `Konten/` | `KontenListe` — die erste Fachansicht |
| `Einstellungen/` | Platzhalter: zeigt den Zugang und lässt abmelden |
| `Texte/` | `de.lproj` und `en.lproj`, zeilengleich |
| `Tests/` | `GrundlagenTests` — reine Logik, Swift Testing |
| `Tests/` | `GrundlagenTests` — reine Logik, Swift Testing, 28 Stück |
| `project.yml` | XcodeGen-Spezifikation, erzeugt `Certain.xcodeproj` |
### Wie die Anmeldung abläuft
@@ -249,11 +258,17 @@ Wegwerf-Datenbank, Felder flach ausgeben, mit den `CodingKeys` vergleichen.
(Das Passwort der Dev-Datenbank unter `backend/data/app.db` ist unbekannt —
nicht raten, eine frische Testdatenbank nehmen.)
### Was nicht geprüft ist
### Dass es übersetzt, ist inzwischen geprüft
**Ob es übersetzt.** Der Nutzer hatte Stufe 1 beim Schreiben dieser Datei noch
nicht gebaut. Rechne damit, dass seine erste Rückmeldung Fehlermeldungen sind —
das ist eingeplant und kein Rückschlag.
Am 21.10.2026 gebaut, getestet und gestartet (Commit `ffe1870`). Genau **ein**
Übersetzungsfehler in 2600 blind geschriebenen Zeilen: der Vorgabewert
`[String: String] = []` in `CertainClient.schickeDatei` musste `[:]` heissen.
Sonst keine Fehler, keine Warnung im eigenen Code. Die 28 Tests laufen durch,
die App startet im Simulator bei der Serverabfrage.
**Noch nicht geprüft: der Weg gegen ein echtes Backend.** Anmelden, zweiter
Faktor, Marke anlegen, Kontenliste — das lief bisher nur gegen die Modelle,
nicht gegen einen laufenden Server. Siehe „Klartext-HTTP" unten.
---
@@ -306,20 +321,26 @@ Einwand und will den vollen Import trotzdem.
## 7. Fallen und Arbeitsweise
### Beim Übersetzen am ehesten verdächtig
### Klartext-HTTP — der nächste Stolperstein
Nach abnehmender Wahrscheinlichkeit:
Das Projekt läuft mit der Voreinstellung von App Transport Security, also
**nur https**. Ein selbstgehosteter Server im Heimnetz unter `http://…` wird
abgewiesen, und `http://localhost` beim Entwickeln ebenso — obwohl
`ServerAnsicht` http ausdrücklich zulässt und ein Test das festhält
(„http bleibt http"). Wer gegen ein lokales Backend prüfen will, braucht
in `project.yml` eine ATS-Ausnahme. Das ist eine Sicherheitsentscheidung des
Nutzers: über Klartext geht die Gerätemarke, ein Vollzugang, mit jeder
Anfrage mit.
1. **`@testable import Certain`** in `Tests/GrundlagenTests.swift` muss auf den
Namen des App-Ziels zeigen.
2. **`Lader` ist eine generische `@Observable`-Klasse** — die ungewöhnlichste
Konstruktion im Code. Wird bisher nur in `KontenListe` benutzt.
3. **Nebenläufigkeit:** `AppZustand` ist `@MainActor`, `CertainClient` ein
Actor. An den Übergängen kann es unter strikter Prüfung Warnungen setzen.
4. **`Tab` und `.tabViewStyle(.sidebarAdaptable)`** setzen iOS 18 voraus — bei
iOS 26 als Mindestversion kein Problem.
5. Die Tests nutzen **Swift Testing** (`import Testing`, `@Test`, `#expect`),
nicht XCTest.
### Was beim Übersetzen auffiel
Alles, was hier als verdächtig stand, hat gehalten: `Lader` als generische
`@Observable`-Klasse, der `@MainActor`/Actor-Übergang zwischen `AppZustand`
und `CertainClient`, `Tab` mit `.tabViewStyle(.sidebarAdaptable)`, Swift
Testing statt XCTest. Eine Einschränkung: Das Projekt baut in **Sprachfassung
Swift 5**. Unter Swift 6 greift die strikte Nebenläufigkeitsprüfung, und die
Übergänge sind darauf nicht geschrieben — wer umstellen will, rechnet mit
Arbeit an genau diesen Stellen.
### Schreibende Aufrufe mit Query statt Körper
@@ -336,6 +357,8 @@ Leicht zu übersehen, das Backend macht es an mehreren Stellen:
Commit. Fertige Arbeit wird committet und gepusht, ohne Rückfrage.
- **Kommentare erklären das Warum**, nicht das Was — und zwar das, was der Code
nicht zeigen kann. Das ganze Projekt ist so geschrieben; halte es durch.
- **Neue Swift-Datei?** Danach `cd ios && xcodegen generate`. Die Ordner stehen
einzeln in `project.yml`; ein neuer Ordner will dort eine Zeile.
- **Tests**: `cd backend && ./.venv/Scripts/python.exe -m pytest tests/ -q`
(Python 3.12 im venv; das System-Python kann nicht bauen). Dauert rund zwei
Minuten — im Hintergrund laufen lassen.