Integrations

You can send VWO's campaign information to third-party analytics platforms by using notification listeners. You can then segment the analytics report by using VWO's campaign id, campaign name, variation id, or name.

Next, you will find suggested implementations for some common analytics platforms. Feel free to use these as showcased, or adapt these to meet your specific needs.

Notification Listener

The code can listen to an NSNotification on the key VWOUserStartedTrackingInCampaignNotification.

Here is how notifications can be integrated in AppDelegate.

#import "AppDelegate.h"
@import VWO;

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [VWO launchForAPIKey:@"8116fb11614377a61fb7eb2fa2754660-295084" completion:^{
        NSLog(@"Launch success");
    } failure:^(NSString * _Nonnull error) {
    }];

    [self addVWOObserver];

    return YES;
}

- (void)addVWOObserver {
    [NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        NSDictionary *campaign = note.userInfo;
        NSString *campaignName = campaign[@"vwo_campaign_name"];
        NSString * campaignId = campaign[@"vwo_campaign_id"];
        NSString * variationName = campaign[@"vwo_variation_name"];
        NSString * variationId = campaign[@"vwo_variation_id"];

        NSLog(@"Campaign %@ %@", campaignName, campaignId);
        NSLog(@"Variation %@, %@", variationName, variationId);
    }];
}

@end
import VWO

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        VWO.launch(apiKey: "YOUR-API-KEY", config: nil, completion: {
            // Launch success
        }, failure: nil)

        addVWOObserver()
        return true
    }

    func addVWOObserver() {
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name.VWOUserStartedTrackingInCampaign,
            object: nil, queue: nil) {
                notification in
                if let campaign = notification.userInfo as? [String : String] {
                    let campaignName = campaign["vwo_campaign_name"]!
                    let campaignId = campaign["vwo_campaign_id"]!
                    let variationName = campaign["vwo_variation_name"]!
                    let variationId = campaign["vwo_variation_id"]!
                    print("Campaign \(campaignName) \(campaignId)")
                    print("Variation \(variationName) \(variationId)")
                }
        }
    }
}

📘

Note

Notifications will only be triggered for the first time a user becomes part of the test and is assigned a variation.

Notification Data

On receiving a notification, you can get the campaign data from the notification object which is passed to the callback.

The data contains the following keys:

  • vwo_campaign_id : Identifier of the campaign; this is generated by VWO. This is unique for your account.
  • vwo_campaign_name : Name of the campaign, as set by you. This is not necessarily unique.
  • vwo_variation_id : Identifier of the variation in the campaign of which the user became a part. Variation Id is unique for its campaign, but it is not unique across different campaigns.
  • vwo_variation_name : Name of the variation in the campaign, as set by you. This is not necessarily unique.

Amplitude

Please refer to the Amplitude iOS guide if you are getting started with Amplitude.

In the following suggested approach for Amplitude, we use Events.

We add a notification listener to listen to the notification with the key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Amplitude when a user becomes a part of a campaign. In the event, we are sending the campaign name and id, along with the variation name and id.

Events in Amplitude take an event name and event properties in the form of a dictionary.

If the campaign name is TestSignup and campaign id is 21, we can set the event name as VWO Campaign - TestSignup - 21. We also send event parameters as campaign_name, campaign_id, variation_name, and variation_id.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
   NSDictionary *campaign = note.userInfo;
   NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
   [Amplitude.instance logEvent:event withEventProperties:campaign];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaign = notification.userInfo as? [String : String] {
      let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
       Amplitude.instance().logEvent(event, withEventProperties: campaign)
   }
}

Flurry

Please refer to the Flurry iOS guide if you are getting started with Flurry.

In the following suggested approach for Flurry, we use Custom Events.

We add a notification listener to listen to NSNotification with the key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Flurry when a user becomes part of a campaign. In the event, we are sending the campaign name and id, along with the variation name and id.

Events in Flurry have a two-level structure. The highest level is the specific action, in this case, VWO. The second level in the Events structure is the Event parameter.

