Apps
iOS & macOS (Swift)
Analytics für iOS, iPadOS, macOS, tvOS, watchOS und visionOS — ohne Abhängigkeiten, ohne IDFA, ohne App-Tracking-Transparency-Abfrage.
Überblick
- Keine IDFA, keine IDFV, kein Gerätemodell, keine Install-ID — nichts Dauerhaftes, kein Fingerprinting.
- Nichts wird auf das Gerät geschrieben (keine UserDefaults, keine Dateien, kein Keychain). Events und Session-ID liegen nur im Arbeitsspeicher.
- Gebündelte Übertragung über eine ephemere
URLSession(keine Cookies, kein Cache) mit neutralemUser-Agent: trackd-ios/<version>. - Ein Privacy Manifest (
PrivacyInfo.xcprivacy) liegt bei.
Voraussetzungen: Xcode 15+ (Swift 5.9), iOS 13+ / macOS 11+ / tvOS 13+ / watchOS 7+ / visionOS 1+.
Installation
Ein Swift-Paket mit Versions-Tag folgt. Bis dahin kopierst du die Quellen in dein App-Target:
Trackd.swiftTrackScreenModifier.swift(SwiftUI.trackScreen(_:), optional)PrivacyInfo.xcprivacy— Einträge in das Privacy Manifest deiner App übernehmen
Lass dann import Trackd in den Beispielen weg (der Code ist Teil deines Moduls). Alternativ bindest du den Ordner sdk/ios als lokales Swift-Paket ein.
macOS (Sandbox, Mac Catalyst): Aktiviere Outgoing Connections (Client), sonst schlagen alle Requests still fehl:
<!-- *.entitlements (Debug + Release) -->
<key>com.apple.security.network.client</key>
<true/>
Einrichten
import SwiftUI
@main
struct MyApp: App {
init() {
Trackd.configure(websiteId: "YOUR_WEBSITE_ID")
// selbst gehostet: Trackd.configure(websiteId: "…", host: "https://stats.example.com", debug: true)
}
var body: some Scene { WindowGroup { ContentView() } }
}
UIKit: Trackd.configure(...) in application(_:didFinishLaunchingWithOptions:) aufrufen, auf dem Main Thread. Lege im Dashboard ein Projekt mit deiner Bundle-ID (z. B. com.example.mygame) als Domain an.
API
Trackd.configure(websiteId: String,
host: String = "https://trackd.one",
debug: Bool = false,
flushInterval: TimeInterval = 30, // Sekunden
flushAt: Int = 20)
Trackd.screen("Home") // Screen-View (Alias: screenView)
Trackd.screen("Settings/Profile", title: "Profile")
Trackd.event("signup", data: ["plan": "pro", "trial": true])
Trackd.revenue(4.99, currency: "EUR", orderId: "order-123") // → Event "purchase"
Trackd.flush()
Trackd.setEnabled(false) // Opt-out: stoppen + Warteschlange leeren
// Hilfsmethoden für Games & Medien
Trackd.gameStart(level: 1, mode: "hard")
Trackd.levelComplete(5, score: 1200, timeMs: 45_000)
Trackd.gameOver(3, reason: "fell")
Trackd.videoWatch("intro", durationMs: 30_000, completed: true)
Trackd.adView("rewarded", adId: "ad-1")
Trackd.tutorialStep(2, total: 5, skipped: false)
data muss flach sein: String, Zahlen oder Bool. Verschachtelte Werte, Datumswerte, nil, NaN und Infinity werden verworfen; das JSON ist auf 4 KB begrenzt.
Screens mit SwiftUI
struct HomeView: View {
var body: some View {
List { /* … */ }
.onAppear { Trackd.screen("Home") }
}
}
// oder mit dem mitgelieferten View-Modifier
struct SettingsView: View {
var body: some View {
Form { /* … */ }
.trackScreen("Settings")
}
}
UIKit: Trackd.screen("Home") in viewDidAppear(_:). Schreibe nie Nutzerdaten (Namen, E-Mails, IDs) in Screen-Namen.
Was gesendet wird
| Feld | Quelle |
|---|---|
platform |
ios, ipados, macos (inkl. Mac Catalyst), tvos, watchos, visionos |
app_version |
CFBundleShortVersionString |
os_version |
z. B. iOS 18.1 |
screen |
Bildschirmauflösung in Pixeln (Hochformat) |
language |
bevorzugte Sprache des Systems |
device |
tablet (iPad), mobile (iPhone, Watch), desktop (Mac, TV, Vision) |
App-Store-Datenschutzangaben
Nutzungsdaten → Produktinteraktion und Standort → Grober Standort (Land, serverseitig aus der IP abgeleitet), jeweils nicht mit der Identität verknüpft, nicht für Tracking, Zweck Analytics. Ergänze Käufe → Kaufhistorie, wenn du revenue nutzt. Tracking: Nein.
Batching, Wiederholungen & Sessions
- Senden bei 20 gesammelten Events, 30 s nach einem Event, bei
flush()und wenn die App in den Hintergrund geht — der Request läuft dann überperformExpiringActivityzu Ende. - Max. 50 Events / 60 KB pro Request, max. 500 Events in der Warteschlange.
- Netzwerkfehler,
5xx,408,429→ exponentielles Backoff (1 s … 5 min,Retry-Afterwird beachtet). - Session-ID: 20 zufällige Zeichen, nur im Speicher, neu nach 30 Minuten ohne Events oder 30 Minuten im Hintergrund.
In wenigen Minuten startklar
Kostenloses Konto erstellen, Website oder App hinzufügen, Snippet kopieren.