本开发者指南将介绍如何在 Google 跟踪代码管理器中 。
简介
借助 Google 跟踪代码管理器,开发者可以更改配置 通过 Google 跟踪代码管理器在移动应用中植入 而无需重新生成应用二进制文件并将其重新提交给应用 市场。
这对于管理任何配置值非常有用 或标志(将来可能需要更改的标志), 包括:
- 各种界面设置和显示字符串
- 应用中投放的广告的尺寸、位置或类型
- 游戏设置
也可以在运行时使用规则评估配置值 启用动态配置,例如:
- 根据屏幕尺寸确定横幅广告尺寸
- 使用语言和位置配置界面元素
Google 跟踪代码管理器还支持动态实现跟踪代码 和像素。开发者可以将重要事件推送到数据中, 层,并决定应触发哪些跟踪代码或像素。 跟踪代码管理器目前支持以下代码:
- Google移动应用分析
- 自定义函数调用代码
准备工作
在使用本入门指南之前,您需要做好以下准备:
- 一个 Google 跟踪代码管理器账号
- 新的跟踪代码管理器 容器和值收集宏
- iOS 版移动应用,其中实现 Google 跟踪代码管理器
- Google Analytics 服务 SDK,其中包含跟踪代码管理器库。
如果您刚开始接触 Google 跟踪代码管理器,我们建议您 请先详细了解容器、宏和规则(帮助中心),然后再继续本指南。
使用入门
本部分将指导开发者完成典型的跟踪代码管理器工作流程:
1. 将 Google 跟踪代码管理器 SDK 添加到您的项目中
在使用 Google 跟踪代码管理器 SDK 之前,您需要将
libGoogleAnalyticsServices.a
以及 Library
中的 Google 跟踪代码管理器 (GTM) 头文件
目录中。
接下来,将以下内容添加到应用目标的关联库中(如果它们 :
CoreData.framework
SystemConfiguration.framework
libz.dylib
libsqlite3.dylib
libGoogleAnalyticsServices.a
如果您希望应用访问 广告客户 (IDFA) 和跟踪标记, Google 跟踪代码管理器 SDK 宏,那么您还需要关联下面这些额外的库:
libAdIdAccess.a
AdSupport.framework
2. 将默认容器文件添加到项目中
Google 跟踪代码管理器会在您的应用首次运行时使用默认容器。默认 系统将使用容器,直到应用能够通过容器检索到 。
如需下载默认容器二进制文件并将其添加到您的应用,请按以下步骤操作:
- 登录 Google 跟踪代码管理器网页界面。
- 选择您要下载的容器的版本。
- 点击下载按钮,获取容器二进制文件。
- 将二进制文件添加到 项目的根目录下的“Supporting Files”文件夹中的文件
默认文件名应为容器 ID(例如 GTM-1234
)。安装
下载了二进制文件,请务必从文件名中移除版本后缀
以确保遵循正确的命名惯例。
虽然我们建议使用二进制文件,但如果您的容器不包含规则或代码,
则可以选择使用简单的
属性列表或 JSON
文件。
该文件应位于主 bundle 中,且应跟随路径
命名惯例:<Container_ID>.<plist|json>
。
例如,如果您的容器 ID 为 GTM-1234
,则可以指定
并将默认容器值存储在名为
GTM-1234.plist
。
3. 打开容器
在从容器中检索值之前,您的应用需要打开 容器。打开容器将从磁盘加载该容器(如果有),或者 将向网络请求该标识符(如果需要)。
要在 iOS 上打开容器,最简单的方法是使用
openContainerWithId:tagManager:openType:timeout:notifier:
,如以下示例所示:
// MyAppDelegate.h
// This example assumes this file is using ARC.
#import <UIKit/UIKit.h>
@class TAGManager;
@class TAGContainer;
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) TAGManager *tagManager;
@property (nonatomic, strong) TAGContainer *container;
@end
// MyAppDelegate.m
// This example assumes this file is using ARC.
#import "MyAppDelegate.h"
#import "TAGContainer.h"
#import "TAGContainerOpener.h"
#import "TAGManager.h"
@interface MyAppDelegate ()<TAGContainerOpenerNotifier>
@end
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.tagManager = [TAGManager instance];
// Optional: Change the LogLevel to Verbose to enable logging at VERBOSE and higher levels.
[self.tagManager.logger setLogLevel:kTAGLoggerLogLevelVerbose];
/*
* Opens a container.
*
* @param containerId The ID of the container to load.
* @param tagManager The TAGManager instance for getting the container.
* @param openType The choice of how to open the container.
* @param timeout The timeout period (default is 2.0 seconds).
* @param notifier The notifier to inform on container load events.
*/
[TAGContainerOpener openContainerWithId:@"GTM-XXXX" // Update with your Container ID.
tagManager:self.tagManager
openType:kTAGOpenTypePreferFresh
timeout:nil
notifier:self];
// Method calls that don't need the container.
return YES;
}
// TAGContainerOpenerNotifier callback.
- (void)containerAvailable:(TAGContainer *)container {
// Note that containerAvailable may be called on any thread, so you may need to dispatch back to
// your main thread.
dispatch_async(dispatch_get_main_queue(), ^{
self.container = container;
});
}
// The rest of your app delegate implementation.
4. 从容器中获取配置值
容器打开后,可以使用
该
<type>ForKey:
方法:
// 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"];
使用不存在的键发出的请求将返回相应的默认值 更改为请求的类型:
// Empty keys will return a default value depending on the type requested.
// Key does not exist. An empty string is returned.
NSString subtitle = [container stringForKey:@"Non-existent-key"];
[subtitle isEqualToString:@""]; // Evaluates to true.
5. 将值推送到 DataLayer
DataLayer 是一个地图,可启用有关应用的运行时信息,例如触摸 事件或屏幕浏览事件,以提供给跟踪代码管理器宏和代码, 容器。
例如,将有关屏幕浏览的信息推送到 DataLayer 地图, 则可以在跟踪代码管理器网页界面中设置代码以触发转化像素 并跟踪调用以响应这些屏幕浏览量, 将其编码到应用中
使用 push:
将事件推送到数据层
//
// ViewController.m
// Pushing an openScreen event with a screen name into the data layer.
//
#import "MyAppDelegate.h"
#import "TAGDataLayer.h"
#import "ViewController.h"
@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
在网页界面中,您现在可以创建代码(例如 Google Analytics 代码) 创建以下规则来针对每个屏幕浏览触发: 为“openScreen”。传递屏幕名称 添加到上述某个代码中,请创建一个引用“screenName”参数的数据层宏, 键。你还可以创建代码 (如 Google Ads 转化像素)设置为仅针对特定屏幕浏览触发,具体方法是: 创建一条规则,其中为“openScreen” && 为“ConfirmationScreen”。
6. 预览与发布容器
宏值将始终与当前发布的版本相对应。 在发布容器的最新版本之前,您可以预览 草稿容器
要预览容器,请在 Google
跟踪代码管理器网页界面:选择容器版本
您想预览的内容,然后选择Preview
。请稍候
此预览网址,因为您在后续步骤中会用到它。