If the campaign name is TestSignup and campaign id is 21, we can set the event name as VWO Campaign - TestSignup - 21. We also send event parameters as campaign_name, campaign_id, variation_name, and variation_id.

Per Flurry, prior to logging any events, you must initiate the session with one of the startSession method variants . Any events logged prior to session initialization will not be recorded.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
   NSDictionary *campaign = note.userInfo;
   NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
   [Flurry logEvent:event withParameters:campaign];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaign = notification.userInfo as? [String : String] {
      let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      Flurry.logEvent(event, withParameters: campaign)
   }
}

Google Analytics

Please refer to the Google Analytics iOS guide, if you are getting started with Google Analytics.

In the following approach for Google Analytics, we use Events.

We add a notification listener to listen to NSNotification with the key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Google Analytics when a user becomes a part of a campaign. In the event, we are sending the campaign name and id, along with the variation name and id.

The next step is to build segments for each variation of your campaign. In the segment-builder user interface, look under Advanced and add a new Condition. Filter Users by Event Action and Event Label, enter a name for the segment, and then click Save.

Finally, build a report of metrics you are interested in.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    NSDictionary *campaign = notification.userInfo
    NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
    NSString *action = [NSString stringWithFormat:@"%@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
    NSString *label = [NSString stringWithFormat:@"%@ - %@", campaign[@"vwo_variation_name"], campaign[@"vwo_variation_id"]];
  
    id<GAITracker> tracker = [GAI sharedInstance].defaultTracker;
    [tracker send:[[GAIDictionaryBuilder
                    createEventWithCategory:category
                                     action:action
                                      label:label
                                      value:nil] build]];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaign = notification.userInfo as? [String : String] {
      let category = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      let action = "\(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      let label = "\(campaign["vwo_variation_name"]!) - \(campaign["vwo_variation_id"]!)"

      if let builder = GAIDictionaryBuilder.createEvent(withCategory: category, action: action, label: label, value: nil),
         let tracker = GAI.sharedInstance().defaultTracker {
            tracker.send(builder.build() as! [AnyHashable : Any]!)
         }   
    }
}

Google Custom Dimension

Google also offers Custom Dimensions which enables association of metadata with hits, users, and sessions in Google Analytics.

In the above approach, we only send an event to Google Analytics. You may choose to set the custom dimension. For this, refer to the Custom Dimension and Metrics section in Google Analytics and then set the custom dimension in the notification callback.

The next step is to make changes in Google Analytics. Look for the Admin option in the menu bar, and then select the appropriate account and a property. Under Property, click Custom Definitions > New Custom Dimension. Enter a unique name for the dimension, select User for the scope, and then click Create.

You can now see the reports according to the custom dimension.

Localytics

Please refer to the Localytics iOS guide if you are getting started with Localytics.

In the following suggested approach for Localytics, we use Custom event with attributes.

We add a notification listener to listen to NSNotification with key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Localytics when a user becomes part of a campaign. In the event, we send the campaign name and id, along with the variation name and id.

Localytics also offers a way to set user attributes. You can set user attributes for VWO's campaign data as well.

The custom event in Localytics has an event name and attributes.
If the campaign name is TestSignup and campaign id is 21, we can set the event name as VWO Campaign - TestSignup - 21. We also send event parameters as campaign_name, campaign_id, variation_name, and variation_id.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
   NSDictionary *campaign = note.userInfo;
   NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
   [Localytics tagEvent:event attributes:campaign];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaign = notification.userInfo as? [String : String] {
      let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      Localytics.tagEvent(event, attributes: campaign)
   }
}

Mixpanel

Please refer to the Mixpanel iOS guide if you are getting started with Mixpanel.

In the following suggested approach for Mixpanel, we use Events. Mixpanel also offers a way to set super properties and user profiles.

We add a notification listener to listen to NSNotification with key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Mixpanel when a user becomes part of a campaign. In the event, we send the campaign name and id, along with the variation name and id.

If you need to use super properties or people properties, modify the following code and send appropriate values to Mixpanel.

