Listen to recorded events

Prev Next

Event Listener lets your app observe every event the Insider SDK records on the device. You can forward these events to your own analytics tool, such as Google Analytics 4 (Firebase), Mixpanel, or Amplitude.

The listener receives custom events, default events, and campaign events (e.g., push_session and inapp_seen). Each event arrives with its parameters and the time it was recorded.

This method is available on iOS SDK 16.1.0 or higher. For release details, see iOS SDK Changelog.

Before you start

Check the following before you add a listener:

  • You can register the listener before or after you initialize the SDK. A listener registered before initialization stays registered and starts receiving events once the SDK starts a session.

  • Events tagged before a session starts are delivered when the session starts.

  • The user has not opted out of data collection. Nothing is delivered while the user has opted out. For details, see Set GDPR consent.

Add an event listener

Create a class that conforms to the InsiderEventListener protocol and register it through Insider.events(). The SDK calls onEventRecorded once for every event it records.

The following table shows the parameters that the listener receives.

Parameter

Data Type

Description

name

String

The event name, e.g., product_detail_page_view.

parameters

Dictionary

The event parameters. Empty when the event has no parameters.

timestamp

NSTimeInterval

The time the event was recorded, in whole seconds since 1970. It is the same value the SDK sends to Insider One for this event.

Method signatures

+ (nonnull InsiderEvents *)events;

// InsiderEvents
- (void)addObserver:(id<InsiderEventListener>)observer;

// InsiderEventListener
- (void)onEventRecorded:(NSString *)name
             parameters:(NSDictionary<NSString *, id> *)parameters
              timestamp:(NSTimeInterval)timestamp;
class func events() -> InsiderEvents

// InsiderEvents
func addObserver(_ observer: InsiderEventListener)

// InsiderEventListener
func onEventRecorded(_ name: String, parameters: [String : Any], timestamp: TimeInterval)

Method examples

A shared instance that lives for the whole app session is the simplest way to keep a strong reference to your listener.

#import <InsiderMobile/InsiderMobile.h>

@interface AnalyticsForwarder : NSObject <InsiderEventListener>
+ (instancetype)shared;
@end

@implementation AnalyticsForwarder

+ (instancetype)shared {
    static AnalyticsForwarder *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{ instance = [[AnalyticsForwarder alloc] init]; });
    return instance;
}

- (void)onEventRecorded:(NSString *)name
             parameters:(NSDictionary<NSString *, id> *)parameters
              timestamp:(NSTimeInterval)timestamp {
    // Forward the event to your analytics tool.
    NSLog(@"Insider event: %@ %@ %f", name, parameters, timestamp);
}

@end

// AppDelegate.m, didFinishLaunchingWithOptions
[[Insider events] addObserver:[AnalyticsForwarder shared]];
import InsiderMobile

final class AnalyticsForwarder: NSObject, InsiderEventListener {
    static let shared = AnalyticsForwarder()

    func onEventRecorded(_ name: String, parameters: [String : Any], timestamp: TimeInterval) {
        // Forward the event to your analytics tool.
        print("Insider event: \(name) \(parameters) \(timestamp)")
    }
}

// AppDelegate.swift, didFinishLaunchingWithOptions
Insider.events().addObserver(AnalyticsForwarder.shared)

The SDK holds listeners with a weak reference, so keep a strong reference to your listener for as long as you want to receive events.

Remove an event listener

Call removeObserver to stop receiving events. Only the listener you pass is removed; other listeners keep receiving events.

Method signatures

- (void)removeObserver:(id<InsiderEventListener>)observer;
func removeObserver(_ observer: InsiderEventListener)

Method examples

[[Insider events] removeObserver:[AnalyticsForwarder shared]];
Insider.events().removeObserver(AnalyticsForwarder.shared)

Event details

Which events are delivered

The listener receives every event the SDK records. The following events are delivered:

  • Custom events and default events.

  • Campaign events, such as inapp_seen and push_session.

  • session_start.

  • Events you create by calling the tag event methods from inside the callback. This is safe and does not cause recursion.

The following events are not delivered:

  • Events recorded while the SDK is disabled or the user has opted out of data collection.

  • Events dropped by the per-session event limit.

  • flush_event, the SDK heartbeat event.

  • Event names that Insider One excludes from listener delivery for your app.

Event timestamps

timestamp is in seconds since 1970, not milliseconds. Multiply it by 1000 to get milliseconds.

Date values in parameters

Date parameters arrive as formatted date strings, not as NSDate objects.

Threading, ordering, and error handling

  • The listener is called on an internal background queue, not on the main queue. Dispatch to the main queue yourself if you update the UI.

  • All listeners are called from the same queue, in the order the SDK recorded the events. A slow listener delays the listeners after it and the events that follow, so move expensive work to your own queue and return quickly.

  • Adding the same listener twice keeps a single registration. The listener is called once per event.

The SDK does not catch exceptions thrown by your listener. An exception that escapes onEventRecorded terminates the app, so handle errors (casts, force unwraps, parsing) inside the method.

Forward events to your analytics tool

The following example forwards selected events and converts the timestamp to milliseconds, which most analytics tools expect.

final class AnalyticsForwarder: NSObject, InsiderEventListener {
    static let shared = AnalyticsForwarder()

    private let forwardedEvents: Set<String> = ["purchase", "item_added_to_cart", "product_detail_page_view"]

    func onEventRecorded(_ name: String, parameters: [String : Any], timestamp: TimeInterval) {
        guard forwardedEvents.contains(name) else { return }

        let recordedAtMillis = Int64(timestamp * 1000)
        DispatchQueue.global(qos: .utility).async {
            // Send name, parameters, and recordedAtMillis to your analytics tool.
        }
    }
}

Forward only the event names you need. GA4 allows up to 500 distinct event names per user, so forwarding every Insider event can push your own events over that limit.

Event parameters may contain user data. You are responsible for what you send to third-party tools. Forward an allow-list of events and parameters, as in the example above.

Limits

  • Events dropped by the per-session event limit are never delivered, so the stream you forward matches what Insider One records.

  • Priority events such as inapp_seen, push_session, and confirmation_page_view bypass the limit and are always delivered.

  • Events you create from inside the callback are delivered to every listener, and they count toward the per-session event limit.

  • Insider One can exclude specific event names from listener delivery for your app. flush_event is never delivered.