Files
audi-app/companion-app/scripts/ios-luftweg.sh
T
Paul Nothaft b4d44b2731 Signierte iOS-App gebaut und Luftweg-Installation vorbereitet
Phase 10 Schritt 7 ist damit erledigt. auslieferung/App.ipa, 2,4 MB, Ad-hoc
signiert mit "Apple Distribution: Paul Nothaft", Profil gueltig bis
29.08.2027, genau ein eingetragenes Geraet.

Zwei Annahmen von heute frueh waren falsch und sind korrigiert: die bezahlte
Mitgliedschaft stuft das bestehende Team hoch, statt ein neues anzulegen (die
Kennung bleibt RMACS9VLS4), und der Export als Ad-hoc funktioniert einwandfrei.

Neue Falle festgehalten: beim ersten Signieren fragt der Schluesselbund per
Dialog um Erlaubnis. Bleibt der unbeantwortet, haengt xcodebuild wortlos und
endet mit errSecInternalComponent. Die Diagnose steht in AGENTS.md, weil das
Symptom von sich aus nirgendwohin zeigt.

Neu: scripts/ios-luftweg.sh erzeugt manifest.plist, Installationsseite und
Symbole fuer die Uebertragung ueber die Luft. Es verweigert eine Basis-Adresse
ohne https, weil iOS sonst erst auf dem Telefon still scheitert.

Offen bleibt der Host, der die Dateien ausliefert.
2026-08-29 12:56:42 +02:00

125 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bereitet die Installation ueber die Luft vor: legt neben der signierten .ipa
# die manifest.plist und eine kleine Installationsseite ab.
#
# bash scripts/ios-luftweg.sh https://mein-mac.tailnetname.ts.net
#
# Warum das noetig ist: iOS installiert eine App nur dann ueber die Luft, wenn
# ein itms-services-Link auf eine manifest.plist zeigt, die wiederum die
# Adresse der .ipa enthaelt. Beide Adressen muessen ueber **HTTPS mit einem
# oeffentlich vertrauenswuerdigen Zertifikat** erreichbar sein - einfaches HTTP
# und selbstsignierte Zertifikate lehnt iOS kommentarlos ab. Home Assistant
# unter /local/ genuegt dafuer nicht, das laeuft im Tailnet unverschluesselt.
#
# Passend dazu und ohne offenen Port: `tailscale serve` liefert ein echtes
# Let's-Encrypt-Zertifikat auf <maschine>.<tailnet>.ts.net aus. Voraussetzung
# ist, dass in der Tailscale-Verwaltung HTTPS-Zertifikate aktiviert sind.
#
# tailscale serve --bg ios/build/luftweg
#
# Danach den ausgegebenen Link auf dem iPhone in **Safari** oeffnen (andere
# Browser reichen itms-services nicht an das System weiter).
set -euo pipefail
if [ $# -lt 1 ]; then
echo "Aufruf: bash scripts/ios-luftweg.sh <basis-url>" >&2
echo "Beispiel: bash scripts/ios-luftweg.sh https://mein-mac.tailnetname.ts.net" >&2
exit 1
fi
BASIS="${1%/}"
if [ "${BASIS#https://}" = "$BASIS" ]; then
echo "FEHLER: Die Basis-Adresse muss mit https:// beginnen." >&2
echo "iOS verweigert die Installation ueber die Luft ueber unverschluesseltes HTTP." >&2
exit 1
fi
HIER="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP="$(dirname "$HIER")"
IPA="$APP/auslieferung/App.ipa"
ZIEL="$APP/ios/build/luftweg"
[ -f "$IPA" ] || { echo "FEHLER: $IPA fehlt - erst scripts/ios-signieren.sh laufen lassen." >&2; exit 1; }
# Version aus der .ipa selbst lesen statt sie hier zu wiederholen: zwei Quellen
# fuer dieselbe Angabe waeren eine zu viel.
AUSPACK="$(mktemp -d)"
trap 'rm -rf "$AUSPACK"' EXIT
unzip -q "$IPA" -d "$AUSPACK"
PLIST="$(find "$AUSPACK/Payload" -maxdepth 2 -name Info.plist | head -1)"
KENNUNG="$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$PLIST")"
VERSION="$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$PLIST")"
rm -rf "$ZIEL"
mkdir -p "$ZIEL"
cp "$IPA" "$ZIEL/App.ipa"
cp "$APP/public/symbol-192.png" "$ZIEL/symbol-192.png"
cp "$APP/public/symbol-512.png" "$ZIEL/symbol-512.png"
cat > "$ZIEL/manifest.plist" <<PLISTENDE
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key><string>software-package</string>
<key>url</key><string>$BASIS/App.ipa</string>
</dict>
<dict>
<key>kind</key><string>display-image</string>
<key>url</key><string>$BASIS/symbol-192.png</string>
</dict>
<dict>
<key>kind</key><string>full-size-image</string>
<key>url</key><string>$BASIS/symbol-512.png</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key><string>$KENNUNG</string>
<key>bundle-version</key><string>$VERSION</string>
<key>kind</key><string>software</string>
<key>title</key><string>DataMetric360</string>
</dict>
</dict>
</array>
</dict>
</plist>
PLISTENDE
# Das kaufmaennische Und muss in HTML maskiert werden, sonst schneidet Safari
# den Link hinter dem url-Parameter ab.
cat > "$ZIEL/index.html" <<HTMLENDE
<!doctype html>
<html lang="de">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DataMetric360 installieren</title>
<style>
body { font-family: -apple-system, sans-serif; background: #161b23; color: #eef1f6;
margin: 0; display: grid; place-items: center; min-height: 100vh; }
main { text-align: center; padding: 2rem; }
h1 { font-weight: 300; font-size: 1.5rem; }
a { display: inline-block; margin-top: 1.5rem; padding: 0.9rem 2rem; border-radius: 999px;
background: #eef1f6; color: #161b23; text-decoration: none; font-size: 1.1rem; }
p { color: #8a94a3; font-size: 0.9rem; line-height: 1.5; }
</style>
<main>
<h1>DataMetric360</h1>
<p>Version $VERSION</p>
<a href="itms-services://?action=download-manifest&amp;url=$BASIS/manifest.plist">Installieren</a>
<p>In Safari oeffnen. Nach dem Antippen fragt iOS einmal nach,<br>danach erscheint die App auf dem Startbildschirm.</p>
</main>
</html>
HTMLENDE
echo "Ordner fertig: $ZIEL"
echo
echo "Ausliefern: tailscale serve --bg $ZIEL"
echo "Auf dem iPhone in Safari oeffnen: $BASIS/"