Einzelstueck-QR ueber Custom-Scheme statt Universal Link
Universal Links (Associated Domains) sind an eine feste Domain gebunden - fuer einen selbstgehosteten Dienst untauglich (jede Instanz hat eine andere URL) und die Domain stand im offenen Quellcode (Leak). Jetzt tragen Einzelstueck-QRs das Custom-Scheme vorrania://i/<UID>: Die normale Kamera-App oeffnet die App weiterhin, aber ohne Domain-Bindung und ohne Server im Code. applinks-Eintrag entfernt. Web: itemDeepLink()-Helfer, genutzt in Einzelstuecke-Liste/-Etiketten und im P-touch-Export. Lagerort-QRs bleiben unveraendert (https). iOS: Router erkennt vorrania://i/<UID> und oeffnet das Einzelstueck am aktiven Server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -30,17 +30,31 @@ final class Router: ObservableObject {
|
||||
route = .expiring
|
||||
}
|
||||
|
||||
/// vorrania://checkin bzw. vorrania://checkout – oder ein Universal Link
|
||||
/// (https://…/i/<UID>), der das Einzelstück direkt öffnet.
|
||||
/// vorrania://checkin | checkout … (Aktionen) oder vorrania://i/<UID>
|
||||
/// (Einzelstück – aus einem gescannten QR, auch über die normale Kamera-App).
|
||||
///
|
||||
/// Früher lief das Einzelstück über einen Universal Link auf eine feste Domain.
|
||||
/// Das war für einen selbstgehosteten Dienst untauglich (jede Instanz hat eine
|
||||
/// andere URL, und die Domain stünde im offenen Quellcode). Das Custom-Scheme
|
||||
/// braucht keine Domain: Die Kamera-App öffnet den QR trotzdem, und der Code
|
||||
/// verrät keinen Server.
|
||||
func handle(url: URL) {
|
||||
if url.scheme == "vorrania" {
|
||||
let target = (url.host ?? url.path.replacingOccurrences(of: "/", with: "")).lowercased()
|
||||
if let route = Route(rawValue: target) { self.route = route }
|
||||
// Host + Pfad zu Bestandteilen ohne Trenner: ["i","ABC123"] bzw. ["checkin"].
|
||||
let comps = ([url.host].compactMap { $0 } + url.pathComponents)
|
||||
.filter { $0 != "/" && !$0.isEmpty }
|
||||
// Einzelstück: vorrania://i/<UID> – am aktuell aktiven Server öffnen.
|
||||
if let i = comps.firstIndex(where: { $0.lowercased() == "i" }), i + 1 < comps.count {
|
||||
openItemUid = comps[i + 1].uppercased()
|
||||
return
|
||||
}
|
||||
if let route = comps.first.flatMap({ Route(rawValue: $0.lowercased()) }) { self.route = route }
|
||||
return
|
||||
}
|
||||
let parts = url.pathComponents // z.B. ["/", "i", "ABC123"]
|
||||
// Alt-Fall: Universal Link (…/i/<UID>) – nur noch relevant, falls je wieder
|
||||
// eine Associated Domain hinterlegt würde (dann Serverwechsel per Host).
|
||||
let parts = url.pathComponents
|
||||
if let idx = parts.firstIndex(of: "i"), idx + 1 < parts.count {
|
||||
// Auf den Server aus dem Link wechseln, damit die UID dort gesucht wird.
|
||||
Session.shared.switchToProfile(matching: url)
|
||||
openItemUid = parts[idx + 1].uppercased()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user