// Spike D — App-Group-Container aus einem NICHT sandboxed Prozess // // Frage: liefert containerURL(forSecurityApplicationGroupIdentifier:) einen Pfad, // wenn der Prozess die App-Group-Entitlement trägt, aber NICHT sandboxed ist? // Davon hängt ab, ob Onyx den Calendarr-Snapshot direkt lesen kann oder eine // sandboxed Bridge-App braucht. // // Bauen und signieren: Spikes/build-appgroup-probe.sh import Foundation let groupID = "PP34X97WS3.group.com.scarriffleservices.calendarr" print("App-Group-Probe") print("Gruppe: \(groupID)") print("Sandboxed: \(ProcessInfo.processInfo.environment["APP_SANDBOX_CONTAINER_ID"] != nil ? "ja" : "nein")") print(String(repeating: "─", count: 64)) guard let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID) else { print("ERGEBNIS: nil") print() print("Der Container ist nicht erreichbar. Mögliche Ursachen:") print(" 1. Entitlement fehlt oder Signatur ungültig") print(" 2. Team-Präfix stimmt nicht byte-genau") print(" 3. App-Group ohne Sandbox wird doch nicht gewährt → Bridge-App nötig") exit(1) } print("ERGEBNIS: \(url.path)") print("Existiert: \(FileManager.default.fileExists(atPath: url.path) ? "ja" : "nein (Calendarr lief hier noch nie)")") // Schreibprobe — der Container muss beschreibbar sein, sonst wäre selbst ein // eigener Cache dort unmöglich. Berührt widget-cache.json NICHT. let probe = url.appendingPathComponent(".onyx-probe") do { try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true) try Data("ok".utf8).write(to: probe) try FileManager.default.removeItem(at: probe) print("Schreibzugriff: ja") } catch { print("Schreibzugriff: nein (\(error.localizedDescription))") } // Was liegt drin? Nur auflisten, nichts öffnen und nichts verändern. if let items = try? FileManager.default.contentsOfDirectory(atPath: url.path), !items.isEmpty { print("\nInhalt:") for item in items.sorted() { print(" \(item)") } } else { print("\nContainer ist leer — Calendarr-Mac-App noch nicht gestartet.") print("Das ist der Zustand .neverWritten, den das Kalender-Widget anzeigen muss.") } // Die Darwin-Notification, auf die Onyx später hört. Nur registrieren, um zu // bestätigen, dass das ohne Sandbox funktioniert. let name = "com.scarriffleservices.calendarr.snapshot-changed" CFNotificationCenterAddObserver( CFNotificationCenterGetDarwinNotifyCenter(), nil, { _, _, _, _, _ in print("Darwin-Notification empfangen") }, name as CFString, nil, .deliverImmediately) print("\nDarwin-Observer für '\(name)' registriert (ohne Fehler).")