Audit 2026-05-17 V4. Ersetzt das hand-getippte Log.swift-Boilerplate
in jeder App durch einen Config-getriebenen Wrapper.
Neu:
- `ManaAppLog` — Factory fuer OSLog-Logger gegen ein ManaAppConfig.
Standard-Kategorien app/auth/api/db/web, plus `category("…")` fuer
app-spezifische Kategorien.
- `ManaAppConfig.appGroup: String?` (default nil) — Single-Source fuer
den App-Group-String, der heute in jeder App 3-4× hardcoded steht.
- `ManaAppConfig.logSubsystem: String` (default = keychainService) —
Subsystem fuer ManaAppLog.
Nichts breaking — beide neuen Felder haben Default-Implementations,
DefaultManaAppConfig.init hat zwei zusaetzliche optionale Parameter.
Tests: 4 neue ManaAppConfig-Tests + 5 neue ManaAppLog-Tests.
85/85 gruen (vorher 76/76).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.9 KiB
Swift
75 lines
2.9 KiB
Swift
import Foundation
|
||
|
||
/// App-spezifische Konfiguration für ManaCore. Wird von der konsumierenden
|
||
/// App beim Erzeugen eines `AuthClient` injiziert.
|
||
///
|
||
/// ManaCore hardcoded nichts App-Spezifisches. Bundle-ID, Auth-Server-URL
|
||
/// und Keychain-Adressierung kommen ausschließlich hierüber.
|
||
public protocol ManaAppConfig: Sendable {
|
||
/// Basis-URL des mana-auth-Servers, z.B. `https://auth.mana.how`.
|
||
var authBaseURL: URL { get }
|
||
|
||
/// Keychain-Service-Identifier, üblich `ev.mana.<app>`. Trennt
|
||
/// Token-Einträge verschiedener Apps voneinander, falls keine
|
||
/// shared Access-Group benutzt wird.
|
||
var keychainService: String { get }
|
||
|
||
/// Optional: Shared-Keychain-Access-Group für Cross-App-SSO.
|
||
/// `nil` bedeutet: nur App-eigener Keychain-Zugriff.
|
||
///
|
||
/// Wenn gesetzt, müssen alle teilnehmenden Apps unter derselben
|
||
/// Apple-Developer-Team-ID provisioniert sein und das Entitlement
|
||
/// `keychain-access-groups` mit demselben Wert tragen.
|
||
var keychainAccessGroup: String? { get }
|
||
|
||
/// App-Group für Daten-Sharing zwischen App ↔ Widget ↔ ShareExt.
|
||
/// Üblich `group.ev.mana.<app>`. `nil` für Apps ohne Extensions.
|
||
///
|
||
/// Single-Source für den App-Group-String, der heute in jeder App
|
||
/// 3-4× hardcoded steht (AppConfig + App-Entitlement + Widget-
|
||
/// Entitlement + ShareExt-Entitlement). Die Entitlements bleiben
|
||
/// hardcoded (das verlangt iOS), aber im Swift-Code ist der Wert
|
||
/// damit single-source.
|
||
var appGroup: String? { get }
|
||
|
||
/// OSLog-Subsystem für App-Logger, üblich `ev.mana.<app>`. Default
|
||
/// ist `keychainService` (der schon der Konvention folgt).
|
||
var logSubsystem: String { get }
|
||
}
|
||
|
||
// MARK: - Default-Implementationen
|
||
|
||
public extension ManaAppConfig {
|
||
/// Default `nil` — Apps ohne Widget/ShareExt müssen nichts setzen.
|
||
var appGroup: String? { nil }
|
||
|
||
/// Default = `keychainService`. Beide folgen heute in allen Apps
|
||
/// derselben Konvention `ev.mana.<app>`.
|
||
var logSubsystem: String { keychainService }
|
||
}
|
||
|
||
/// Standard-Implementierung von ``ManaAppConfig``. Apps können diese
|
||
/// nutzen oder ein eigenes Type adoptieren.
|
||
public struct DefaultManaAppConfig: ManaAppConfig {
|
||
public let authBaseURL: URL
|
||
public let keychainService: String
|
||
public let keychainAccessGroup: String?
|
||
public let appGroup: String?
|
||
public let logSubsystem: String
|
||
|
||
public init(
|
||
authBaseURL: URL,
|
||
keychainService: String,
|
||
keychainAccessGroup: String? = nil,
|
||
appGroup: String? = nil,
|
||
logSubsystem: String? = nil
|
||
) {
|
||
self.authBaseURL = authBaseURL
|
||
self.keychainService = keychainService
|
||
self.keychainAccessGroup = keychainAccessGroup
|
||
self.appGroup = appGroup
|
||
// Konvention: log-Subsystem = keychainService, falls nicht
|
||
// explizit anders gewünscht.
|
||
self.logSubsystem = logSubsystem ?? keychainService
|
||
}
|
||
}
|