Q:

Passing UTM parameters using Google Tag Manager on iOS

I am trying to pass the UTM campaign parameter (which i have locally in the app from a different source) to Google Tag Manager along with the transaction event to be able to associate transactions to campaigns. I use the data layer to send the data: [self.tagManager.dataLayer push:combinedParameters] the event is set to transaction in the combinedParameters.
The transaction data is being tracked correctly but there is no associated campaign data like utm_source, utm_medium etc. visible in the Analytics website. I am passing all of them in combinedParameters. I also tried sending it through [self.tagManager.dataLayer pushValue:val forKey:key]; using utm_source etc as keys and also using kGAICampaignContent.
None of which actually worked. There is no documentation (atleast i could find) which helps in understanding how to pass UTM data through GTM. The only available one is the Google Analytics one which does not work in this case.
Any help would be really appreciated.

A:

It's easier to wrap your head around if you just consider the SDK to be a hit builder for Measurement Protocol.
In GTM, you can add MP fields to a tag using the settings found under More Settings > Fields to set. To set the three required campaign parameters (source, medium, name), you would add the following fields:
Field name: &cm
Value: some-campaign-medium
Field name: &cs
Value: some-campaign-source
Field name: &cn
Value: some-campaign-name
To set the dynamic values for "some-campaign-*", you can use Data Layer Variables to pull the parsed URL parameter values into GTM's data model.
So, to parse a URL that's coming in, you could leverage the dataLayer as well as the GAIDictionaryBuilder interface of the GA SDK.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

  NSString *urlString = [url absoluteString];

  GAIDictionaryBuilder *hitParams = [[GAIDictionaryBuilder alloc] init];
  [hitParams setCampaignParametersFromUrl:urlString];

  TAGDataLayer *dataLayer = [TAGManager instance].dataLayer;

  if([hitParams get:kGAICampaignSource] && [hitParams get:kGAICampaignMedium] && [hitParams get:kGAICampaignName]) {
    [dataLayer push:@{
      @"event": @"screenView", 
      @"screenName": @"Home Screen", 
      @"customCampaignSource": [hitParams get:kGAICampaignSource], 
      @"customCampaignMedium": [hitParams get:kGAICampaignMedium], 
      @"customCampaignName": [hitParams get:kGAICampaignName]
    }];
  }
  return YES;
}

After that, you'd create three Data Layer Variables, one for customCampaignSource, one for customCampaignName, and one for customCampaignMedium. Add those to the &cs, &cn, and &cm fields, respectively, and your Tags should collect dynamic campaign data.

