GTM(Google Tag Manager)은 GA(Google Analytics)를 비롯한 여러 모니터링/마케팅 플랫폼들과 연동할 수 있는 중간자 적인 역할을 하는 플랫폼이다. 바로가기: https://developers.google.com/tag-manager/
앱/웹을 재배포 하지 않고도 태그매니저내부의 설정값 변경 만으로 이미 배포되어있는 앱/웹의 설정 또는 조건식 들을 동적으로 변경할 수 있도록 기능을 지원하기때문에 사용자 액션에 따라서 좀더 유연한 마케팅/로깅을 할 수 있다.(ex: 200달러 이상 구매 고객일 경우에만 리마케팅을 수행 등)
GTM의 가장 작은 구성단위부터 점점 큰 순서대로 설명하면 다음과 같다.
앱/웹에 기존에 GA가 적용이 되어있더라도 동시에 적용하는것이 가능하다. 자세한 가이드는 다음 페이지를 참고하면된다.
앱/웹이 처음 로딩될때 GTM에 정의된 컨테이너를 내려받게되고, 해당 컨테이너안에 정의된 변수, 트리거, 태그 등이 모두 로드된다. 따라서 컨테이너를 내려 받은 이후에는 다음번 컨테이너 refresh까지는 GTM쪽과 통신할 필요가 없다. (GTM은 이 컨테이너를 생성하기 위한 관리 인터페이스 정도로 생각하면 된다.)
모바일SDK에서 GTM이 컨테이너의 새 버전으로 refresh 주기는 변경가능하다 (디폴트값은 12시간)
원하는시점에 앱에서 GTM 버전을 수동으로 refresh도 가능하다.
GA을 사용할경우 기존에 특정 화면(viewController or web page) 진입시 GA로 로그를 send하는로직이 들어간다.
// Retrieving a configuration value from a Tag Manager Container.
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
TAGContainer *container = appDelegate.container;
// Get the configuration value by key.
NSString *title = [container stringForKey:@"title_string"];
// MyAppDelegate.m
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Open the container.
id<TAGContainerFuture> future =
[TAGContainerOpener openContainerWithId:@"GTM-XXXX" // Placeholder Container ID.
tagManager:[TAGManager instance]
openType:kTAGOpenTypePreferNonDefault
timeout:nil];
// Method calls that don't need the container.
self.container = [future get];
// Register a function call macro handler using the macro name defined
// in the Google Tag Manager web interface.
[self.container registerFunctionCallMacroHandler:[[MyFunctionCallMacroHandler alloc] init]
forMacro:kMyMacroFunctionName];
}
@end
// MyFunctionCallMacroHandler.h
#import "TAGContainer.h"
// The function name field of the macro, as defined in the Google Tag Manager
// web interface.
extern NSString *const kMyMacroFunctionName;
@interface MyFunctionCallMacroHandler : NSObject<TAGFunctionCallMacroHandler>
@end
// MyFunctionCallMacroHandler.m
#import "MyFunctionCallMacroHandler.h"
// Corresponds to the function name field in the Google Tag Manager interface.
NSString *const kMyMacroFunctionName = @"myConfiguredFunctionName";
@implementation MacroHandler
- (id)valueForMacro:(NSString *)functionName parameters:(NSDictionary *)parameters {
if ([functionName isEqualToString:kMyMacroFunctionName]) {
// Process and return the calculated value of this macro accordingly.
return macro_value;
}
return nil;
}
@end
//
// MyAppDelegate.m
//
#import "MyAppDelegate.h"
#import "MyFunctionCallTagHandler.h"
#import "TAGContainer.h"
#import "TAGContainerOpener.h"
#import "TAGManager.h"
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Open the container.
id<TAGContainerFuture> future =
[TAGContainerOpener openContainerWithId:@"GTM-XXXX" // Placeholder Container ID.
tagManager:[TAGManager instance]
openType:kTAGOpenTypePreferNonDefault
timeout:nil];
// Method calls that don't need the container.
self.container = [future get];
// Register a function call tag handler using the function name of the tag as
// defined in the Google Tag Manager web interface.
[self.container registerFunctionCallTagHandler:[[MyFunctionCallTagHandler alloc] init]
forTag:kMyTagFunctionName];
}
@end
//
// MyFunctionCallTagHandler.h
//
#import "TAGContainer.h"
extern NSString *const kMyTagFunctionName;
@interface MyFunctionCallTagHandler : NSObject<TAGFunctionCallTagHandler>
@end
//
// MyFunctionCallTagHandler.m
//
// Corresponds to the function name field in the Google Tag Manager interface.
NSString *const kMyTagFunctionName = @"myConfiguredFunctionName";
@implementation MyFunctionCallTagHandler
/**
* This method will be called when any custom tag's rule(s) evalute to true and
* should check the functionName and process accordingly.
*
* @param functionName corresponds to the function name field, not tag
* name field, defined in the Google Tag Manager web interface.
* @param parameters An optional map of parameters as defined in the Google
* Tag Manager web interface.
*/
- (void)execute:(NSString *)functionName parameters:(NSDictionary *)parameters {
if ([functionName isEqualToString:kMyTagFunctionName]) {
// Process accordingly.
}
}
@end
미리 정의된 pageCategory, visitorType 값은 현재 페이지내에서 dataLayer.push를 할경우 디폴트로 포함된다.
push 시에 값을 overwrite 하는것도 가능.
dataLayer는 queue로 되어있으며, push 는 async 오퍼레이션.
<body>
<script>
dataLayer = [{
'pageCategory': 'signup',
'visitorType': 'high-value'
}];
</script>
<!-- Google Tag Manager -->
...
<!-- End Google Tag Manager -->
<a href="#" name="button1" onclick="dataLayer.push({'event': 'button1-click'});" >Button 1</a>
dataLayer로 push를 할 경우에는 컨테이너가 먼저 초기화되어 open 상태가 되어있어야 값이 전달된다.
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// The container should have already been opened, otherwise events pushed to
// the data layer will not fire tags in that container.
TAGDataLayer *dataLayer = [TAGManager instance].dataLayer;
[dataLayer push:@{@"event": @"openScreen", @"screenName": @"Home Screen"}];
}
// Rest of the ViewController implementation
@end