← ClaudeAtlas

telemetry-facade-patternlisted

Single `Telemetry` SwiftPM target with a fan-out facade — callers say "what happened" (`telemetry.observe(event)`), facade dispatches to multiple sinks (OSLog / NoOp tracking / MetricKit / Game Center). Invoke when starting a new project that will log + track, deciding logger / tracker coupling, designing telemetry interfaces, or when asked "should Logger and Tracking be one thing".
wei18/apple-dev-skills · ★ 0 · AI & Automation · score 70
Install: claude install-skill wei18/apple-dev-skills
# Telemetry Facade Pattern ## When to invoke - Starting a new project and designing the logger / tracker / metrics interface. - About to introduce OSLog and any tracking / analytics at the same time. - Wanting to preserve flexibility for "swap the tracking provider later". - User asks "should Logger and Tracking be separate", "how should the event interface look". ## Default decisions ### A single `Telemetry` target - Create one `Telemetry` target inside the SwiftPM Package. - It contains: - `TelemetryEvent` value type (enum / struct, `Sendable`) - `TelemetrySink` protocol - The main facade — default to a `Telemetry` **actor**. Sink stateful subscriptions (e.g. `MetricKitSink` holding `MXMetricManagerSubscriber` reference identity) require an actor for clean lifecycle management. A `Sendable` struct facade is acceptable only when every sink is fully synchronous and stateless. The facade fans out to multiple sinks. - Default sinks (see below) ### Call sites describe only "what happened" ```swift telemetry.observe(.puzzleCompleted(id: puzzleId, durationMs: 12_345)) ``` - The call site **doesn't know** who will consume the event. - Swapping providers / adding sinks only requires replacing a sink; call sites change nothing. ### Default sink set | Sink | Receives | Purpose | |---|---|---| | `OSLogSink` | All events | Human-readable debug messages | | `TrackingSink` (default `NoOpTrackingSink`) | Business events | v1 has no third-party tracking but the protocol is