English | 日本語
「どう数えるか」をイベントの定義自身に持たせる。数え方の規則が、呼び出し側の記憶ではなく定義の側にある。
swift-log / swift-metrics のような診断ログではありません。「何人が、どの画面で、何をしたか」を、
あとから分析できる形で残すためのものです。
計測の事故は「出ない」より出すぎるほうが多く、そしてどちらもテストでもレビューでも ダッシュボードでも落ちません。原因は発火点を 2 箇所に書いたことではなく、 数え方がどこにも書かれていなかったので、2 箇所に書いたことを誰も間違いだと言えなかったことです。 だから数え方を語彙に入れました。
- 数え方をカタログが持つ。「1 インストールに 1 回」「見えて 1 秒で 1 回」を発火点に覚えさせません
- カタログから Swift を生成する。 文字列でイベントを送る口が無いので、名前の打ち間違いも、 宣言していない引数の混入も起きません
- 重複の間引きは実施であって記憶ではない。 宣言した範囲を
DedupingAnalyticsが実施し、 発火点は「もう撃ったか」を一切書きません - 「見えた」の定義が閉じている。 面積の 50% 以上が連続して 1.0 秒。判定器は時計を持たないので、 シミュレータも実時間の待ちもなしにユニットテストで固定できます
- grep では書けない CI 監査。 宣言だけで撃たれていない出来事・同じ発火が 2 箇所にあること・ カタログを迂回した文字列直書きを、すべてビルドで落とします
- 外部依存ゼロ。 SwiftPM は依存をパッケージ単位で解決するので、送信先(Firebase / PostHog / 自前のサーバー)は別パッケージに置いています
- 端末で読めるログ画面。 実際に送られたものを、種別・数え方つきで、2 回出ているものには
×2を付けて表示します
出来事と、その数え方を宣言します。
# analytics.yaml
version: 1
dialect: ga4
swift:
event_type: AppEvent
events:
- name: paywall_shown
kind: impression # screen | impression | interaction | outcome
dedup: always # session | install | always
description: 課金の案内が実際に見えたSwift を生成し、生成物はコミットします。計測の変更は「何を測ることにしたか」の変更であり、 差分が唯一のレビュー材料だからです。
Scripts/analytics-gen.py generate --schema analytics.yaml --out Sources/App/Generated/AppAnalytics.swift発火点はこれだけです。
import AnalyticsSwiftUI
PaywallView().trackScreen(.paywallShown)API リファレンスとガイド — Getting Started、 Counting Rules、 What Not to Send を含みます。
カタログの書式は Schema/SCHEMA.md が仕様です。
.package(url: "https://github.com/no-problem-dev/swift-analytics.git", .upToNextMinor(from: "0.1.0"))| プロダクト | 中身 | 依存 |
|---|---|---|
AnalyticsCore |
語彙・ポート・数え方 | なし |
AnalyticsSwiftUI |
画面から撃つ層・端末で読むログ | SwiftUI |
AnalyticsTesting |
テストの土台 | なし |
送信先のアダプタは別パッケージです(swift-analytics-firebase)。 同居させると、語彙しか使わない消費者にまで vendor の SDK が降ってきます。
生成器は Python 3 だけで動きます(追加のインストールはありません)。
- iOS 17.0+ / macOS 14.0+ / tvOS 17.0+ / watchOS 10.0+ / visionOS 1.0+
- Swift 6.2+
- Python 3(カタログ生成器のみ)
MIT — LICENSE を参照してください。