Zum Inhalt springen
trackd.one

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 neutralem User-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:

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 über performExpiringActivity zu 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-After wird 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.

Kostenlos starten