137 lines
5.5 KiB
Bash
Executable File
137 lines
5.5 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> [zielordner]" >&2
|
|
echo "Beispiel: bash scripts/ios-luftweg.sh https://mein-mac.tailnetname.ts.net" >&2
|
|
echo "Gitea: bash scripts/ios-luftweg.sh \\" >&2
|
|
echo " https://gitea.nothaft.cloud/paul/audi-app/raw/branch/main/companion-app/auslieferung \\" >&2
|
|
echo " auslieferung" >&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"
|
|
# Zweites Argument erlaubt es, direkt in den versionierten Ordner zu schreiben -
|
|
# noetig, wenn nicht ein eigener Host ausliefert, sondern das Repository selbst.
|
|
ZIEL="$APP/${2:-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")"
|
|
|
|
mkdir -p "$ZIEL"
|
|
[ "$IPA" -ef "$ZIEL/App.ipa" ] || 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&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 "Wenn ein eigener Host ausliefert:"
|
|
echo " tailscale serve --bg $ZIEL"
|
|
echo " dann auf dem iPhone in Safari oeffnen: $BASIS/"
|
|
echo
|
|
# Gitea liefert rohe Dateien grundsaetzlich als text/plain aus - die
|
|
# index.html wird dort also als Quelltext angezeigt statt gerendert. Deshalb
|
|
# hier zusaetzlich der fertige Link zum Einfuegen in die Safari-Adresszeile;
|
|
# der funktioniert unabhaengig davon, ob eine Seite drumherum existiert.
|
|
echo "Ohne Seite (z. B. aus dem Repository heraus) direkt in Safari einfuegen:"
|
|
echo " itms-services://?action=download-manifest&url=$BASIS/manifest.plist"
|