Google Tag Manager for iOS

Initializing the SDK

Braze’s iOS SDK can be initialized and controlled by tags configured within Google Tag Manager.

But first - before using Google Tag Manager - be sure to first follow our Initial SDK Setup.

Configuring Your Google Tag Manager

In our example, we’ll pretend we are a music streaming app that wants to log different events as users listen to songs. Using Google Tag Manager for iOS, we can control which of our 3rd party vendors receive this event, and create tags specific to Braze.

Custom Events

Custom events are logged with actionType set to logEvent. The Braze custom tag provider in our example is expecting the custom event name to be set using eventName.

To get started, create a trigger that looks for an “Event Name” that equals played song

Event Name Trigger for events

Next, create a new Tag (“Function Call”) and enter the Class Path of your custom tag provider described later in this article.

This tag will be triggered when you log the played song event we just created.

In our example tag’s custom parameters (key-value pairs), we’ve set eventName to played song - which will be the custom event name logged to Braze.

Function Call Tag

You can also include additional key-value pair arguments to the tag, which will be sent as custom event properties to Braze. eventName and actionType will not be ignored for custom event properties. In our example tag below, we’ll pass in genre which was defined using a tag Variable in Google Tag Manager - sourced from the custom event we logged in our app.

The genre event property is sent to Google Tag Manager a “Firebase - Event Parameter” variable since Google Tag Manager for iOS uses Firebase as the data layer.

Tag Variable Event Name

Lastly, when a user plays a song in our app, we will log an event through Firebase/Google Tag Manager using the Firebase Analytics event name that matches our tag’s trigger name, played song.

1
2
3
NSDictionary *parameters = @{@"genre" : @"pop",
                             @"number of times listened" : @42};
[FIRAnalytics logEventWithName:@"played song" parameters:parameters];

Logging Custom Attributes

Custom attributes are set via an actionType set to customAttribute. The Braze custom tag provider is expecting the custom attribute key/value to be set via customAttributeKey and customAttributeValue.

1
2
3
NSDictionary *parameters = @{@"customAttributeKey" : @"favorite song",
                             @"customAttributeValue" : @"Private Eyes"};
[FIRAnalytics logEventWithName:@"customAttribute" parameters:parameters];

Calling ChangeUser

Calls to changeUser() are made via an actionType set to changeUser. The Braze custom tag provider is expecting the Braze user ID to be set via an externalUserId key-value pair within your tag.

1
2
NSDictionary *parameters = @{@"externalUserId" : userId};
[FIRAnalytics logEventWithName:@"changeUser" parameters:parameters];

Braze SDK Custom Tag Provider

With the tags and triggers set up, you will also need to implement Google Tag Manager in your iOS app which can be found in Google’s documentation.

Once Google Tag Manager is installed in your app, add a custom tag provider to call Braze SDK methods based on the tags you’ve configured within Google Tag Manager.

Be sure to note the “Class Path” to the file which - this is what you’ll enter when setting up a Tag in the Google Tag Manager console.

This example shows one of many ways to structure your custom tag provider, where we determine which Braze SDK method to call based on the actionType key-value pair sent down from the GTM Tag.

The actionType we’ve supported in our example are logEvent, customAttribute, and changeUser, but you may prefer to change how your tag provider handles data from Google Tag Manager.

Add the following code to your BrazeGTMTagManager.h file:

1
2
3
4
5
6
@import Firebase;
@import GoogleTagManager;

@interface BrazeGTMTagManager : NSObject <TAGCustomFunction>

@end

And add the following code to your BrazeGTMTagManager.m file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#import <Foundation/Foundation.h>
#import "BrazeGTMTagManager.h"
#import "Appboy-iOS-SDK/AppboyKit.h"

static NSString *const ActionTypeKey = @"actionType";

// Custom Events
static NSString *const LogEventActionType = @"logEvent";
static NSString *const LogEventEventName = @"eventName";

// Custom Attributes
static NSString *const CustomAttributeActionType = @"customAttribute";
static NSString *const CustomAttributeKey = @"customAttributeKey";
static NSString *const CustomAttributeValueKey = @"customAttributeValue";

// Change User
static NSString *const ChangeUserActionType = @"changeUser";
static NSString *const ChangeUserExternalUserId = @"externalUserId";

@implementation BrazeGTMTagManager

- (NSObject *)executeWithParameters:(NSDictionary *)parameters {
  NSMutableDictionary *mutableParameters = [parameters mutableCopy];
  
  NSString *actionType = mutableParameters[ActionTypeKey];
  if (!actionType) {
    NSLog(@"There is no Braze action type key in this call. Doing nothing.", nil);
    return nil;
  }
  
  [mutableParameters removeObjectForKey:ActionTypeKey];
  
  if ([actionType isEqualToString:LogEventActionType]) {
    [self logEvent:mutableParameters];
  } else if ([actionType isEqualToString:CustomAttributeActionType]) {
    [self logCustomAttribute:mutableParameters];
  } else if ([actionType isEqualToString:ChangeUserActionType]) {
    [self changeUser:mutableParameters];
  } else {
    NSLog(@"Invalid action type. Doing nothing.");
  }
  return nil;
}

- (void)logEvent:(NSMutableDictionary *)parameters {
  NSString *eventName = parameters[LogEventEventName];
  [parameters removeObjectForKey:LogEventEventName];
  [[Appboy sharedInstance] logCustomEvent:eventName withProperties:parameters];
}

- (void)logCustomAttribute:(NSMutableDictionary *)parameters {
  NSString *customAttributeKey = parameters[CustomAttributeKey];
  id customAttributeValue = parameters[CustomAttributeValueKey];
  
  if ([customAttributeValue isKindOfClass:[NSString class]]) {
    [[Appboy sharedInstance].user setCustomAttributeWithKey:customAttributeKey
                                             andStringValue:customAttributeValue];
  } else if ([customAttributeValue isKindOfClass:[NSDate class]]) {
    [[Appboy sharedInstance].user setCustomAttributeWithKey:customAttributeKey
                                               andDateValue:customAttributeValue];
  } else if ([customAttributeValue isKindOfClass:[NSNumber class]]) {
    if (strcmp([customAttributeValue objCType], [@(YES) objCType]) == 0) {
      [[Appboy sharedInstance].user setCustomAttributeWithKey:customAttributeKey
                                                 andBOOLValue:[(NSNumber *)customAttributeValue boolValue]];
    } else if (strcmp([customAttributeValue objCType], @encode(short)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(int)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(long)) == 0) {
      [[Appboy sharedInstance].user setCustomAttributeWithKey:customAttributeKey
                                              andIntegerValue:[(NSNumber *)customAttributeValue integerValue]];
    } else if (strcmp([customAttributeValue objCType], @encode(float)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(double)) == 0) {
      [[Appboy sharedInstance].user setCustomAttributeWithKey:customAttributeKey
                                               andDoubleValue:[(NSNumber *)customAttributeValue doubleValue]];
    } else {
      NSLog(@"Could not map NSNumber value to Appboy custom attribute:%@", customAttributeValue);
    }
  } else if ([customAttributeValue isKindOfClass:[NSArray class]]) {
    [[Appboy sharedInstance].user setCustomAttributeArrayWithKey:customAttributeKey
                                                           array:customAttributeValue];
  }
}

- (void)changeUser:(NSMutableDictionary *)parameters {
  NSString *userId = parameters[ChangeUserExternalUserId];
  [[Appboy sharedInstance] changeUser:userId];
}

@end
WAS THIS PAGE HELPFUL?
New Stuff!