如需启用容器预览,您必须向应用添加代码 委托实现文件并定义 Google 跟踪代码管理器预览网址 架构。
首先,将以下加粗的代码段添加到应用委托文件中:
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.tagManager = [TAGManager instance];
// Add the code in bold below to preview a Google Tag Manager container.
// IMPORTANT: This code must be called before the container is opened.
NSURL *url = [launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
if (url != nil) {
[self.tagManager previewWithUrl:url];
}
id<TAGContainerFuture> future =
[TAGContainerOpener openContainerWithId:@"GTM-XXXX" // Placeholder Container ID.
tagManager:self.tagManager
openType:kTAGOpenTypePreferNonDefault
timeout:nil];
// The rest of your method implementation.
self.container = [future get];
return YES;
}
// Add the code in bold below preview a Google Tag Manager container.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([self.tagManager previewWithUrl:url]) {
return YES;
}
// Code to handle other urls.
return NO;
}
接下来,在 应用属性列表文件的网址类型键:
URL identifier: your.package_name URL scheme: tagmanager.c.your.package.name

在模拟器或实体设备上打开链接 在应用中预览草稿容器。
准备好将草稿配置值提供给您的 应用程序, 发布容器。
高级配置
移动版 Google 跟踪代码管理器提供一系列高级配置, 可让您根据运行时条件选择值, 手动刷新容器,并获取用于打开 容器以下各部分概述了一些最常用的高级方法, 配置。
打开容器的高级选项
Google 跟踪代码管理器 SDK 提供了多种方法来打开 容器,可让您更好地控制加载过程:
openContainerById:callback:
openContainerById:callback:
是最低级别且最灵活的 API,用于
容器。它会立即返回一个默认容器,
还会异步从磁盘或网络加载容器,
容器是否存在,或者保存的容器不是最新的(超过 12 小时)。
@interface ContainerCallback : NSObject<TAGContainerCallback>
@end
@implementation ContainerCallback
/**
* Called before the refresh is about to begin.
*
* @param container The container being refreshed.
* @param refreshType The type of refresh which is starting.
*/
- (void)containerRefreshBegin:(TAGContainer *)container
refreshType:(TAGContainerCallbackRefreshType)refreshType {
// Notify UI that container refresh is beginning.
}
/**
* Called when a refresh has successfully completed for the given refresh type.
*
* @param container The container being refreshed.
* @param refreshType The type of refresh which completed successfully.
*/
- (void)containerRefreshSuccess:(TAGContainer *)container
refreshType:(TAGContainerCallbackRefreshType)refreshType {
// Notify UI that container is available.
}
/**
* Called when a refresh has failed to complete for the given refresh type.
*
* @param container The container being refreshed.
* @param failure The reason for the refresh failure.
* @param refreshType The type of refresh which failed.
*/
- (void)containerRefreshFailure:(TAGContainer *)container
failure:(TAGContainerCallbackRefreshFailure)failure
refreshType:(TAGContainerCallbackRefreshType)refreshType {
// Notify UI that container request has failed.
}
@end
在整个加载过程中,存在openContainerById:callback:
个问题
多个生命周期回调,以便您的代码发现
加载请求开始,是否失败或成功及其原因,以及是否
容器最终是从磁盘或网络加载的。
除非您的应用允许使用默认值 您需要使用这些回调来了解 容器加载完成请注意,您将无法加载已保存的 网络容器(如果这是首次运行该应用,并且没有 网络连接。
openContainerById:callback:
会将以下 enum
值作为参数传递给这些回调:
RefreshType
值 | 说明 |
---|---|
kTAGContainerCallbackRefreshTypeSaved
|
刷新请求正在加载保存在本地的容器。 |
kTAGContainerCallbackRefreshTypeNetwork
|
刷新请求通过网络加载容器。 |
RefreshFailure
值 | 说明 |
---|---|
kTAGContainerCallbackRefreshFailureNoSavedContainer
|
没有可用的已保存容器。 |
kTAGContainerCallbackRefreshFailureIoError
|
I/O 错误阻止刷新容器。 |
kTAGContainerCallbackRefreshFailureNoNetwork
| 没有可用的网络连接。 |
kTAGContainerCallbackRefreshFailureNetworkError
|
出现网络错误。 |
kTAGContainerCallbackRefreshFailureServerError
|
服务器上出现错误。 |
kTAGContainerCallbackRefreshFailureUnknownError
|
发生了无法分类的错误。 |
打开非默认容器和最新容器的方法
TAGContainerOpener
封装 openContainerById:callback:
提供两种打开容器的便捷方法:
openContainerWithId:tagManager:openType:timeout:notifier:
和
openContainerWithId:tagManager:openType:timeout:
。
这些方法均采用枚举,用于请求非默认或 容器。
建议为大多数应用使用 kTAGOpenTypePreferNonDefault
,
尝试返回指定的给定容器中第一个可用的非默认容器
超时期限(磁盘或网络),即使该容器
超过 12 小时。如果它返回过时的已保存容器,
异步网络请求
使用 kTAGOpenTypePreferNonDefault
时,
如果没有其他容器可用,或者超时期限已过,则返回容器。
超出上限。
kTAGOpenTypePreferFresh
尝试从
磁盘或网络的流量。
如果某个广告网络
连接不可用和/或已超过超时期限。
不建议使用 kTAGOpenTypePreferFresh
在请求时间较长可能会明显影响用户体验的情况下,
例如使用界面标记或显示字符串您还可以使用
TAGContainer::refresh
(不限时间)
来强制执行网络容器请求
这两种便捷方法都是非阻塞的。
openContainerWithId:tagManager:openType:timeout:
会返回
TAGContainerFuture
对象,其 get
方法会返回
TAGContainer
(但在此之前,该操作将阻塞)。
openContainerWithId:tagManager:openType:timeout:notifier:
方法接受单个回调,
在容器可用时调用的方法。
两种方法的默认超时期限均为
2.0
秒。
使用规则在运行时评估宏
容器可以在运行时使用规则评估值。规则可能 例如设备语言、平台或任何其他宏值对于 例如,可以使用规则根据 设备的语言。您可以使用 以下规则:

然后,您可以为每种语言创建值集合宏,并将此 规则,插入相应的语言代码。这个容器 发布后,您的应用将能够在 字符串,具体取决于用户设备在运行时的语言。
请注意,如果您的默认容器需要规则,您必须使用 二进制文件容器文件 容器。
默认二进制文件容器文件
需要规则的默认容器应使用二进制容器文件 而不是属性列表文件或 JSON 文件作为默认容器。二元容器支持确定 宏值,而 属性列表或 JSON 文件不能。
二进制容器文件可从 Google 跟踪代码管理器网站下载
和
应按照以下命名惯例添加到您的主应用软件包中:
GTM-XXXX
,其中文件名表示您的
容器 ID。
在属性列表文件和/或 JSON 文件的情况下 以及二进制容器文件存在时,SDK 将使用二进制容器 文件作为默认容器。
使用函数调用宏
函数调用宏是设置为 指定函数函数调用宏可用于 将运行时值纳入您的 Google 跟踪代码管理器规则中,例如 在运行时根据配置的 设备的语言和货币
如需配置函数调用宏,请执行以下操作:
- 在 Google 跟踪代码管理器网页界面中定义函数调用宏。 您可以选择将参数配置为键值对。
- 定义一个实现
TAGFunctionCallMacroHandler
的处理程序 协议:// 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 - 使用 TAGContainer::registerFunctionCallMacroHandler:forMacro: 和函数名称注册处理程序 在 Google 跟踪代码管理器界面中指定:
//
// MyAppDelegate.h
//
#import <UIKit/UIKit.h>
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@end
//
// MyAppDelegate.m
//
#import "MyAppDelegate.h"
#import "MyFunctionCallMacroHandler.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 macro handler using the macro name defined
// in the Google Tag Manager web interface.
[self.container registerFunctionCallMacroHandler:[[MyFunctionCallMacroHandler alloc] init]
forMacro:kMyMacroFunctionName];
}
@end
使用函数调用标记
借助函数调用代码,每当用户调用预注册函数时,
将事件推送到数据层和代码规则
求得的值为 true
。
如需配置函数调用代码,请执行以下操作:
- 在 Google 跟踪代码管理器网页界面中定义函数调用代码。 您可以选择将参数配置为键值对。
- 实现
TAGFunctionCallTagHandler
协议://
// 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) evaluate 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 - 使用在 Google 跟踪代码管理器网页界面:
//
// MyAppDelegate.h
//
#import <UIKit/UIKit.h>
@interface MyAppDelegate : UIResponder <UIApplicationDelegate>
@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
设置自定义刷新周期
Google 跟踪代码管理器 SDK 将尝试
一个新容器(如果当前容器的存在时间超过 12 小时)。要设置
自定义容器刷新周期,请使用
NSTimer
,如
示例:
- (void)refreshContainer:(NSTimer *)timer {
[self.container refresh];
}
self.refreshTimer = [NSTimer scheduledTimerWithTimeInterval:<refresh_interval>
target:self
selector:@selector(refreshContainer:)
userInfo:nil
repeats:YES];
使用 Logger 调试
默认情况下,Google 跟踪代码管理器 SDK 会将错误和警告输出到日志中。
启用更详细的日志记录有助于进行调试,
实现自己的 Logger
,如以下示例所示:
// MyAppDelegate.h
// This example assumes this file is using ARC.
// This Logger class will print out not just errors and warnings (as the default
// logger does), but also info, debug, and verbose messages.
@interface MyLogger: NSObject<TAGLogger>
@end
@implementation MyLogger
- (void)error:(NSString *)message {
NSLog(@"Error: %@", message);
}
- (void)warning:(NSString *)message {
NSLog(@"Warning: %@", message);
}
- (void)info:(NSString *)message {
NSLog(@"Info: %@", message);
}
- (void)debug:(NSString *)message {
NSLog(@"Debug: %@", message);
}
- (void)verbose:(NSString *)message {
NSLog(@"Verbose: %@", message);
}
@end
// MyAppDelegate.m
// This example assumes this file is using ARC.
@implementation MyAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.tagManager = [TAGManager instance];
self.tagManager.logger = [[MyLogger alloc] init];
// Rest of Tag Manager and method implementation.
return YES;
}
// Rest of app delegate implementation.
@end
或者,你可以使用
TagManager::logger::setLogLevel
,
如以下示例中所示:
// Change the LogLevel to INFO to enable logging at INFO and higher levels.
self.tagManager = [TAGManager instance];
[self.tagManager.logger setLogLevel:kTAGLoggerLogLevelInfo];