Die .ipa war nicht installierbar, plus QR-Scanner (2026.9.4.8)
Der Erweiterung fehlte CFBundleVersion - eine Pflichtangabe, ohne die iOS
die Installation der ganzen App verweigert ("kann nicht installiert werden").
Verursacht von der Versionsangleichung vom Vortag: das Skript reichte den
Platzhalter $(CURRENT_PROJECT_VERSION) statt einer Zahl weiter, und das per
Skript angelegte Ziel der Erweiterung kennt diese Build-Einstellung nicht.
An den entpackten .ipa nachgemessen, 2026.9.3.3 gegen 2026.9.4.5.
ios-signieren.sh reicht nur noch echte Zahlen weiter, das Gegenlesen der
fertigen .ipa bricht ab statt zu warnen, und abgelegt wird erst danach -
eine Datei, die die Pruefung nicht besteht, darf nicht in auslieferung/
landen.
Dazu:
- Kopfmarke statt Firmierung des Betreibers in der Tankstellen-Zeile
- dritter Suchbegriff: der Name ohne fuehrende Marke. Gemessen: Nominatim
findet "Shell, Pascalstr. 8, Ingolstadt" nicht, "Pascalstr. 8, Ingolstadt"
schon - daran blieb die Belegkarte der realen Instanz leer
- der Tankstellen-Verweis zeigt die Tankstelle, statt eine Route zu rechnen
- Cache-Brecher auf .ipa, Symbolen und manifest.plist
- QR-Scanner fuer den Zugangs-Token bei der Ersteinrichtung (jsQR statt
GoogleMLKit, damit der Xcode-Lauf kein pod install riskiert)
214/214 Tests, Panel als Modul geparst, live gegen audi_ha_test geprueft.
This commit is contained in:
@@ -1 +1 @@
|
||||
{"version":"2026.9.4.5","sha256":"ffea00a94ac842d8b6b233ebd91a1a97252c4b7b6a952c336ca7a6218eceef1e","bytes":270888,"gebaut":"2026-09-04T07:57:27Z"}
|
||||
{"version":"2026.9.4.8","sha256":"d6fe041f31480ff67d9b39884e9ef8b5ac5795d8575716d4638a9f557198bc49","bytes":319995,"gebaut":"2026-09-04T09:50:03Z"}
|
||||
Binary file not shown.
@@ -1236,6 +1236,38 @@ async function adresseAufloesen(adresse) {
|
||||
Erste Zeile Tankstelle und Strasse, zweite Zeile der Ort (Vorgabe des
|
||||
Eigentuemers, 04.09.2026). Ohne Komma bleibt alles in der ersten Zeile -
|
||||
lieber ein langer erster Eintrag als ein erfundener Ort. */
|
||||
/* Kopfmarken des deutschsprachigen Marktes. WORTGLEICH mit _MARKEN in
|
||||
shell_beleg_parser.py und MARKEN in companion-app/src/daten/tankstelle.ts -
|
||||
der Parser erkennt die Marke beim Einlesen, diese Liste erkennt sie
|
||||
nachtraeglich in dem, was gespeichert ist. Reihenfolge zaehlt:
|
||||
"TotalEnergies" muss vor "Total" stehen. */
|
||||
const MARKEN = [
|
||||
"TotalEnergies", "Total", "Aral", "Shell", "Eni", "Agip", "Esso", "OMV",
|
||||
"Avia", "Turmöl", "Turmoel", "Orlen", "Tamoil", "Westfalen", "Allguth",
|
||||
"Classic", "Sprint", "Raiffeisen", "BayWa", "Elan", "HEM", "Star", "JET",
|
||||
"bft", "BP", "Q1",
|
||||
];
|
||||
|
||||
/* Die Kopfmarke aus dem gespeicherten Stationsnamen - null, wenn keine
|
||||
bekannte darin steht.
|
||||
|
||||
`station_name` traegt je nach Alter des Belegs Verschiedenes: seit dem
|
||||
16.08.2026 setzt der Parser "Marke, Strasse, Ort" zusammen, aeltere Belege
|
||||
und jeder ohne erkennbare Marke tragen dort die Firmierung des Betreibers
|
||||
("A. Zrenner GmbH"). Die ist nach aussen nicht sichtbar und gehoert nicht in
|
||||
die Anzeige (Vorgabe des Eigentuemers, 04.09.2026).
|
||||
|
||||
Wortgrenzen sind Absicht: "Star" darf nicht in "Starnberg" treffen. */
|
||||
function markeErkennen(name) {
|
||||
const roh = (name || "").trim();
|
||||
if (!roh) return null;
|
||||
for (const marke of MARKEN) {
|
||||
const muster = new RegExp("\\b" + marke.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "\\b", "i");
|
||||
if (muster.test(roh)) return marke;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function adresseTeilen(adresse) {
|
||||
const roh = (adresse || "").trim();
|
||||
if (!roh) return { strasse: "", ort: "" };
|
||||
@@ -1244,9 +1276,14 @@ function adresseTeilen(adresse) {
|
||||
return { strasse: roh.slice(0, komma).trim(), ort: roh.slice(komma + 1).trim() };
|
||||
}
|
||||
|
||||
/* Oben Kopfmarke und Strasse mit Hausnummer, unten Postleitzahl und Ort.
|
||||
Ohne erkennbare Marke steht oben nur die Strasse - die Firmierung des
|
||||
Betreibers tritt NICHT an ihre Stelle. Ohne Anschrift bleibt der
|
||||
gespeicherte Name die einzige Auskunft und wird unveraendert gezeigt. */
|
||||
function tankstelleZeilen(name, adresse) {
|
||||
const { strasse, ort } = adresseTeilen(adresse);
|
||||
const oben = [(name || "").trim(), strasse].filter(Boolean).join(", ");
|
||||
if (!strasse && !ort) return { oben: (name || "").trim() || "unbekannt", unten: "" };
|
||||
const oben = [markeErkennen(name) || "", strasse].filter(Boolean).join(", ");
|
||||
return { oben: oben || "unbekannt", unten: ort };
|
||||
}
|
||||
|
||||
@@ -1255,8 +1292,20 @@ function tankstelleZeilen(name, adresse) {
|
||||
gemessen: "Pascalstr. 8, 85057 Ingolstadt" findet Nominatim, mit dem
|
||||
Betreibernamen davor nicht. Der Name ALLEIN ist trotzdem wertvoll
|
||||
("Shell, SOELDEN" findet es), deshalb der zweite Versuch. */
|
||||
/* Dritter Versuch: der Name OHNE die fuehrende Marke. Seit dem 16.08.2026
|
||||
setzt der Belegparser den Namen als "Marke, Strasse, Ort" zusammen; fehlt
|
||||
darin die Postleitzahl, kippt die Marke die Suche. Am 04.09.2026 gemessen:
|
||||
"Shell, Pascalstr. 8, Ingolstadt" findet Nominatim NICHT,
|
||||
"Pascalstr. 8, Ingolstadt" dagegen schon. Genau daran blieb die Karte auf
|
||||
der realen Instanz leer. */
|
||||
function tankstelleKandidaten(name, adresse) {
|
||||
return [(adresse || "").trim(), (name || "").trim()].filter(Boolean);
|
||||
const n = (name || "").trim();
|
||||
const marke = markeErkennen(n);
|
||||
const ohneMarke =
|
||||
marke && n.toLowerCase().startsWith(marke.toLowerCase())
|
||||
? n.slice(marke.length).replace(/^[ ,]+/, "").trim()
|
||||
: "";
|
||||
return [...new Set([(adresse || "").trim(), n, ohneMarke].filter(Boolean))];
|
||||
}
|
||||
|
||||
/** Der erste Suchbegriff - leer heisst: der Beleg nennt gar nichts. */
|
||||
@@ -1268,7 +1317,9 @@ function tankstelleSuchtext(name, adresse) {
|
||||
Apple Karten und Google Maps kennen Betriebsnamen und treffen damit die
|
||||
Zapfsaeule statt des Nachbargebaeudes. */
|
||||
function tankstelleZiel(name, adresse) {
|
||||
return [(name || "").trim(), (adresse || "").trim()].filter(Boolean).join(", ");
|
||||
const a = (adresse || "").trim();
|
||||
if (!a) return (name || "").trim();
|
||||
return [markeErkennen(name) || "", a].filter(Boolean).join(", ");
|
||||
}
|
||||
|
||||
/* Die Kandidaten der Reihe nach nachschlagen, erster Treffer gewinnt. */
|
||||
@@ -1286,15 +1337,26 @@ function apfelgeraet() {
|
||||
return /iPhone|iPad|iPod|Macintosh|Mac OS X/i.test(kennung);
|
||||
}
|
||||
|
||||
function kartendienstUrl(name, adresse, pos) {
|
||||
/* modus "route" berechnet den Weg, "zeigen" setzt nur eine Nadel. Der
|
||||
Tankstellen-Verweis im Einzelbeleg will das Zweite (Vorgabe des
|
||||
Eigentuemers, 04.09.2026): erst sehen, wo sie liegt - eine Route erwartet
|
||||
dort niemand, und sie ist im Kartendienst einen Tipp entfernt. */
|
||||
function kartendienstUrl(name, adresse, pos, modus = "route") {
|
||||
const beschriftung = (name || "").trim();
|
||||
const ziel = pos ? `${pos.lat},${pos.lon}` : tankstelleZiel(name, adresse);
|
||||
if (!ziel) return null;
|
||||
if (apfelgeraet()) {
|
||||
if (modus === "zeigen") {
|
||||
return pos
|
||||
? `https://maps.apple.com/?ll=${ziel}&q=${encodeURIComponent(beschriftung || "Ziel")}`
|
||||
: `https://maps.apple.com/?q=${encodeURIComponent(ziel)}`;
|
||||
}
|
||||
const q = pos && beschriftung ? `&q=${encodeURIComponent(beschriftung)}` : "";
|
||||
return `https://maps.apple.com/?daddr=${encodeURIComponent(ziel)}${q}`;
|
||||
}
|
||||
return `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(ziel)}`;
|
||||
return modus === "zeigen"
|
||||
? `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(ziel)}`
|
||||
: `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(ziel)}`;
|
||||
}
|
||||
|
||||
function kartendienstUrlZuPunkt(pos) {
|
||||
@@ -1308,8 +1370,12 @@ function tankstelleAufKarteZeigen(karte, pos, f) {
|
||||
if (!karte || !window.L || !pos) return;
|
||||
karte.setView([pos.lat, pos.lon], 14);
|
||||
const icon = window.L.divIcon({ className: "fahrzeug-pin-wrap", html: `<div class="fahrzeug-pin">${tankstellenMarkerSVG(32)}</div>`, iconSize: [32, 32], iconAnchor: [15, 31] });
|
||||
// Dieselben zwei Zeilen wie in der Wertezeile darunter (tankstelleZeilen) -
|
||||
// die Nadel soll nicht die Firmierung des Betreibers nennen, wenn die Zeile
|
||||
// die Kopfmarke zeigt.
|
||||
const zeilen = tankstelleZeilen(f.station_name, f.station_address);
|
||||
window.L.marker([pos.lat, pos.lon], { icon }).addTo(karte)
|
||||
.bindPopup((f.station_name || "") + "<br>" + (f.station_address || ""));
|
||||
.bindPopup(esc(zeilen.oben) + (zeilen.unten ? "<br>" + esc(zeilen.unten) : ""));
|
||||
// Position merken und den Knopf scharf schalten - er kann erst jetzt etwas
|
||||
// Sinnvolles tun (bei Adressauflösung kommt das hier verzögert, siehe
|
||||
// Aufrufstelle in initMap).
|
||||
@@ -4542,7 +4608,7 @@ function belegKarte(f) {
|
||||
ein Verweis, der nirgendwohin fuehrt, waere schlechter als keiner. */
|
||||
function tankstellenZeile(f) {
|
||||
const { oben, unten } = tankstelleZeilen(f.station_name, f.station_address);
|
||||
const url = kartendienstUrl(f.station_name, f.station_address);
|
||||
const url = kartendienstUrl(f.station_name, f.station_address, null, "zeigen");
|
||||
const inhalt =
|
||||
`<span class="tankstellenzeile-ort">${esc(oben)}${unten ? `<small>${esc(unten)}</small>` : ""}</span>` +
|
||||
(url ? `<svg class="chev" viewBox="0 0 6 10" aria-hidden="true"><polyline points="1,1 5,5 1,9"/></svg>` : "");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.9.4.5",
|
||||
"version": "2026.9.4.8",
|
||||
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
|
||||
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
|
||||
"codeowners": [
|
||||
|
||||
Reference in New Issue
Block a user