Advanced usage
User ID
The user ID lets you associate events from various sources with the same user. Each new visitor gets a randomly generated visitor ID. The SDK keeps this visitor ID between app launches. You can use the user ID to replace this random identifier with your own identifier, such as an email address or an ID from your customer relationship management system (CRM).
Use the userID property to set the user ID:
PiwikTracker.sharedInstance()?.userID = "John Doe"[PiwikTracker sharedInstance].userID = @"John Doe";- Use a non-empty string when you set a user ID. Pass
nil, or leave the property unset, if you don't want the SDK to send the user ID. The property itself is optional on the tracker.
The SDK doesn't sent the user ID is when data anonymization is enabled (isAnonymizationEnabled = YES).
User email address
DeprecatedThe user email address property
userEmailwas used by Audience Manager. Audience Manager is no longer available in the latest product version. Use the user ID for cross-source identity instead.
Device ID
DeprecatedThe
deviceIDproperty is no longer recommended. Audience Manager is no longer available in the latest product version, and the value is only forwarded on Audience Manager requests.
By default the device ID is empty (nil). You can set a non-empty string with the property (for example IDFA from Ad Support):
import AdSupport
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
PiwikTracker.sharedInstance()?.deviceID = idfa#import <AdSupport/ASIdentifierManager.h>
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
[PiwikTracker sharedInstance].deviceID = idfa;The device ID isn't sent if data anonymization is enabled.
Visitor ID
The SDK uses the visitor ID to track user sessions across different sources. The visitor ID is randomly generated when the tracker instance is created and is stored between application launches.
You can set the visitor ID manually with setVisitorID(newVisitorID:):
PiwikTracker.sharedInstance()?.setVisitorID(newVisitorID: "0123456789abcdef")[[PiwikTracker sharedInstance] setVisitorID:@"0123456789abcdef"];- For
setVisitorID, the ID must be exactly 16 characters and use only lowercase hexadecimal characters (0-9,a-f). If the input is invalid input, the SDK doesn't change the stored visitor ID.
When anonymization is enabled, the SDK issues a new visitor ID the first time it one needs one during an app run, then stores it. Every unique visitor have a different ID, and that ID must not change after assignment.
We recommend using the user ID, not the visitor ID, to identify users.
You can also use visitorIDLifetime to limit how long the current visitor ID stays valid. Set the lifetime in seconds.
When the visitor ID expires, the SDK assigns a new random visitor ID and clears visit-scoped data, such as default visit custom variables, custom dimensions, and campaign parameters.
Use 0 or less for no expiry.This is the default.
PiwikTracker.sharedInstance()?.visitorIDLifetime = 30 * 24 * 60 * 60[PiwikTracker sharedInstance].visitorIDLifetime = 30 * 24 * 60 * 60;Sessions
A session is a set of user interactions with your app.
By default, the SDK starts a new session when more than 30 minutesminutes without a queued analytics event. Only interactions that reach the local queue extend the session.
When optOut is enabled, no events are queued. When sampleRate is below 100, some events may be excluded before they reach the queue. Events that don't reach the queue don't extend the session. You can change the timeout with sessionTimeout:
PiwikTracker.sharedInstance()?.sessionTimeout = 30 * 60[PiwikTracker sharedInstance].sessionTimeout = 30 * 60;You can manually start a new session with startNewSession(). The no-argument version clears visit-level data stored on the tracker, such as visit custom variables. To keep that data, use startNewSession(preserveSessionParameters: true):
PiwikTracker.sharedInstance()?.startNewSession()
PiwikTracker.sharedInstance()?.startNewSession(preserveSessionParameters: true)[[PiwikTracker sharedInstance] startNewSession];
[[PiwikTracker sharedInstance] startNewSession:YES];Dispatching
Tracked events are stored in a local queue and dispatched every 30 seconds by default. You can change this behavior with dispatchInterval:
dispatchInterval = 0– Dispatch events immediately.dispatchInterval = -1– Disable automatic dispatching. Usedispatch()to send queued events manually.
PiwikTracker.sharedInstance()?.dispatchInterval = -1
do {
try processCart()
} catch {
PiwikTracker.sharedInstance()?.sendException(description: error.localizedDescription)
PiwikTracker.sharedInstance()?.dispatch()
}[PiwikTracker sharedInstance].dispatchInterval = -1;
@try {
[self processCart];
}
@catch (NSException *exception) {
[[PiwikTracker sharedInstance] sendExceptionWithDescription:exception.reason];
[[PiwikTracker sharedInstance] dispatch];
}When multiple events are queued, the SDK sends them in batches using POST requests with a JSON payload.
A single call to dispatch() may generate mutliple HTTP requests if the number of queued events exceeds the limit configured by eventsPerRequest.
To remove all queued events without sending them, use deleteQueuedEvents().
Default custom variables
The SDK can automatically add the following visit-scoped custom variables: the platform name, OS version, and app version. These values use indexes 1–3.
By default this is enabled by default. To turn it on or off, use includeDefaultCustomVariable:
PiwikTracker.sharedInstance()?.includeDefaultCustomVariable = false[PiwikTracker sharedInstance].includeDefaultCustomVariable = NO;If you need to use indexes 1–3 for your own data, disable this option and set custom variables manually with setCustomVariable (legacy) or use the recommended setCustomDimension.
App name and app version
By default, the SDK reads the app name from CFBundleDisplayName, or, if unavailable, CFBundleName. It builds the app version from CFBundleShortVersionString and CFBundleVersion, using the same format as the App version custom variable.
You can override these values with appName and appVersion:
PiwikTracker.sharedInstance()?.appName = "MyApp Beta"
PiwikTracker.sharedInstance()?.appVersion = "2.5.0-beta+build.123"[PiwikTracker sharedInstance].appName = @"MyApp Beta";
[PiwikTracker sharedInstance].appVersion = @"2.5.0-beta+build.123";Local storage limits
You can limit how long events are kept in local storage and how many events can be stored. Events older than the limit are discarded on the next dispatch attempt. The Piwik backend accepts back-dated events for up to 24 hours by default.
To change the maximum age of queued events, use maxAgeOfQueuedEvents:
PiwikTracker.sharedInstance()?.maxAgeOfQueuedEvents = 12 * 60 * 60[PiwikTracker sharedInstance].maxAgeOfQueuedEvents = 12 * 60 * 60;To change the maximum number of queued events, use maxNumberOfQueuedEvents. The default is 500. Setting the limit to0 stops new events from being queued.
PiwikTracker.sharedInstance()?.maxNumberOfQueuedEvents = 250[PiwikTracker sharedInstance].maxNumberOfQueuedEvents = 250;Anonymization
When anonymization is on, the user's IP address, location (only the country is reported), user ID, and device ID aren't collected. The SDK generates a new visitor ID each time the application starts. The ID is created the first time it's needed during that app session. The default value is YES.
PiwikTracker.sharedInstance()?.isAnonymizationEnabled = false[PiwikTracker sharedInstance].isAnonymizationEnabled = NO;Opt-out
When optOut is true, the SDK doesn't store new analytics events. The default value is false. This setting is saved across app restarts and upgrades.
Events that were queued before opt-out was enabled can still be uploaded with dispatch(). To remove them without sending, use deleteQueuedEvents().
PiwikTracker.sharedInstance()?.optOut = true[PiwikTracker sharedInstance].optOut = YES;Dry run
Use dryRun during development. Instead of sending events to the Piwik server, the SDK prints them to the console.
PiwikTracker.sharedInstance()?.dryRun = true[PiwikTracker sharedInstance].dryRun = YES;Sample rate
Use sampleRate to enable client-side sampling.
The value is a whole number from 1 to 100. Approximately sampleRate / 100 of Analytics** events are queued. The default value is 100, which disables sampling.
PiwikTracker.sharedInstance()?.sampleRate = 10[PiwikTracker sharedInstance].sampleRate = 10;URL prefixing
When isPrefixingEnabled is true (default), sendView() and sendViews() prepend the screen segment to the path you provide. For example settings becomes screen/settings.
This setting doesn't affect other tracking APIs.
Disable prefixing if you want use only the path strings you provide:
PiwikTracker.sharedInstance()?.isPrefixingEnabled = false[PiwikTracker sharedInstance].isPrefixingEnabled = NO;Using the SDK with SwiftUI
The SDK works with both UIKit (UIApplicationDelegate) and SwiftUI (App) lifecycles. This section covers the patterns you need when using the SwiftUI lifecycle, which has been the default lifecycle for new Xcode projects since iOS 14.
Initializing the tracker
The simplest place to configure the tracker is the App initializer. It runs once before any Scene or view is created:
import SwiftUI
import PiwikPROSDK
@main
struct MyApp: App {
init() {
PiwikTracker.sharedInstance(
siteID: "site-id",
baseURL: URL(string: "https://example.piwik.pro")!
)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}If you need UIApplicationDelegate callbacks, attach a small AppDelegate using @UIApplicationDelegateAdaptor. See Using the SDK with SwiftUI for a complete example.
Tracking screen views with .onAppear
.onAppearCall sendView() from the .onAppear modifier when the view appears. In a UIKit UIViewController, call it from viewDidAppear:
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, world!")
}
.onAppear {
PiwikTracker.sharedInstance()?.sendView(view: "Home")
}
}
}Reusable view modifier
If you track screen views from many views, define a small modifier so each call site stays a single line:
extension View {
func trackPiwikView(_ name: String) -> some View {
onAppear {
PiwikTracker.sharedInstance()?.sendView(view: name)
}
}
}
struct SettingsView: View {
var body: some View {
Form {
// ...
}
.trackPiwikView("Settings")
}
}Handling deep links with .onOpenURL
.onOpenURLAttach the .onOpenURL modifier to attribute incoming URLs to web sessions or pass campaign data. In a UIKit app delegate, handle the same URLs in application(_:open:options:).
sendCampaign() doesn't send an event by itself. Campaign parameters are stored and attached to the next analytics event the SDK sends, then cleared.
See Cross-platform tracking for more about pk_vid and sendCampaign() for campaign URL parameters.
Reason:
@main
struct MyApp: App {
init() {
PiwikTracker.sharedInstance(
siteID: "site-id",
baseURL: URL(string: "https://example.piwik.pro")!
)
}
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
// Cross-platform tracking: pick up pk_vid from the deep link
PiwikTracker.sharedInstance()?.setVisitorIdFrom(url: url)
// Campaign attribution: capture pk_campaign / pk_keyword
PiwikTracker.sharedInstance()?.sendCampaign(url: url.absoluteString)
}
}
}
}See cross-platform tracking for more about pk_vid and sendCampaign() for campaign URL parameters.
Tracking app installs and updates
Call the lifecycle methods from App.init() or from the AppDelegate adapter, if you use one.
applicationInstall() runs at most once per app installation on the device. It runs on the first launch after installation.If the app is reinstalled, it can run again.
applicationUpdate() runs at most once per each bundle version (CFBundleShortVersionString + CFBundleVersion).
@main
struct MyApp: App {
init() {
PiwikTracker.sharedInstance(
siteID: "site-id",
baseURL: URL(string: "https://example.piwik.pro")!
)
PiwikTracker.sharedInstance()?.applicationInstall()
PiwikTracker.sharedInstance()?.applicationUpdate()
}
var body: some Scene {
WindowGroup { ContentView() }
}
}Updated 2 months ago