Swift Custom Configuration

Initialization Options

Heap.shared.startRecording accepts a variety of options meant to customize core and autocapture SDK behavior.

These properties are passed in using the options parameter:

Heap.shared.startRecording("YOUR_APP_ID", with: [
  .uploadInterval: 60, // Upload every 60 seconds instead of every 15.
  .baseUrl: "https://heap-proxy.example.com", // Send Heap data through a proxy.
])
[Heap.sharedInstance startRecording:@"YOUR_APP_ID" withOptions:@{
  HeapOption.uploadInterval: @60, // Upload every 60 seconds instead of every 15.
  HeapOption.baseUrl: @"https://heap-proxy.example.com", // Send Heap data through a proxy.
}];

The Option dictionary accepts any value type and values are validated and copied during startRecording. To confirm which values are applied, use LogLevel.debug before startRecording.

Core Configuration Options

startSessionImmediately (Bool)

Whether or not to start the session immediately when startRecording is called. Defaults to false.

The default behavior is to wait for the first event (either from track or autocapture) before starting the session to prevent sessions from starting during background app launches.

baseUrl (String or URL)

The base URL to upload data to while Heap is running. This follows relative link mechanics must end with a / for paths to resolve correctly.

This parameter primarily exists for testing and proxying purposes, and in the majority of use cases this parameter should not be set.

uploadInterval (TimeInterval or Int or Double literal)

The interval at which event batches should be uploaded to the API. Defaults to 15 seconds.

For apps with limited connectivity, it may make sense to increase this interval. Note: Shorter upload intervals may impact device battery life but improve the experience while using Live View to define events.

captureAdvertiserId (Bool)

Whether or not to track advertisingIdentifier in events. Defaults to false.

This has no effect if AdSupport hasn’t been linked in the app and will only provide a valid value if the user has authorized the app to access the advertiser ID.

Autocapture Configuration Options

disablePageviewAutocapture (Bool)

Whether or not to disable pageview autocapture. Defaults to false.

If set, registered autocapture libraries are instructed not to capture pageviews.

disablePageviewTitleCapture (Bool)

Whether or not to disable pageview title capture. Defaults to false.

If set, the core SDK will prevent pageview titles from being stored or uploaded and autocapture libraries will be instructed not to capture them.

disableInteractionAutocapture (Bool)

Whether or not to disable interaction autocapture. Defaults to false.

If set, registered autocapture libraries are instructed not to capture user interactions.

disableInteractionTextCapture (Bool)

Whether or not to disable user interface text capture. Defaults to false.

If set, the core SDK will prevent user interface text from being stored or uploaded and autocapture libraries will be instructed not to capture them.

📘

Because text can be copied over to accessibility labels when accessibility services are enabled, you may also want to set disableInteractionAccessibilityLabelCapture if using this property.

disableInteractionAccessibilityLabelCapture (Bool)

Whether or not to disable user interface accessibility label capture. Defaults to false.

If set, the core SDK will prevent user interface accessibility labels from being stored or uploaded and autocapture libraries will be instructed not to capture them.

disableInteractionReferencingPropertyCapture (Bool)

Whether or not to disable user interface referencing property capture. Defaults to false.

If set, the core SDK will prevent user interface referencing property names from being stored or uploaded and autocapture libraries will be instructed not to capture them. By default, the UIKit autocapture SDK will use Mirror to identify the property name for a view in its container.

interactionHierarchyCaptureLimit (Int)

The maximum number of UI elements to traverse when building a view ancestry. Defaults to 30.

If set, registered autocapture libraries are instructed use this limit when scanning the hierarchy.

useObjectiveCClassNames (Bool)

Whether or not to use the same naming logic used in the Classic iOS SDK. Defaults to false.

If set, the autocapture SDK will use Objective-C class names when capturing ViewController, Target View, and Hierarchy. This option is most useful for customers who previously used the Classic SDK with the same app, as it will preserve consistency with existing data and event definitions.

Add Custom Object Data to Event Properties

Heap methods like track, addUserProperties, and addEventProperties, already accepts number, boolean, and string data as values for event properties, but there might be times where you want to include custom objects as property values. While Swift and Objective-C support string descriptions with the CustomStringConvertible and CustomDebugStringConvertible interfaces, this is often used for custom logging or display purposes, which might not be the exact data that you want to track. To prevent alterations to your existing implementations, we’ve introduced a new protocols, HeapPropertyValue and HeapObjcPropertyValue, that your types can implement to be used as event property values.

