Skip to content

Phase-Analytics/Phase-Swift

Repository files navigation

Phase Analytics SDK for Swift

Privacy-first mobile analytics for iOS and macOS applications.

Swift Platforms License: AGPL-3.0 SPM Compatible

Features

  • Privacy by Default - No PII collected without explicit consent
  • Offline Support - Events queued locally and synced when online
  • SwiftUI Native - Built for modern Swift with async/await
  • Type Safe - Full Swift 6 concurrency support
  • Lightweight - Minimal impact on app size
  • Self-Hostable - Run on your own infrastructure

Requirements

  • iOS 15.0+ or macOS 12.0+
  • Swift 6.0+
  • Xcode 15.0+

Installation

Swift Package Manager

Add Phase Analytics to your project using Swift Package Manager:

In Xcode:

  1. Go to File → Add Package Dependencies
  2. Enter the repository URL: https://github.com/Phase-Analytics/Phase
  3. Select the latest version
  4. Add to your target

In Package.swift:

dependencies: [
    .package(url: "https://github.com/Phase-Analytics/Phase-Swift", from: "0.1.8")
]

Then add it to your target dependencies:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "PhaseAnalytics", package: "Phase")
    ]
)

Quick Start

SwiftUI

Wrap your app with the Phase view to initialize the SDK:

import SwiftUI
import PhaseAnalytics

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Phase(apiKey: "phase_xxx") {
                ContentView()
            }
        }
    }
}

Then identify the user and track events:

import SwiftUI
import PhaseAnalytics

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .onAppear {
                Task {
                    // Initialize analytics - no PII collected by default
                    await PhaseSDK.shared.identify()

                    // Track custom events
                    track("app_opened")
                }
            }
    }
}

UIKit

Initialize the SDK in your AppDelegate:

import UIKit
import PhaseAnalytics

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        Task {
            try await PhaseSDK.shared.initialize(apiKey: "phase_xxx")
            await PhaseSDK.shared.identify()
        }
        return true
    }
}

Configuration

The Phase view and initialize() method accept the following parameters:

Parameter Type Default Description
apiKey String Required Your Phase API key (starts with phase_)
baseURL String "https://api.phase.sh" Custom API endpoint for self-hosted deployments
logLevel LogLevel .none Console logging level (.info, .warn, .error, .none)
debugData Bool false Mark identify/events as debug data
deviceInfo Bool true Collect device metadata (model, OS version, platform, app version as app_version)
userLocale Bool true Collect user locale and timezone information

Example with Configuration

Phase(
    apiKey: "phase_xxx",
    logLevel: .info,
    debugData: false,
    deviceInfo: true,
    userLocale: true
) {
    ContentView()
}

API Reference

identify(_:)

Register the device and start a session. Must be called before tracking events.

// Basic usage - no PII collected
await PhaseSDK.shared.identify()

// With custom properties
await PhaseSDK.shared.identify([
    "user_id": "123",
    "plan": "premium",
    "beta_tester": true
])

track(_:params:)

Track custom events with optional parameters.

// Global function - event without parameters
track("app_opened")

// Global function - event with parameters
track("purchase_completed", [
    "amount": 99.99,
    "currency": "USD",
    "product_id": "premium_plan"
])

// Instance method
PhaseSDK.shared.track("button_clicked", params: ["button_id": "submit"])

trackScreen(_:params:)

Manually track screen views.

// Global function
trackScreen("/profile", ["user_id": "123"])

// Instance method
PhaseSDK.shared.trackScreen("/settings", params: nil)

.phaseScreen(_:params:) Modifier

Automatically track screen views in SwiftUI:

struct ProfileView: View {
    let userID: String

    var body: some View {
        VStack {
            Text("Profile")
        }
        .phaseScreen("ProfileView", params: ["user_id": userID])
    }
}

Screen names are normalized automatically (e.g., "ProfileView""/profile-view").

Documentation

For complete documentation, including:

  • Advanced configuration
  • Event tracking best practices
  • Screen tracking strategies
  • Type references
  • Privacy guidelines

Visit our documentation:

Swift Guide - Complete setup guide for iOS and macOS

Privacy

Phase Analytics is designed with privacy as a core principle:

  • No personal data is collected by default
  • Device IDs are generated locally and stored persistently using UserDefaults
  • Only technical metadata is collected (OS version, platform, locale, app version)
  • Geolocation is resolved server-side from IP address
  • All data collection is optional via configuration

Important: If you collect PII (personally identifiable information), ensure you have proper user consent.

How It Works

Offline Support

Events are queued locally using UserDefaults when offline. The queue automatically syncs when connection is restored.

Performance

  • Offline events are batched and sent asynchronously
  • Network state is monitored automatically
  • Failed requests retry with exponential backoff
  • Maximum batch size: 1000 events
  • Thread-safe with Swift 6 concurrency

Type Safety

All parameters must be primitives: String, Int, Double, Bool, or nil.

Event Naming Rules

  • Alphanumeric characters, underscores (_), hyphens (-), periods (.), forward slashes (/), and spaces
  • 1-256 characters
  • Examples: purchase, user.signup, payment/success, Button Clicked

Dependencies

Phase Analytics uses the following dependencies:

  • ULID.swift - Universally Unique Lexicographically Sortable Identifiers
  • GzipSwift - Data compression

License

This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.

Repository

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

Swift SDK for Phase Analytics - Privacy-first, open-source product analytics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors