Customer instrumentation involves many events, including error, exception, location and custom events. Each event type has a method for instrumenting the SDK.

Error Exception KillSwitch Geolocation GPS location Custom


Returns the shared instance of TLFCustomEvent. You should use this instance when logging custom events.

+ (TLFCustomEvent *)sharedInstance

Returns a shared instance of TLFCustomEvent.

Declared in TLFCustomEvent.h.

Error events

Logs an error as described in an NSError instance.


Logs an error as described in an NSError instance.

– (BOOL)logNSErrorEvent:(NSError *)error message:(NSString *)message [file:(const] char *)file line:(unsigned int)line level:(kTLFMonitoringLevelType)level

– (BOOL)logNSErrorEvent:(NSError *)error message:(NSString *)message level:(kTLFMonitoringLevelType)level

Parameter Description
The NSError returned by the SDK or your own method.
An associated message for your own.
The original file where the error occurred. The source code file name, usually from the FILE preprocessor macro (optional).
The source code line number, usually from the LINE preprocessor macro (optional).
The monitoring level of the event. The minimum logging level at which this error is logged.
Whether the event was successfully logged or not.

Declared in TLFCustomEvent.h. kTLFMonitoringLevelType is declared in TLFPublicDefinitions.h.

This example shows the expected JSON:

{          "exception":{
                "unhandled": false,            
                   "message":"Custom Message"           
                "name": "(null)",            
                "description": "An Error Occured,"          
               "count": 4,          
               "offset": 39,          

Exception events

Use this method to log exceptions.


Requests that the framework logs an exception trapped by your own exception handler. These methods do not use the Cocoa SDK, which is not exception-safe. Sets the Unhandled flag to false.

This example shows how to call the method:

- (BOOL)logNSExceptionEvent:(NSException *)exception;
- (BOOL)logNSExceptionEvent:(NSException *)exception dataDictionary:(NSDictionary*)dataDictionary;
- (BOOL)logNSExceptionEvent:(NSException *)exception dataDictionary:(NSDictionary*)dataDictionary isUnhandled:(BOOL)unhandled;
Parameter Description
The caught NSexception instance.
This value is whether the event was successfully logged. Values are true or false.
This value is additional data about the exception.
Indicates whether the exception was caught by an exception handler.

Logging exceptions in Swift

NSException codes are not supported for logging exceptions in Swift. Use the following code snippet to log exceptions in Swift.

enum MyError : ErrorType {
  case RuntimeError(String)
  case OutofIndex(String)

func throwError(message: String) throws {
  throw MyError.RuntimeError(message)

func throwException(message: String) throws {
  let info:[Int:String] = [1:"any"]
  let exceptionInfo:[String:NSException] = ["ExceptionObject":NSException(name:
      "TheException", reason: "WantToThrowNSException", userInfo: info)];
  throw NSError(domain: "exception", code: 10, userInfo:exceptionInfo)

@IBAction func generateUnhandledException(sender: UIButton) {

  /* catching NSError with embedded NSException */
do {
  try throwException("exceptionexception")
}catch let err as NSError  {
  let ex = err.userInfo["ExceptionObject"] as! NSException
  TLFCustomEvent.sharedInstance().logNSExceptionEvent(ex, dataDictionary: info, isUnhandled:
  TLFCustomEvent.sharedInstance().logNSErrorEvent(err, message: "error", level:
  }catch let ex as NSException {
  TLFCustomEvent.sharedInstance().logNSExceptionEvent(ex, dataDictionary: info, isUnhandled:

Kill Switch events

– (BOOL)setDeviceId:(NSString*)value;

This sets the Device ID.

[[TLFApplicationHelper sharedInstance] setDeviceId:@"CustomID"];
Parameter Description
The string that represents the new Device ID.
Indicates whether the Device ID was set.

– (NSString*)getDeviceId;

This returns a string representation of the Device ID.

[[TLFApplicationHelper sharedInstance] getDeviceId];
Parameter Descripiton
A string representation of the Device ID.


Use this method to have the framework log a geographic location at a specific point in your application.

Requests that the framework logs a geographic location. This is an example of how to use this API:

     CLLocationDegrees myLatitude= 37.7888024;    
     CLLocationDegrees myLongitude= -122.40031809;    
     CLLocation *myLocation=[[CLLocation alloc] initWithLatitude:myLatitude longitude:myLongitude]; 
     [[TLFCustomEvent sharedInstance] logLocation:myLocation];  
Parameter Description
A CLLocation Object containing a location of interest.

GPS location events

To avoid making unnecessary location updates, and to protect the privacy of your application's users by ensuring that location is reported only when the application has some other reason to request it, location events are not logged automatically. To log location updates, you use logLocationUpdateEventWithLatitude.


This method is meant to be called inside your handler for locationManager:didUpdateToLocation:fromLocation:. Your application must include the Core Location framework (CoreLocation.framework).

#import "CoreLocation/CoreLocation.h"
#import "TLFCustomEvent.h"


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:
(CLLocation *)
newLocation fromLocation:(CLLocation *)oldLocation {
    CLLocationCoordinate2D c = newLocation.coordinate;
    [[TLFCustomEvent sharedInstance] logLocationUpdateEventWithLatitude:c.latitude 
- (void)logLocationUpdateEventWithLatitude:(double)latitude longitude:(double)
longitude level:(kTLFMonitoringLevelType)level
Parameter Description
The latitude to log.
The longitude to log.
The minimum logging level for locations.

Declared in TLFCustomEvent.h. kTLFMonitoringLevelType is declared in TLFPublicDefinitions.h.

Custom events

You can log a specified event with or without also logging an associated value or dictionary.


Logs a named event and associated dictionary. The dictionary is converted to its JSON representation.

Note: To be convertible to a JSON representation, the values of the dictionary must be NSDictionary, NSArray, NSString, NSNumber or NSNull objects.

– (void)logEvent:(NSString *)eventName values:(NSDictionary *)values

– (void)logEvent:(NSString *)eventName values:(NSDictionary *)values level:(kTLFMonitoringLevelType)level

Parameter Description
The name of the event. Must not contain equal signs or square brackets.
More data items that are associated with the event.
The minimum logging level for this event logged (optional, default is 1).

Declared in TLFCustomEvent.h. kTLFMonitoringLevelType is declared in TLFPublicDefinitions.h.

Log screen layout for iOS mobile app session replay

You can replay a mobile app session in cxImpact Browser Based Replay as you would an HTML web session instead of viewing the mobile app session as a series of screen captures.

The screen layouts of the native mobile app sessions are captured in Acoustic Experience Analytics (Tealeaf) JSON format. The screen layouts are then sent back to replay server. The replay server uses a template engine, which interprets the JSON into HTML format. You can then replay the screen lay out from the native mobile app session as HTML pages in cxImpact Browser Based Replay.

There are several advantages to using JSON data to replay mobile app session over screen captures.

  • Reduce bandwidth. Screen captures for each screenview generate relatively large image data. It not only consumes large amounts of wireless and cellular bandwidth, but it also consumes more memory inside the device. It also impacts the app performance.
  • Mask sensitive information. You cannot mask sensitive information in a screen capture. When using JSON data to replay mobile app sessions, you can mask EditTexts by adding View IDs to the MaskIdList attribute in
  • Draw user interactions (UI events) onto the HTML pages that are created from the JSON data.

Replay logging can be automatic, manual, or a combination of the two. To enable automatic layout logging find LogViewLayoutOnScreenTransition in TealeafBasicConfig and set it to YES. This will automatically log a view controller when the view controller's viewDidAppear:(BOOL)animated method is called.

Note: If the viewController overrode the viewDidAppear, method[super viewDidAppear:animated] must be called.


	[super viewDidAppear:animated];
	// Custom code

	// Custom code

Several methods are included for manual logging of screen layout.

The following is the most basic manual logging method. The following method logs the layout of the viewController passed into it.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController

The following method performs the same action as the first method, but you can pass in a specific name for the screen layout that is logged. This is helpful when you log a view controller that can perform several different functions.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController 
andName:(NSString *)name

The following method performs the same action as the first method, but after the specified delay. This is helpful for logging after certain events, such as reloading the data in a table. The delay is measured in seconds.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController	

The following method performs the same function as the previous method, but it allows you to pass in a name for the layout.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController	
       andDelay:(CGFloat)delay andName:(NSString *)name

In addition to logging the main view controller passed in, this method allows you to pass in an array of other views to be logged at the same time. This is useful in instances where there are elements on screen that are not part of the same view hierarchy, such as an overlay attached directly to the application's window or an alert view.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController 

The following method performs the same action as the previous method, but it allows you to pass in a name for the layout.

-(BOOL)logScreenLayoutWithViewController:(UIViewController *)viewController 
andRelatedViews:(NSArray*)views andName:(NSString *)name

Where and when to call manual logging

With automatic logging enabled, view controllers are logged during the viewDidAppear stage of the view lifecycle. If the view that is logged is loading remote data, this is not adequate. In this case, the ideal time to call the logging method is when the remote data is done loading and displaying.

- (void)RESTRequestCompleted:(RESTRequest *)request responseData:
(NSDictionary *)responseData response:(NSHTTPURLResponse *)response
    	  [self updateUI: [responseData objectForKey:[self productKeyKey]]];
   	    [self hideActivityIndicator];
	      [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:self];

In some cases, you need to delay triggering logging to give time for UI animations to complete or a UITableView reloadData call to complete. The Custom Event provides a method to accomplish this.

- (void)RESTRequestCompleted:(RESTRequest *)request responseData:(NSDictionary 
*)responseData response:(NSHTTPURLResponse *)response
   items = [responseData objectForKey:[self itemsKey]];
   [self.itemsTable reloadData];
   [self hideActivityIndicator];
	       [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:self 

After certain UIEvents, it may be beneficial to trigger logging, such as upon selection of an item on table view that stretches beyond one screen.

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:
(NSIndexPath *)indexPath
	     [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:self];
	     return indexPath;

A manual logging call is required to capture an alert view.

- (IBAction)btnSubmitFormClick:(id)sender {
	      UIAlertView *alert=[[UIAlertView alloc] initWithTitle:
@"Thank You!" message:@"We will be in touch with you soon." 
delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
	      [alert show];
	      [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:
self andRelatedViews:@[alert]];

You should also log the screen layout after the alert dialog is dismissed.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:
	      [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:self];

Acoustic Experience Analytics (Tealeaf) screen layout logging only logs the views and controls that are on screen when the logging call is made. When UITableView contains more rows than can be view on a screen at once, call the screen layout logging when an item is selected. This ensures that the event matches the row selected. Use the following code in your UITableViewDelegate to make this change.

- (NSIndexPath *)tableView:(UITableView *)tableView 
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    [[TLFCustomEvent sharedInstance] logScreenLayoutWithViewController:self];
    return indexPath; 

Disabling auto-instrumentation to include advanced custom instrumentation

By default, the iOS SDK automatically instruments your application by using a template of selected items that are based on the configured logging level. For more information, see Logging templates.

As needed, you can configure the iOS SDK for custom instrumentation. A predefined set of events and objects are instrumented in the application, and the rest can be instrumented through custom methods.

Note: Before you begin, complete the initial configuration tasks that are associated with instrumentation.