The next step is to look for VWO events in your Mixpanel account. You can look at the funnels with the VWO event or look at the segment data.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
   NSDictionary *campaign = note.userInfo;
   NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
   [Mixpanel.sharedInstance track:event properties:campaign];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaign = notification.userInfo as? [String : String] {
      let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      Mixpanel.mainInstance().track(event: event, properties: campaign)
   }
}

Segment

Please refer to the Segment iOS guide if you are getting started with Segment.

Segment has a spec for A/B testing events.

We add a notification listener to listen to NSNotification with the key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to Segment when a user becomes part of a campaign. In the event, we are sending the campaign name and id, along with the variation name and id.

If the campaign name is TestSignup and campaign id is 21, we can set the event name as Experiment Viewed. We also send event parameters as experimentId, experimentName, variationId, and variationName.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
   NSDictionary *campaign = note.userInfo;
   NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];
   NSDictionary *properties = @{
       @"experimentId"   : campaign[@"vwo_campaign_id"],
       @"experimentName" : campaign[@"vwo_campaign_name"],
       @"variationId"    : campaign[@"vwo_variation_id"],
       @"variationName"  : campaign[@"vwo_variation_name"]
    };
    [SEGAnalytics.sharedAnalytics track:event properties:properties];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in
   if let campaignDict = notification.userInfo as? [String : String] {
      let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)"
      let properties = [
         "experimentId"   : campaign["vwo_campaign_id"]!,
         "experimentName" : campaign["vwo_campaign_name"]!,
         "variationId"    : campaign["vwo_variation_id"]!,
         "variationName"  : campaign["vwo_variation_name"]!
      ]
      SEGAnalytics.shared().track(event, properties: properties)
   }
}

MoEngage

Please refer to the MoEngage guide if you are getting started with moengage.

In the following suggested approach for MoEngage, we use Events.

We add a notification listener to listen to NSNotification with the key VWOUserStartedTrackingInCampaignNotification. When the callback is requested, we send an event to MoEngage when a user becomes part of a campaign. In the event, we are sending the campaign name and id, along with the variation name and id.

Events in MoEngage take an event name and event properties in the form of a dictionary.

[NSNotificationCenter.defaultCenter addObserverForName:VWOUserStartedTrackingInCampaignNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
     NSDictionary *campaign = note.userInfo;
     NSString *event = [NSString stringWithFormat:@"VWO Campaign - %@ - %@", campaign[@"vwo_campaign_name"], campaign[@"vwo_campaign_id"]];

     MoEngageProperties* eventProperties = [[MoEngageProperties alloc] initWithAttributes:campaign];
     [eventProperties addAttribute:campaign[@"vwo_campaign_id"] withName:@"experimentId"];     
     [eventProperties addAttribute:campaign[@"vwo_campaign_name"] withName:@"experimentName"];
     [eventProperties addAttribute:campaign[@"vwo_variation_id"] withName:@"variationId"];
     [eventProperties addAttribute:campaign[@"vwo_variation_name"] withName:@"variationName"];

     [[MoEngageSDKAnalytics sharedInstance] trackEvent:event withProperties:eventProperties];
}];
NotificationCenter.default.addObserver(forName: NSNotification.Name.VWOUserStartedTrackingInCampaign, object: nil, queue: nil) { (notification) in 

    if let campaign = notification.userInfo as? [String : String] {
        let event = "VWO Campaign - \(campaign["vwo_campaign_name"]!) - \(campaign["vwo_campaign_id"]!)" 
          
      			 let eventProperties = MoEngageProperties(withAttributes:campaign)
             eventProperties.addAttribute(campaign["vwo_campaign_id"], withName: "experimentId")
             eventProperties.addAttribute(campaign["vwo_campaign_name"], withName: "experimentName")
             eventProperties.addAttribute(campaign["vwo_variation_id"], withName: "variationId")
             eventProperties.addAttribute(campaign["vwo_variation_name"], withName: "variationName")

      MoEngageSDKAnalytics.sharedInstance.trackEvent(event, withProperties: eventProperties)
    }
}