VisitorIdManager
public protocol VisitorIdManager : Subscribable where Self.Element == Result<String, ModuleError<any Error>>
The VisitorId module is a Collector module that owns the anonymous visitor ID: it creates and persists it, adds it to every tracking event, and can switch it automatically when an identity stored in the data layer changes (Visitor Switching). It is enabled by default. Other modules read the visitor ID synchronously through the VisitorIdProvider protocol, exposed via ModuleManager; apps read and observe it through tealium.visitorId (a VisitorIdManager) on the Tealium object.
Collected Data Points
The VisitorId module collects the following information:
| Data Point | Key | Description | Source |
|---|---|---|---|
| Visitor ID | tealium_visitor_id |
The anonymous visitor identifier for this device | VisitorId module |
Installation/Configuration
The VisitorId module can be configured using three different approaches:
Local and Remote Settings
Configure the module using local JSON settings file (via settingsFile parameter) and/or remote settings (via settingsUrl parameter):
var config = TealiumConfig(account: "tealiummobile",
profile: "your-profile",
environment: "dev",
settingsFile: "TealiumSettings",
settingsUrl: "https://tags.tiqcdn.com/dle/tealiummobile/lib/example_settings.json")
Default initialization - the module is enabled by default, so no settings are needed to use it. Only if it’s added with Modules.visitorId(forcingSettings: nil) is it initialized just when configured in settings, like this:
{
"modules": {
"VisitorId": {
"module_type": "VisitorId"
}
}
}
Custom configuration - module with specific settings:
{
"modules": {
"VisitorId": {
"module_type": "VisitorId",
"enabled": true,
"order": 1,
"rules": {
"operator": "and",
"children": [
"rule_id_from_settings"
]
},
"configuration": {
"visitor_identity_key": "email"
}
}
}
}
When both local and remote settings are provided, they are deep merged with remote settings taking priority.
Programmatic Configuration
Configure the module programmatically by adding it to the modules parameter in TealiumConfig.
Default initialization - module will be initialized with default settings:
let config = TealiumConfig(account: "tealiummobile",
profile: "your-profile",
environment: "dev",
modules: [
Modules.visitorId(),
// other modules...
])
Note: This module is automatically included, so it will be initialized with default settings even if not explicitly added to the modules list.
Settings-driven initialization - pass nil to initialize the module only when Local or Remote settings configure it:
modules: [
Modules.visitorId(forcingSettings: nil),
// other modules...
]
Custom configuration - module with enforced settings:
let config = TealiumConfig(account: "tealiummobile",
profile: "your-profile",
environment: "dev",
modules: [
Modules.visitorId(forcingSettings: { builder in
builder.setOrder(1)
.setRules(.and(["rule_id_from_settings"]))
.setVisitorIdentityKey("email")
}),
// other modules...
])
⚠️ Important: Programmatic settings are deep merged onto local and remote settings and will always take precedence. Only provide programmatic settings for configuration values that you never want to be changed remotely, as they will override any remote updates.
To disable the module, set enabled: false in its settings or call setEnabled(false) on its builder. See Consequences of Disabling below.
Configuration Options
The VisitorId module supports the following configuration options:
| Setting | Key | Description | Default Value |
|---|---|---|---|
| Visitor Identity Key | visitor_identity_key |
The data layer key that holds the identity of the current user, used to drive Visitor Switching. | nil (Visitor Switching disabled) |
Settings Builders Reference
The VisitorId module uses the VisitorIdSettingsBuilder for configuration. This is an extension of the CollectorSettingsBuilder which offers common settings like:
ModuleSettingsBuilder.setEnabled(_:)ModuleSettingsBuilder.setOrder(_:)RuleModuleSettingsBuilder.setRules(_:)
VisitorId-specific methods:
VisitorIdSettingsBuilder.setVisitorIdentityKey(_:)- Set the data layer key that identifies the current user, enabling Visitor Switching
Visitor Switching
Visitor Switching links visitor IDs to identities you place in the data layer, such as an email address or a user ID, so that the same person is recognized across logins on the same device.
Visitor Switching is disabled while no visitor_identity_key is configured. Once configured, the SDK has no notion of login or logout — it simply watches that data layer key:
- Writing a new identity to the key, when the visitor ID is not owned by another identity, links that identity to the current visitor ID.
- Writing a known identity (one seen before on this device) restores the visitor ID it was previously associated with.
- Writing a different, unknown identity generates a new visitor ID and links it to that identity.
- Removing the key from the data layer does not change the visitor ID; it marks the identity as absent.
Resetting the Visitor ID
regenerate() always generates a new anonymous visitor ID. What happens to the identity association depends on whether an identity is present in the data layer (at the configured visitor_identity_key) at the time of the call:
- If an identity is present, it takes ownership of the new visitor ID, and its stored association is updated to point at it.
- If no identity is present, the new visitor ID is unowned: the next identity written to the data layer adopts it, and a returning identity restores its own previous visitor ID instead.
This gives two optional uses, neither of which is required:
- Regenerate after logout — remove the identity key from the data layer, then call
regenerate(), so the departing identity keeps its old visitor ID and the device continues anonymously with a fresh one. Callingregenerate()while an identity is still present instead rebinds that identity to the new visitor ID. - Regenerate before login — call
regenerate()immediately before writing a new identity to the data layer, so that new identity can never adopt whatever visitor ID the device had before. Both calls go through the Tealium queue in call order, so the regenerate is guaranteed to land before the identity write that follows it.
eraseLocalHistory() erases every stored identity association, then generates a new anonymous visitor ID. If an identity is present at the time of the call, it is immediately re-associated with the new visitor ID, so one new association may exist afterwards; remove the identity from the data layer first to erase without leaving any association behind.
Seeding the First Visitor ID
TealiumConfig.existingVisitorId seeds the very first visitor ID for this device — for example, to migrate an ID generated by a previous SDK. It only applies on first launch, before any visitor ID has been stored; it has no effect afterwards.
Consequences of Disabling
While the VisitorId module is disabled:
tealium_visitor_idis not added to tracking events.tealium.visitorIdand its methods (current(),regenerate(),eraseLocalHistory()) resolve to a.failure.- Identity-driven Visitor Switching stops: identity changes in the data layer are not observed.
- The Collect module still batches and sends events, grouping those without a visitor ID together.
- The ContextAPI module can’t fetch engine responses:
fetchEngineResponse(engineID:)fails withModuleError.moduleNotEnabled.
Usage
You can read and observe the visitor ID by accessing an interface on the Tealium object.
// Subscribe to the current visitor ID and every subsequent change
tealium.visitorId.subscribe { result in
switch result {
case .success(let visitorId):
// Use the current visitor ID
print("Visitor ID: \(visitorId)")
case .failure(.tealiumError(let error)):
// The Tealium instance failed to initialize or was shut down: this is the last emission
print("Visitor ID no longer available: \(error)")
case .failure(let error):
// The VisitorId module is disabled: successes resume if it is re-enabled
print("Failed to resolve visitor ID: \(error)")
}
}.addTo(disposable)
// Or read it once
tealium.visitorId.current().subscribe { result in
// Handle the result
}
// Generate a new anonymous visitor ID. If regenerating around a login or logout, see
// "Resetting the Visitor ID" above for where to place this call relative to the data-layer write.
tealium.visitorId.regenerate().subscribe { result in
// Handle the result
}
// Erase every stored identity association on this device, then generate a new anonymous visitor ID
tealium.visitorId.eraseLocalHistory().subscribe { result in
// Handle the result
}
While the module is disabled, every method completes with a .failure, and subscribers to visitorId changes receive a .failure that is followed by successes again if the module is later re-enabled. If the Tealium instance failed to initialize, or is shut down, every method completes with a .failure, and subscribers to visitorId changes receive a single .failure after which the subscription completes.
If regenerate() or eraseLocalHistory() can’t store their changes, they complete with a .failure, but the new visitor ID is still used until the app is relaunched. In this case nothing is stored, so on the next launch the previous visitor ID and every stored association are restored.
See more on the interface definition below.
VisitorIdManager
The anonymous visitor ID of this device, and the Visitor Switching state behind it.
This object is itself subscribable: subscribing emits the current visitor ID first, then again
on every change, whether caused by regenerate(), eraseLocalHistory(), or an
identity-driven switch when Visitor Switching is configured. Emissions are delivered on the
Tealium queue.
Visitor Switching is driven entirely by the data layer. An identity is present when the
visitor identity key (see
VisitorIdSettingsBuilder.setVisitorIdentityKey(_:))
holds a value in the data layer, and absent when that key has been removed or has expired. The SDK has no
notion of login or logout: a login is the app writing the identity to that key, a logout is the
app removing it.
Operations below that depend on an identity being present read the data layer at the time of the call.
Visitor ID handling can be disabled through settings. While visitor ID handling is disabled,
subscribers receive a .failure instead of a value, both at subscription time and if it becomes
disabled later; successes resume if it is re-enabled. These failures do not complete the subscription.
If the Tealium instance failed to initialize, or is later shut down, subscribers receive a single
ModuleError.tealiumError(_:) failure and the subscription completes.
Every method returns a failure result while visitor ID handling is disabled, and after the Tealium
instance failed to initialize or was shut down.
-
The visitor ID at the time of the call.
Equivalent to the first emission of a new subscription. To follow subsequent changes, subscribe to this object instead.
Declaration
Swift
func current() -> SingleResult<String, ModuleError<Error>>Return Value
The current visitor ID, or a failure if visitor ID handling is disabled.
-
Generates a new anonymous visitor ID and returns it.
Identity associations stored by Visitor Switching are left untouched. If an identity is present (see
VisitorIdManager), it takes ownership of the new ID and its stored association is updated. If none is present, the new ID is unowned: the next identity written to the data layer adopts it, and a returning identity restores its own previous visitor ID.Typical uses, both optional:
- after removing the identity from the data layer, so that events in the anonymous gap are not attributed to the previous identity. Remove the key before calling this method; calling it while the identity is still present rebinds that identity to the new ID.
- immediately before writing a new identity to the data layer, so that the next identity does not inherit that gap.
The previous visitor ID is not deleted from the device if an identity still owns it; it is restored when that identity returns.
If the new visitor ID can’t be stored, this fails with
ModuleError.underlyingError(_:), but the new visitor ID is still used until the app is relaunched: it is emitted to subscribers and added to events. The stored data is left unchanged, so the previous visitor ID is restored on the next launch.Declaration
Swift
@discardableResult func regenerate() -> SingleResult<String, ModuleError<Error>>Return Value
The new visitor ID, or a failure if visitor ID handling is disabled.
-
Erases every identity association Visitor Switching has stored on this device, then generates a new anonymous visitor ID and returns it.
Erased data: the hashed identities and the visitor IDs associated with them. No prior association survives the call.
If an identity is present (see
VisitorIdManager) it is immediately associated with the new visitor ID, so one new association may exist afterwards. To erase without any association remaining, remove the identity from the data layer first.This is a device-only operation intended for data-deletion requests. It does not remove the identity from the data layer, and it does not delete or alter server-side visitor profiles; those must be handled separately.
If the erasure can’t be stored, this fails with
ModuleError.underlyingError(_:)and nothing is erased, but the new visitor ID is still used until the app is relaunched: it is emitted to subscribers and added to events. On the next launch, the previous visitor ID and every stored association are restored.Declaration
Swift
@discardableResult func eraseLocalHistory() -> SingleResult<String, ModuleError<Error>>Return Value
The new visitor ID, or a failure if visitor ID handling is disabled.
View on GitHub