An example implementation might look something like this:

struct Book {
  let title: String
  let author: String
  let year: Int
}

extension Book: HeapPropertyValue {
  var heapValue: String { title }
}
@interface Book: NSObject
@property (nonatomic, nonnull, copy) NSString *title;
@property (nonatomic, nonnull, copy) NSString *author;
@property (nonatomic) NSInteger year;
@end

@interface Book (PropertyValue) <HeapObjcPropertyValue>
@end

@implementation Book (PropertyValue)

- (nonnull NSString *)heapValue
{
  return self.title;
}

@end

After implementing the HeapPropertyValue protocol, objects of this type can now be passed into track calls as a custom property value. While objects of this type can also be used with the addEventProperties API, it’s important to note that the properties are stored as strings behind the scenes and will not update if the object is updated.

Customizing SDK Logs

Setting the Log Level

The Heap Swift SDKs output logs at industry-standard log levels based on the severity and usefulness of the log message being printed. You can customize how much is logged to the console by setting the log level like so:

Heap.shared.logLevel = .debug
Heap.sharedInstance.logLevel = HeapLogLevelDebug;

Heap can be customized to print logs at the following log levels:

  • LogLevel.none (HeapLogLevelNone): Heap will not print any log messages.
  • LogLevel.error (HeapLogLevelError): Heap will only print the most critical log messages, such as when the SDK encounters an error and needs to shut down.
  • LogLevel.warn (HeapLogLevelWarn): Heap will print warning messages for recoverable errors, such as when unexpected data types are passed into the SDK or the network is unreachable. Also includes from error logs.
  • LogLevel.info (HeapLogLevelInfo): Heap will print messages that are useful in a production environment, such as when recording starts/stops, when a batch of events is successfully sent, or when a new session has begun.
    This level is recommended for production environments so that developers can see Heap lifecycle messages in their own logging environment. Also includes error and warn logs.
  • LogLevel.debug (HeapLogLevelDebug): Heap will print messages that the implementing developer may find helpful. Messages may include things such as invalid environment ID value, truncated event names, or attempting to track an event before recording has started.
    This level is recommended for implementing developers during the development process to help with debugging normal installation and tracking issues. Also includes error, warn, and info logs.
  • LogLevel.trace (HeapLogLevelTrace): Heap will print messages that help the Heap team diagnose SDK issues. Heap support may ask the implementing developers to enable this log level to gain better insight into issues developers may have encountered when implementing the Heap SDK.
    Full event details are also printed at this level.
    This level is recommended when gathering information to send to Heap support personnel. Heap support may also ask that this level be turned on to help debug installation and tracking issues that require extra investigation. Also includes error, warn, info, and debug logs.

Routing Logs to Custom Destinations

In addition to customizing how much is printed by setting the log level, you can also customize where logs are printed by setting a custom log channel. By default, all logs are printed using OSLog (source). If you’re using a logging library like CocoaLumberJack or SwiftLog and want to send all logs through those channels instead, simply make a new LogChannel and pass it to Heap like so:

import Logging

class SwiftLogChannel: LogChannel {

  let logger: Logger    
  
  func printLog(logLevel: HeapSwiftCore.LogLevel, message: () -> String, source: String?, file: String, line: UInt) {
    
    switch logLevel {
    case .trace:
      logger.trace(message(), file: file, line: line)
    case .debug:
      logger.debug(message(), file: file, line: line)
    case .info:
      logger.info(message(), file: file, line: line)
    case .warn:
      logger.warn(message(), file: file, line: line)
    case .error:
      logger.error(message(), file: file, line: line)
    default:
      break
    }
  }
}

...

Heap.shared.logChannel = SwiftLogChannel(logger: logger)
import CocoaLumberjackSwift

class LumberjackLogChannel: LogChannel {

  func printLog(logLevel: HeapSwiftCore.LogLevel, message: () -> String, source: String?, file: String, line: UInt) {
    
    switch logLevel {
    case .trace:
      DDLogVerbose(message(), file: file, line: line)
    case .debug:
      DDLogDebug(message(), file: file, line: line)
    case .info:
      DDLogInfo(message(), file: file, line: line)
    case .warn:
      DDLogWarn(message(), file: file, line: line)
    case .error:
      DDLogError(message(), file: file, line: line)
    default:
      break
    }
  }
}

...

Heap.shared.logChannel = LumberjackLogChannel()