SwiftEventTracker is a simple, yet flexible, event tracking library for Swift. It enables developers to track analytics events across multiple analytics service providers using a unified, declarative API. With SwiftEventTracker, you can easily integrate with various analytics platforms without coupling your code to any specific SDK.
To use SwiftEventTracker in your project, add the following dependency to your Package.swift
:
.package(url: "https://github.com/hectr/swift-event-tracker", from: "2.0.0"),
Then, add Tracker
to your target's dependencies:
.target(name: "YourAppTarget", dependencies: [
.product(name: "Tracker", package: "swift-event-tracker")
]),
Start by importing the Tracker
module:
import Tracker
1. Define Your Events and Screens:
Create your events and screens using the Event
and Screen
protocols or the provided conforming structs.
let loginEvent = ParameterizedEvent(name: "login", parameters: ["method": "email"])
let homeScreen = NamedScreen(name: "HomeScreen")
2. Configure Service Providers:
Initialize the EventTracker
with the service providers you want to use. Each service provider must conform to the Service
protocol.
let printProvider = PrintServiceProvider()
var tracker = EventTracker(serviceProviders: [printProvider])
3. Track Events and Screens:
Use the trackEvent and trackScreen methods to track events and screen views.
tracker.trackEvent(loginEvent)
tracker.trackScreen(homeScreen)
You can conditionally track events based on custom logic:
tracker.trackEvent(loginEvent, given: { user.isLoggedIn })
Conditional tracking can also be achieved by using the Tag
structure. See Custom Events and Screens, Properties and User Identifier sections.
You can create custom events by conforming to the Event
protocol. This allows you to define events with specific behavior, including setting excludedTags
and requiredTags
, which control whether the event should be tracked based on the tags supported by the service providers.
Here’s an example:
import Tracker
struct PurchaseEvent: Event {
let name: String = "purchase"
let parameters: [String: String]
let date: Date
var excludedTags: [Tag] {
return [.debugging] // Exclude this event from providers tagged with `.crashReporting`
}
var requiredTags: [Tag] {
return [.analytics] // Only track this event with providers tagged with `.analytics`
}
init(itemID: String, price: String) {
self.parameters = ["item_id": itemID, "price": price]
self.date = Date()
}
}
// Usage
let purchaseEvent = PurchaseEvent(itemID: "12345", price: "19.99")
tracker.trackEvent(purchaseEvent)
This event is compatible with any service provider. But only a provider with built-in support for it will handle the custom date
property.
Similarly, you can define custom screens by conforming to the Screen
protocol. This is useful for tracking screen views with custom logic, including the use of excludedTags
and requiredTags
.
Here’s an example:
import Tracker
struct ProductScreen: Screen {
let name: String = "ProductScreen"
let productID: String
var excludedTags: [Tag] {
return [.debugging] // Exclude this screen from providers tagged with `.debugging`
}
var requiredTags: [Tag] {
return [.analytics] // Only track this screen with providers tagged with `.analytics`
}
init(productID: String) {
self.productID = productID
}
}
// Usage
let productScreen = ProductScreen(productID: "67890")
tracker.trackScreen(productScreen)
Again, only service providers with built-in support for this screen will handle the custom productID
property.
See more examples in [./Sources/Tracker/events/vendor/](./Sources/Tracker/events/vendor/)
.
EventTracker
allows you to define properties and a user identifier that can be included in all tracked events. These attributes can be applied globally or selectively, depending on the tags associated with each service provider.
You can set global properties that will be sent with every event:
// Global property applied to all providers
tracker.setProperty("user_type", value: "premium")
// Property applied only to providers tagged with `.crashReporting`
tracker.setProperty("app_version", value: "1.2.3", forTags: [.crashReporting])
If needed, you can reset properties either globally or for specific tags:
// Reset properties only for providers tagged with `.debugging`
tracker.resetProperties(forTags: [.debugging])
// Reset all properties for all providers
tracker.resetProperties()
The user identifier is another key property that can be set globally or for specific service providers:
// Global user identifier applied to all providers
tracker.setUserId("user_12345")
// User identifier applied only to providers tagged with `.analytics`
tracker.setUserId("user_12345", forTags: [.analytics])
Similar to properties, the user identifier can also be reset globally or selectively:
// Reset user identifier for all providers
tracker.resetUserId()
// Reset user identifier only for providers tagged with `.logging` and `.crashReporting`
tracker.resetUserId(forTags: [.logging, .crashReporting])
You can dynamically update the list of service providers:
let appCenterProvider = AppCenterAnalyticsServiceProvider(adapter: Analytics.self)
let adjustProvider = AdjustServiceProvider(adapter: Adjust.self)
let taplyticsProvider = TaplyticsServiceProvider(adapter: Taplytics.self)
let instabugProvider = InstabugServiceAdapter(adapter: Instabug.self)
tracker.setServiceProviders([appCenterProvider, adjustProvider, taplyticsProvider, instabugProvider])
SwiftEventTracker supports a wide range of analytics service providers, including Firebase, Amplitude, Mixpanel, and more. To add support for a new provider, you need to implement the Service protocol and provide an adapter that conforms to the corresponding adapter protocol.
Here’s a simplified example:
import Tracker
class CustomAnalyticsProvider: Service, AbstractProvider {
let supportedTags: [Tag] = [.analytics]
func trackEvent(_ event: Event) {
// Implement custom event tracking logic here
}
}
For further customization, you can implement the methods trackScreen(_:)
, setUserId(_:)
, resetUserId()
, setProperty(_:value:)
, resetProperties()
, and disableTracking(_:)
.
SwiftEventTracker ships with multiple analytics providers:
- Adjust (provider, adapter example)
- Amplitude (provider, adapter example)
- AppCenter (provider, adapter example)
- AppsFlyer (provider, adapter example)
- Braze (provider, adapter example)
- Bugsee (provider, adapter example)
- Countly (provider, adapter example)
- Crashlytics (provider, adapter example)
- Facebook (provider, adapter example)
- Firebase (provider, adapter example)
- Heap (provider, adapter example)
- Instabug (provider, adapter example)
- Kochava (provider, adapter example)
- Localytics (provider, adapter example)
- Mixpanel (provider, adapter example)
- PostHog (provider, adapter example)
- Segment (provider, adapter example)
- SwiftAnalytics (provider, adapter example)
- SwiftAnalyticsKit (provider, adapter example)
- SwiftLogger (provider, adapter example)
- SwiftMetrics (provider, adapter example)
- Taplytics (provider, adapter example)
- UXCam (provider, adapter example)
The adapter implementation for each provider is left to the consumer. Below is an example of an adapter for Firebase:
import FirebaseAnalytics
import Tracker
extension Analytics: FirebaseAnalyticsServiceAdapter {}
// Usage
let firebaseProvider = FirebaseAnalyticsServiceProvider(adapter: Analytics.self)
var tracker = EventTracker(serviceProviders: [firebaseProvider])
This allows SwiftEventTracker to leverage Firebase's capabilities without directly depending on its SDK. Be aware that your application still needs to handle Firebase configuration and initialization.
You can find examples for the rest of supported services in the Examples package.
SwiftEventTracker is available under the MIT license. See the LICENSE file for more information.
Contributions are welcome! If you have ideas, suggestions, or would like to contribute to the codebase, feel free to open an issue or submit a pull request.