DataLayer

public protocol DataLayer

The DataLayer module is a Collector module that provides persistent data storage functionality for the Tealium SDK. This module acts as a centralized data repository where applications can store key-value pairs that will be automatically included in all tracking events. It supports data expiration, transactional operations, and real-time data updates, making it essential for maintaining consistent data across tracking calls.

Note: This module cannot be disabled as it is a core component of the Tealium SDK.

Collected Data Points

The DataLayer module collects all data that has been previously stored in it by the application. The specific data points depend on what has been added to the data layer:

Data Point Key Description Source
Custom Data Variable Any data stored via DataLayer.put(key:value:expiry:) and similar methods Application

Note: The actual keys and values depend on what data has been stored in the DataLayer by your application.

Installation/Configuration

The DataLayer 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 - module will be initialized with default settings:

{
    "modules": {
        "DataLayer": {
            "module_type": "DataLayer"
        }
    }
}

Custom configuration - module with specific settings:

{
    "modules": {
        "DataLayer": {
            "module_type": "DataLayer",
            "order": 1,
            "rules": {
                "operator": "and",
                "children": [
                    "rule_id_from_settings"
                ]
            }
        }
    }
}

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.dataLayer(),
                              // other modules...
                          ])

Note: This module is automatically included and cannot be disabled, so it will be initialized even if not explicitly added to the modules list.

Custom configuration - module with enforced settings:

