本開發人員指南說明如何在 行動應用程式
簡介
Google 代碼管理工具可讓開發人員變更設定 透過 Google 代碼管理工具 在行動應用程式中放送 不必重新建立應用程式二進位檔並重新提交至應用程式介面 市集。
這很適合用來管理任何設定值 日後可能需要變更 包括:
- 各種 UI 設定和顯示字串
- 在應用程式中放送的廣告大小、位置或類型
- 遊戲設定
您也能在執行階段使用規則,評估設定值 可啟用動態設定,例如:
- 使用螢幕大小決定廣告橫幅大小
- 使用語言和位置設定 UI 元素
Google 代碼管理工具也能以動態方式導入追蹤代碼 模型和像素的應用方式開發人員可以將重要事件推送至資料 ,並決定要觸發哪些追蹤代碼或像素。 代碼管理工具目前支援下列代碼:
- Google 行動應用程式分析
- 自訂函式呼叫代碼
事前準備
使用這份入門指南之前,您必須符合以下條件:
- Google 代碼管理工具帳戶
- 全新的代碼管理工具 容器和值組合巨集
- 要導入 Google 代碼管理工具的 iOS 行動應用程式
- Google Analytics 服務 SDK,其中包含代碼管理工具程式庫。
如果您是 Google 代碼管理工具新手,建議您 請先進一步瞭解容器、巨集和規則 (說明中心),再繼續閱讀本指南。
開始使用
本節將引導開發人員完成一般的代碼管理工具工作流程:
1. 將 Google 代碼管理工具 SDK 加進專案
使用 Google 代碼管理工具 SDK 前
libGoogleAnalyticsServices.a
以及 Library
的 Google 代碼管理工具 (GTM) 標頭檔案
新增至專案中 SDK 套件的目錄
接著,將下列內容加入應用程式目標的連結程式庫 (如果這些程式庫中) 尚未存在:
CoreData.framework
SystemConfiguration.framework
libz.dylib
libsqlite3.dylib
libGoogleAnalyticsServices.a
如果您希望應用程式存取 廣告客戶 (IDFA) 和追蹤標幟 Google 代碼管理工具 SDK 巨集,您也必須連結下列額外程式庫:
libAdIdAccess.a
AdSupport.framework
2. 在專案中新增預設容器檔案
Google 代碼管理工具會在應用程式第一次執行時使用預設容器。預設 並持續使用直到應用程式能透過 更是如此
如要下載及新增預設容器二進位檔至應用程式,請按照下列步驟操作:
- 登入 Google 代碼管理工具網頁介面。
- 選取要下載的容器「版本」。
- 點選「下載」按鈕,擷取容器二進位檔。
- 將二進位檔案加入 專案的根目錄和「支援檔案」資料夾
預設檔案名稱應為容器 ID (例如 GTM-1234
)。
已下載二進位檔案,請務必移除檔案名稱中的版本後置字串
以確保遵循正確的命名慣例
雖然我們建議您使用二進位檔案,但如果容器不含規則或標記,
可以選用一個簡單的
屬性清單或 JSON
檔案。
檔案應位於主要套件中,且應如下所示
這個命名慣例:<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 是一種地圖,可用來啟用應用程式的執行階段資訊,例如觸控功能 才能供代碼管理工具巨集和畫面瀏覽 都會在 Docker 容器中執行
例如,將畫面瀏覽的相關資訊推送到 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,用於開啟
都會在 Docker 容器中執行此函式會立即傳回包含預設容器
如果未儲存任何檔案
則能以非同步方式從磁碟或網路載入容器
或儲存的容器還不是最新狀態 (超過 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
對使用者體驗產生明顯影響
例如 UI 旗標或顯示字串您也可以使用
隨時TAGContainer::refresh
強制執行網路容器要求
這兩種方便的方法都是非阻塞。
openContainerWithId:tagManager:openType:timeout:
會傳回
TAGContainerFuture
物件,其 get
方法會傳回
TAGContainer
載入後立即執行 (但 仍會封鎖)。
openContainerWithId:tagManager:openType:timeout:notifier:
方法會採用單一回呼
會在有容器可用時呼叫
這兩種方法的預設逾時期限為
2.0
秒。
使用規則評估執行階段的巨集
容器可以在執行階段透過規則評估值。可根據規則進行設定 例如裝置語言、平台或任何其他巨集值適用對象 例如,您可以運用規則根據 以及裝置在執行階段的語言使用 GCP 控制台 規則:
接著,您就可以為每個語言建立值收集巨集,並將 規則,並插入適當的語言代碼。當這個容器 發布後,您的應用程式就會顯示本地化的螢幕 字串,視使用者裝置在執行階段的語言而定。
請注意,如果預設容器需要規則,您必須使用 二進位容器檔案做為預設選項 都會在 Docker 容器中執行
二進位檔預設容器檔案
需要規則的預設容器應使用二進位容器檔案 而不是屬性清單檔案或 JSON file 設為預設容器,二進位檔容器支援判定 巨集值在執行階段套用 Google 代碼管理工具規則時, 屬性清單或 JSON 檔案不會
您可以從 Google 代碼管理工具網站下載二進位容器檔案
介面和 API
應按照以下命名慣例新增至主要應用程式套件:
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: 和函式名稱來註冊處理常式: 找到以下幾點
// // 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
或者,您也可以使用以下方法設定現有 Logger 的 LogLevel:
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];