e6a9ff4ec8
Auf die Frage, welche Datei man am Mac in die Hand nimmt: der Backlog war die richtige Antwort, ihm fehlte aber genau das - er beschrieb den Zustand und die Pruefliste, nicht den Ablauf. Neuer Abschnitt "Wie ein Lauf abläuft": was vorher zu tun ist (git pull; das Skript bricht selbst ab, wenn der Baum unsauber oder HEAD nicht gleich origin/main ist), der eine Befehl samt seiner dreizehn Schritte, dass die Fassung aus manifest.json kommt und nichts von Hand hochzuzaehlen ist, das einmalige Schluesselbund-"Immer erlauben" samt Symptom wenn man es uebersieht, und danach Push plus der itms-services-Link in Safari - ausdruecklich ohne ?v=, mit Verweis auf den Befund aus Abschnitt CK. Damit ist die Datei als alleinige Uebergabe brauchbar; AGENTS.md braucht man nur noch fuers Warum. OFFEN.md 1.1 verweist entsprechend darauf.
207 lines
8.4 KiB
Markdown
207 lines
8.4 KiB
Markdown
# Apple Dev Backlog (DM360)
|
|
|
|
Alles, was einen **Xcode-Lauf** oder das **Apple Developer Portal** braucht,
|
|
wird hier gesammelt - und nur hier.
|
|
|
|
**Warum:** ein Xcode-Lauf lohnt sich nicht für eine einzelne native Änderung.
|
|
Er wird erst gestartet, wenn eine nennenswerte Menge zusammengekommen ist; die
|
|
Entscheidung darüber trifft der Eigentümer, nicht eine Sitzung.
|
|
|
|
## Arbeitsregel (verbindlich)
|
|
|
|
* Jede Aufgabe, die Xcode oder das Apple-Portal braucht, kommt **in diese
|
|
Datei**, in derselben Sitzung, in der sie auffällt - nicht in eine Notiz im
|
|
Bericht und nicht nur in `AGENTS.md`.
|
|
* **Nichts davon wird von sich aus gestartet.** Ein Xcode-Lauf ist eine
|
|
Handlung des Eigentümers am Mac; eine Sitzung bereitet ihn vor und meldet,
|
|
wenn sich genug angesammelt hat.
|
|
* Was **ohne** Xcode geht, gehört nicht hierher: Änderungen an der Oberfläche
|
|
der App reisen im OTA-Bündel (`@capgo/capacitor-updater`), Änderungen am Panel
|
|
und am Backend über die Selbstaktualisierung der Integration. Nur nativer
|
|
Code, Plugins, Berechtigungen, Signatur und Auslieferungsweg brauchen einen
|
|
Lauf.
|
|
* Erledigtes wird **nicht gelöscht**, sondern nach unten unter „Erledigt"
|
|
verschoben - mit der Fassung, in der es ausgeliefert wurde. Sonst wird
|
|
dieselbe Frage in einem halben Jahr wieder aufgemacht.
|
|
|
|
---
|
|
|
|
## Stand der ausgelieferten App
|
|
|
|
Gemessen am Artefakt `companion-app/auslieferung/App.ipa`, nicht aus dem
|
|
Gedächtnis (06.09.2026):
|
|
|
|
| | |
|
|
|---|---|
|
|
| Fassung | **2026.9.4.17** (Build 1), App und Erweiterung gleich |
|
|
| Bundle-ID | `app.datametric360`, Erweiterung `app.datametric360.teilen` |
|
|
| Profile | beide Ad Hoc, **2 Geräte**, gültig bis **2027-08-29** |
|
|
| Berechtigungen | Standort, Kalender (beide Schlüssel), Kamera - alle vorhanden |
|
|
| `packageClassList` | **6 Klassen - beide eigenen Plugins fehlen** |
|
|
|
|
Zum Vergleich: das Repository steht auf `2026.9.6.5`. Der Abstand ist **kein**
|
|
Rückstand - alles dazwischen war Oberfläche und Backend und reist über OTA. Was
|
|
wirklich auf einen Lauf wartet, steht unten.
|
|
|
|
---
|
|
|
|
## Wie ein Lauf abläuft
|
|
|
|
**Diese Datei ist die Übergabe.** Wer am Mac sitzt - mit oder ohne Claude am
|
|
Xcode - braucht keine weitere: hier steht der Stand, der eine Befehl, und was
|
|
danach zu prüfen ist. `AGENTS.md` ist nur für das *Warum* nötig.
|
|
|
|
### Vorher
|
|
|
|
Nichts vorzubereiten außer einem aktuellen Stand:
|
|
|
|
```bash
|
|
git pull
|
|
```
|
|
|
|
Das Skript prüft das selbst und **bricht ab**, wenn der Arbeitsbaum nicht sauber
|
|
oder `HEAD` nicht gleich `origin/main` ist - sonst signierte es einen veralteten
|
|
Stand. Ebenso bricht es ab, wenn das Zielgerät nicht im Team eingetragen ist
|
|
(„Your team has no devices"); das ist dann eine Portal-Sache, kein Projektfehler.
|
|
|
|
### Der Lauf
|
|
|
|
```bash
|
|
bash companion-app/scripts/ios-signieren.sh
|
|
```
|
|
|
|
Ein Befehl, von jedem Verzeichnis im Repository aus. Er wechselt selbst nach
|
|
`companion-app/` und erledigt der Reihe nach: Git-Stand prüfen, Webbündel bauen,
|
|
native Hülle synchronisieren, Standort-/Kalender-/Kamera-Berechtigung eintragen,
|
|
Share-Erweiterung einrichten, App-Symbol einspielen, Versionsnummern setzen,
|
|
Archiv bauen und signieren, `.ipa` exportieren, **die fertige `.ipa` gegenlesen**
|
|
und die Auslieferung über die Luft vorbereiten.
|
|
|
|
**Die Fassung kommt aus `custom_components/audi_dashboard/manifest.json`** - es
|
|
gibt nichts von Hand hochzuzählen. Beim Schreiben dieser Zeilen wäre das
|
|
`2026.9.6.5`.
|
|
|
|
**Einmalig beim ersten Signieren:** der Schlüsselbund fragt, ob `codesign` den
|
|
Schlüssel benutzen darf. **„Immer erlauben"** wählen, nicht „Erlauben" - ein
|
|
Archiv signiert über 25 Programmteile und fragte sonst jedes Mal erneut. Bleibt
|
|
der Lauf minutenlang beim Signieren stehen, wartet er auf genau diesen Dialog.
|
|
|
|
### Danach
|
|
|
|
```bash
|
|
git add companion-app/auslieferung && git commit && git push
|
|
```
|
|
|
|
Das Telefon lädt die `.ipa` aus dem Repository - ohne diesen Push ändert sich
|
|
dort nichts. Danach in **Safari** auf dem Telefon öffnen (andere Browser reichen
|
|
`itms-services://` nicht an das System weiter):
|
|
|
|
```
|
|
itms-services://?action=download-manifest&url=https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/companion-app/auslieferung/manifest.plist
|
|
```
|
|
|
|
Die Adresse trägt **kein** `?v=` - ein zweites Fragezeichen zerlegt den
|
|
Parameter, und weil iOS die Rückfrage erst aus dem geladenen Manifest baut,
|
|
passiert dann sichtbar gar nichts (Abschnitt CK).
|
|
|
|
Zum Schluss die eine Prüfung, die kein Skript abnehmen kann - siehe Abschnitt C
|
|
unten.
|
|
|
|
---
|
|
|
|
## A. Wartet auf einen Xcode-Lauf
|
|
|
|
### A1. Zwei eigene Plugins sind auf dem Telefon tot
|
|
|
|
**Auswirkung: Zwischenablage und Kalendereintrag funktionieren nicht.** Das ist
|
|
die einzige Position mit sichtbarem Ausfall.
|
|
|
|
Capacitor 8 registriert ausschließlich, was in `packageClassList` der
|
|
`capacitor.config.json` im Bündel steht (`CapacitorBridge.swift`,
|
|
`registerPlugins()`). Diese Liste erzeugt `cap sync` aus den installierten
|
|
npm-Paketen - app-eigene Plugins sind keine. Beide Klassen liegen nachweislich
|
|
im Programm der ausgelieferten `.ipa` und werden trotzdem nie registriert.
|
|
|
|
*Korrektur liegt im Repo* (`a99ae43`): `ios-teilen-einrichten.mjs` trägt die
|
|
Klassen nach jedem `cap sync` nach und liest ihre Namen aus den Swift-Dateien
|
|
selbst, damit sie nicht an zwei Stellen gepflegt werden. `ios-signieren.sh`
|
|
**bricht ab**, wenn eine davon im fertigen Bündel fehlt.
|
|
|
|
Hintergrund vollständig: `AGENTS.md`, Abschnitt DH und CM.
|
|
|
|
### A2. Installationslink ohne zweites Fragezeichen
|
|
|
|
`ios-luftweg.sh` hängte den Cache-Brecher `?v=` auch an die Manifest-Adresse
|
|
**innerhalb** des `itms-services`-Links - damit steht dort ein zweites `?`, der
|
|
Abruf scheitert, und weil iOS die Rückfrage erst aus dem geladenen Manifest
|
|
baut, passiert sichtbar gar nichts.
|
|
|
|
*Korrektur liegt im Repo* (`6365136`). Die bereits ausgelieferte
|
|
`auslieferung/index.html` wurde von Hand nachgezogen; das Skript zieht beim
|
|
nächsten Lauf nach. Hintergrund: `AGENTS.md`, Abschnitt CK.
|
|
|
|
---
|
|
|
|
## B. Wartet auf das Apple Developer Portal
|
|
|
|
Derzeit **nichts offen.** App-Gruppe, beide App-IDs und die Gerätefreigabe sind
|
|
eingerichtet (Abschnitt AK), die Profile laufen bis 2027-08-29.
|
|
|
|
Vorzumerken, aber noch lange hin:
|
|
|
|
* **2027-07-17** - das Entwicklerzertifikat läuft ab.
|
|
* **2027-08-29** - beide Bereitstellungsprofile laufen ab.
|
|
* Ein **neues Gerät** braucht eine Registrierung im Portal *und* frisch
|
|
ausgestellte Profile. Ein bereits ausgestelltes Profil erfährt von einem neuen
|
|
Gerät nichts - deshalb räumt `ios-signieren.sh` die zwischengespeicherten
|
|
Profile vor dem Bauen weg (Abschnitt AI).
|
|
|
|
---
|
|
|
|
## C. Nach dem Lauf zu prüfen
|
|
|
|
Am **fertigen Bündel**, nicht am Projekt. Die Begründung steht in Abschnitt AK:
|
|
von fünf Fehlern der nativen Hülle haben vier einen erfolgreichen Archivlauf
|
|
erzeugt und sind erst am entpackten `.ipa` aufgefallen.
|
|
|
|
Das Skript prüft selbst und bricht ab, wenn etwas fehlt:
|
|
|
|
1. Die Erweiterung hat ein echtes Programm.
|
|
2. App und Erweiterung tragen dieselbe `CFBundleShortVersionString` **und** eine
|
|
brauchbare `CFBundleVersion` (ohne die lehnt iOS die Installation der ganzen
|
|
App ab - Abschnitt CD).
|
|
3. Die App-Gruppe steht in den Entitlements **beider** Ziele.
|
|
4. Beide eigenen Plugin-Klassen stehen in `packageClassList`.
|
|
|
|
**Von Hand bleibt genau eine Prüfung** - auf dem Gerät: einen Beleg über das
|
|
Teilen-Blatt schicken, ein PDF aus der Zwischenablage einfügen, einen
|
|
Kalendereintrag anlegen. Ob die Plugins *registriert* sind, sagt Punkt 4; ob sie
|
|
*tun*, was sie sollen, sagt nur das Telefon.
|
|
|
|
---
|
|
|
|
## Was der Lauf von selbst erledigt
|
|
|
|
Damit es niemand ein zweites Mal von Hand macht: `ios-signieren.sh` trägt bei
|
|
jedem Lauf Standort-, Kalender- und Kamera-Berechtigung ein, richtet die
|
|
Share-Erweiterung ein, spielt das App-Symbol ein und setzt die Versionsnummern
|
|
in beide Ziele. Das muss sein, weil `companion-app/ios/` gitignored ist und von
|
|
`npx cap add ios` jederzeit neu erzeugt wird - alles, was man in Xcode
|
|
anklickt, wäre danach weg (Abschnitt AI).
|
|
|
|
Unvermeidlich von Hand bleiben: die einmalige Portal-Einrichtung, das
|
|
Schlüsselbund-„Immer erlauben" beim ersten Signieren, und `git push` der
|
|
fertigen `.ipa`, weil das Telefon sie aus dem Repository lädt.
|
|
|
|
---
|
|
|
|
## Erledigt
|
|
|
|
| Fassung | Was |
|
|
|---|---|
|
|
| 2026.9.4.17 | Kamera-Berechtigung für den QR-Scanner |
|
|
| 2026.9.4.7 | `CFBundleVersion` in beiden Bündeln - die App war vorher nicht installierbar |
|
|
| 2026.9.4.5 | Versionsnummern von App und Erweiterung angeglichen |
|
|
| 2026.9.2.7 | Share-Erweiterung, Zwischenablage- und Kalender-Plugin gebaut und signiert |
|
|
| 2026.8.30.8 | Erste signierte `.ipa`, Luftweg über Gitea eingerichtet |
|