let config = TealiumConfig(account: "tealiummobile",
                          profile: "your-profile", 
                          environment: "dev",
                          modules: [
                              Modules.dataLayer(forcingSettings: { builder in
                                  builder.setOrder(1)
                                         .setRules(.and(["rule_id_from_settings"]))
                              }),
                              // 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.

⚠️ Note: This module cannot be disabled, and should not have any rules applied to it, as it provides essential data storage functionality. The setEnabled(false) method will have no effect on this module.

Settings Builders Reference

The DataLayer module uses the DataLayerSettingsBuilder for configuration. This is an extension of the CollectorSettingsBuilder which offers common settings like:

Note: The ModuleSettingsBuilder.setEnabled(_:) method is available but has no effect since this module cannot be disabled.

Usage

You can use the dataLayer by accessing an interface on the Tealium object.

tealium.dataLayer.put(key: "some_key", value: "some value", expiry: .forever).subscribe { result in
            // Optionally handle result here
        }

See more on the interface definition below.

DataLayer

A storage where the application can insert some data to be added to each tracking call.

You can potentially also extract data that was previously added via various getters. If you want to add several read and writes in a transaction, you can use transactionally and execute all the transaction with the provided synchronous blocks.

Warning

All the blocks passed in this protocol’s methods will always be run on a Tealium queue.

Type aliases

  • A block used to apply a DataStoreEdit.

    The DataLayer will not be changed until the transaction is committed. Applying after commit does nothing.

    Declaration

    Swift

    typealias Apply = (_ edit: DataStoreEdit) -> Void

    Parameters

    edit

    The DataStoreEdit to be applied once the transaction is committed.

  • Get

    A block to retrieve something synchronously from the DataLayer.

    Applied, but not committed, edits won’t be reflected in the items returned by this block.

    Declaration

    Swift

    typealias Get = (_ key: String) -> DataItem?

    Parameters

    key

    The key used to look up data in the DataLayer.

    Return Value

    The DataItem if one was found for the provided key.

  • A block used to commit the transaction. It will commit all the edits that were previously applied.

    Committing more than once does nothing.

    Throws

    An error when the transaction fails.

    Declaration

    Swift

    typealias Commit = () throws -> Void
  • A block that offers utility synchronous methods to perform operations on the DataLayer in a transaction.

    Warning

    This block will always be run on a Tealium queue.

    Declaration

    Swift

    typealias TransactionBlock = (_ apply: Apply, _ getDataItem: Get, _ commit: Commit) throws -> Void

    Parameters

    apply

    A block that can be called to apply a DataStoreEdit.put or DataStoreEdit.remove. The DataLayer will not be changed until the transaction is committed. Applying after commit does nothing.

    getDataItem

    A block to retrieve something synchronously from the DataLayer. Applied, but not committed, edits won’t be reflected in the items returned by this block.

    commit

    A block used to commit the transaction. It will commit all the edits that were previously applied. Committing more than once does nothing.

Inserts

  • Allows editing of the DataLayer using a TransactionBlock that provides methods to Apply edits, Get some DataItems from the data layer and finally Commit the changes in the end, all in a synchronous way.

    The DataLayer will not be changed until the transaction is committed. Applying after commit does nothing. Applied, but not committed, edits won’t be reflected in the items returned by this block. Committing more than once does nothing.

    Warning

    The block will always be run on a Tealium queue.

    Usage example:

     teal.dataLayer.transactionally { apply, getDataItem, commit in
       apply(.put(key: "key1", value: "value", expiry: .forever))
       apply(.put(key: "key2", value: "value2", expiry: .untilRestart))
       apply(.remove(key: "key3"))
       if let count = getDataItem("key4")?.get(as: Int.self) {
           apply(.put(key: "key4", value: count + 1, expiry: .forever))
       }
       do {
           try commit()
       } catch {
           print(error)
       }
     }
     - returns: A Single which can be used to subscribe a block of code to receive any errors that occur
    

    Declaration

    Swift

    @discardableResult
    func transactionally(execute block: @escaping TransactionBlock) -> SingleResult<Void, ModuleError<Error>>
  • Adds all key-value pairs from the DataObject into the storage.

    Declaration

    Swift

    @discardableResult
    func put(data: DataObject, expiry: Expiry) -> SingleResult<Void, ModuleError<Error>>

    Parameters

    data

    A DataObject containing the key-value pairs to be stored.

    expiry

    The time frame for this data to remain stored.

    Return Value

    A Single onto which you can subscribe to receive the completion with the eventual error in case of failure.

  • Adds a single key-value pair into the DataLayer.

    Declaration

    Swift

    @discardableResult
    func put(key: String, value: DataInput, expiry: Expiry) -> SingleResult<Void, ModuleError<Error>>

    Parameters

    key

    The key to store the value under.

    value

    The DataInput to be stored.

    expiry

    The time frame for this data to remain stored.

    Return Value

    A Single onto which you can subscribe to receive the completion with the eventual error in case of failure.

Getters

  • Gets a DataItem from the DataLayer.

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getDataItem(key: String) -> SingleResult<DataItem?, ModuleError<Error>>

    Parameters

    key

    The key used to look for the DataItem.

    Return Value

    A Single onto which you can subscribe to receive the completion with DataItem or the eventual error in case of failure.

  • Gets a DataObject containing all data stored in the DataLayer.

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getAll() -> SingleResult<DataObject, ModuleError<Error>>

    Return Value

    A Single onto which you can subscribe to receive the completion with DataObject or the eventual error in case of failure.

Deletions

  • Removes and individual key from the DataLayer.

    Declaration

    Swift

    @discardableResult
    func remove(key: String) -> SingleResult<Void, ModuleError<Error>>

    Parameters

    key

    The key to remove from storage.

    Return Value

    A Single onto which you can subscribe to receive the completion with the eventual error in case of failure.

  • Removes multiple keys from the DataLayer.

    Declaration

    Swift

    @discardableResult
    func remove(keys: [String]) -> SingleResult<Void, ModuleError<Error>>

    Parameters

    keys

    The list of keys to remove from storage.

    Return Value

    A Single onto which you can subscribe to receive the completion with the eventual error in case of failure.

  • Clears all entries from the DataLayer.

    Declaration

    Swift

    @discardableResult
    func clear() -> SingleResult<Void, ModuleError<Error>>

    Return Value

    A Single onto which you can subscribe to receive the completion with the eventual error in case of failure.

Events

  • A Subscribable to which you can subscribe to receive all the data that was updated in the DataLayer.

    Warning

    The events will always be reported on a Tealium queue.

    Declaration

    Swift

    var onDataUpdated: any Subscribable<DataObject> { get }
  • A Subscribable to which you can subscribe to receive all the data that was removed from the DataLayer.

    This Subscribable will receive events for both data manually removed and for data expired.

    Warning

    The events will always be reported on a Tealium queue.

    Declaration

    Swift

    var onDataRemoved: any Subscribable<[String]> { get }

Utility Getters

  • Returns the data, in the completion block, at the given key if the conversion is possible to the requested type .

    Supported types are:

    • Double
    • Float
    • Int
    • Int64
    • Decimal
    • Bool
    • String
    • NSNumber

    The type must be specified as a parameter:

     let dataLayer: DataLayer = ...
     dataLayer.get(key: "someKey", as: Int.self).onSuccess { anInt in
    
     }
    

    Every numeric type (Int, Int64, Float, Double, NSNumber) can be used interchangeably and the conversion will be made following NSNumber conversion methods.

     let nsNumber = NSNumber(1.5)
     let dataLayer: DataLayer
     dataLayer.put("someKey", nsNumber)
     dataLayer.get("someKey", as: Double.self).onSuccess { aDouble in
      // Double(1.5)
     }
     dataLayer.get(key: "someKey", as: Int.self).onSuccess { anInt in
      // Int(1)
     }
    

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func get<T>(key: String, as type: T.Type) -> SingleResult<T?, ModuleError<Error>> where T : DataInput

    Parameters

    key

    The key in which to look for the convertible item.

    type

    The type to convert the item into. Can be omitted if it’s inferred in the completion block.

    Return Value

    A Single onto which you can subscribe to receive the completion with the DataInput or the eventual error in case of failure.

  • Returns the value at the given key, after converting it via the converter, in the completion block.

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getConvertible<T>(key: String, converter: any DataItemConverter<T>) -> SingleResult<T?, ModuleError<Error>>

    Parameters

    key

    The key in which to look for the convertible item.

    converter

    The DataItemConverter used to convert the item, if found.

    Return Value

    A Single onto which you can subscribe to receive the completion with the converted item or the eventual error in case of failure.

  • Returns the value as an Array of DataItem if the underlying value is an Array, in the completion block.

    Warning

    Do not cast the return object as any cast will likely fail. Use the appropriate methods to extract value from a DataItem.

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getDataArray(key: String) -> SingleResult<[DataItem]?, ModuleError<Error>>

    Parameters

    key

    The key in which to look for the convertible item.

    Return Value

    A Single onto which you can subscribe to receive the completion with the DataItem array or the eventual error in case of failure.

  • Returns the value as a Dictionary of DataItem if the underlying value is a Dictionary, in the completion block.

    Warning

    Do not cast the return object as any cast will likely fail. Use the appropriate methods to extract value from a DataItem.

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getDataDictionary(key: String) -> SingleResult<[String : DataItem]?, ModuleError<Error>>

    Parameters

    key

    The key in which to look for the convertible item.

    Return Value

    A Single onto which you can subscribe to receive the completion with the DataItem dictionary or the eventual error in case of failure.

  • Returns the value at the given key as an Array of the (optional) given type, in the completion block.

    This method will follow the same principles of the get<T: DataInput>(key:as:completion:) counterpart, but applies them on the individual Array elements.

    Supported types are:

    • Double
    • Float
    • Int
    • Int64
    • Decimal
    • Bool
    • String
    • NSNumber

    The type must be specified as a parameter:

     let dataLayer: DataLayer = ...
     dataLayer.getArray(key: "someKey", of: Int.self).onSuccess { anIntArray in
    
     }
    

    Every numeric type (Int, Int64, Float, Double, Decimal, NSNumber) can be used interchangeably and the conversion will be made following NSNumber conversion methods.

     let nsNumber = NSNumber(1.5)
     let dataLayer: DataLayer
     dataLayer.getArray(key: "someKey", of: Double.self).onSuccess { aDoubleArray in
      // [Double(1.5)]
     }
     dataLayer.getArray(key: "someKey", of: Int.self).onSuccess { anIntArray in
      // [Int(1)]
     }
    

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getArray<T>(key: String, of type: T.Type) -> SingleResult<[T?]?, ModuleError<Error>> where T : DataInput

    Parameters

    key

    The key in which to look for the convertible item.

    type

    The type of elements contained in the Array. Can be omitted if it’s inferred in the completion block.

    Return Value

    A Single onto which you can subscribe to receive the completion with the array of items or the eventual error in case of failure.

  • Returns the value at the given key as a Dictionary of the (optional) given type, in the completion block.

    This method will follow the same principles of the get<T: DataInput>(key:as:completion:) counterpart, but applies them on the individual Dictionary elements.

    Supported types are:

    • Double
    • Float
    • Int
    • Int64
    • Decimal
    • Bool
    • String
    • NSNumber

    The type must be specified as a parameter:

     let dataLayer: DataLayer = ...
     dataLayer.getDictionary(key: "someKey", of: Int.self).onSuccess { anIntDictionary in
    
     }
    

    Every numeric type (Int, Int64, Float, Double, Decimal, NSNumber) can be used interchangeably and the conversion will be made following NSNumber conversion methods.

     let nsNumber = NSNumber(1.5)
     let dataLayer: DataLater
     dataLayer.getDictionary(key: "someKey", of: Double.self).onSuccess { aDoubleDictionary in
      // ["someKey": Double(1.5)]
     }
     dataLayer.getDictionary(key: "someKey", of: Int.self).onSuccess { anIntDictionary in
      // ["someKey": Int(1)]
     }
    

    Warning

    The completion will always be run on a Tealium queue.

    Declaration

    Swift

    func getDictionary<T>(key: String, of type: T.Type) -> SingleResult<[String : T?]?, ModuleError<Error>> where T : DataInput

    Parameters

    key

    The key in which to look for the convertible item.

    type

    The type of the values in the Dictionary. Can be omitted if it’s inferred in the completion block.

    Return Value

    A Single onto which you can subscribe to receive the completion with the dictionary of items or the eventual error in case of failure.

Utility Extension