Руководство по началу работы с Objective-C

В этом руководстве для разработчиков описывается, как внедрить Диспетчер тегов Google в мобильное приложение.

Введение

Диспетчер тегов Google позволяет разработчикам изменять значения конфигурации в своих мобильных приложениях с помощью интерфейса Диспетчера тегов Google без необходимости пересобирать и повторно отправлять двоичные файлы приложений на торговые площадки приложений.

Это полезно для управления любыми значениями конфигурации или флагами в вашем приложении, которые вам, возможно, придется изменить в будущем, в том числе:

  • Различные настройки пользовательского интерфейса и строки отображения.
  • Размеры, местоположения и типы объявлений, показываемых в вашем приложении.
  • Игровые настройки

Значения конфигурации также могут оцениваться во время выполнения с использованием правил, позволяющих создавать такие динамические конфигурации, как:

  • Использование размера экрана для определения размера рекламного баннера
  • Использование языка и местоположения для настройки элементов пользовательского интерфейса

Google TagManager также обеспечивает динамическую реализацию тегов и пикселей отслеживания в приложениях. Разработчики могут перенести важные события на уровень данных и позже решить, какие теги отслеживания или пиксели следует активировать. TagManager в настоящее время поддерживает следующие теги:

  • Аналитика мобильных приложений Google
  • Тег вызова пользовательской функции

Прежде чем вы начнете

Прежде чем использовать это руководство по началу работы, вам понадобится следующее:

Если вы новичок в Диспетчере тегов Google, мы рекомендуем вам узнать больше о контейнерах, макросах и правилах (Справочный центр), прежде чем продолжить работу с этим руководством.

Начиная

В этом разделе разработчикам описывается типичный рабочий процесс Диспетчера тегов:

  1. Добавьте Google Tag Manager SDK в свой проект.
  2. Установить значения контейнера по умолчанию
  3. Откройте контейнер
  4. Получить значения конфигурации из контейнера
  5. Отправка событий на уровень данных
  6. Предварительный просмотр и публикация контейнера

1. Добавление SDK Google Tag Manager в ваш проект.

Прежде чем использовать SDK Диспетчера тегов Google, вам необходимо добавить в свой проект libGoogleAnalyticsServices.a и файлы заголовков Диспетчера тегов Google (GTM) из каталога Library пакета SDK.

Затем добавьте следующее в связанные библиотеки целевого приложения, если они еще не присутствуют:

  • CoreData.framework
  • SystemConfiguration.framework
  • libz.dylib
  • libsqlite3.dylib
  • libGoogleAnalyticsServices.a

Если вы хотите, чтобы ваше приложение имело доступ к идентификатору рекламодателей (IDFA) и флагу отслеживания, предоставляемому этой платформой, через макросы Google Tag Manager SDK, вам также необходимо связать эти дополнительные библиотеки:

  • libAdIdAccess.a
  • AdSupport.framework

2. Добавление файла контейнера по умолчанию в ваш проект

Диспетчер тегов Google использует контейнер по умолчанию при первом запуске вашего приложения. Контейнер по умолчанию будет использоваться до тех пор, пока приложение не сможет получить новый контейнер по сети.

Чтобы загрузить и добавить в приложение двоичный файл контейнера по умолчанию, выполните следующие действия:

  1. Войдите в веб-интерфейс Диспетчера тегов Google.
  2. Выберите версию контейнера, который вы хотите загрузить.
  3. Нажмите кнопку «Загрузить» , чтобы получить двоичный файл контейнера.
  4. Добавьте двоичный файл в корневой каталог вашего проекта и в папку «Supporting Files» вашего проекта.

Имя файла по умолчанию должно быть идентификатором контейнера (например GTM-1234 ). После загрузки двоичного файла обязательно удалите суффикс версии из имени файла, чтобы обеспечить правильное соглашение об именах.

Хотя использование двоичного файла рекомендуется, если ваш контейнер не содержит правил или тегов, вы можете вместо этого использовать простой список свойств или файл JSON. Файл должен находиться в основном пакете и соответствовать следующему соглашению об именах: <Container_ID>.<plist|json> . Например, если идентификатор вашего контейнера — 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, вы можете настроить теги в веб-интерфейсе Диспетчера тегов для активации пикселей конверсии и отслеживания вызовов в ответ на эти просмотры экрана без необходимости жесткого кодирования их в вашем приложении.

События передаются на уровень данных с помощью 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 Рекламы), который будет активироваться только для определенных просмотров экрана, создав правило, в котором равно "openScreen" && равно "ConfirmationScreen".

6. Предварительный просмотр и публикация контейнера

Значения макросов всегда будут соответствовать текущей опубликованной версии. Прежде чем публиковать последнюю версию контейнера, вы можете просмотреть черновой вариант контейнера.

Чтобы просмотреть контейнер, создайте URL-адрес предварительного просмотра в веб-интерфейсе Диспетчера тегов Google, выбрав версию контейнера, который вы хотите просмотреть, а затем выбрав Preview . Сохраните этот URL-адрес предварительного просмотра, поскольку он понадобится вам на последующих этапах.

URL-адреса предварительного просмотра доступны в окне предварительного просмотра веб-интерфейса Диспетчера тегов.
Рисунок 1. Получение URL-адреса предварительного просмотра из веб-интерфейса Диспетчера тегов.

Чтобы включить предварительный просмотр контейнера, необходимо добавить код в файл реализации делегата приложения и определить схему URL-адреса предварительного просмотра Диспетчера тегов 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-адреса и схему URL-адреса в ключе типов URL-адресов файла списка свойств вашего приложения:

URL identifier: your.package_name
URL scheme: tagmanager.c.your.package.name
Зарегистрируйте схему URL-адреса предварительного просмотра диспетчера тегов в файле списка свойств вашего приложения.
Рисунок 3. Добавление схемы URL-адресов предварительного просмотра Диспетчера тегов в файл списка свойств вашего приложения.

Откройте ссылку на эмуляторе или физическом устройстве, чтобы просмотреть черновой вариант контейнера в своем приложении.

Когда вы будете готовы сделать значения черновой конфигурации доступными для вашего приложения, опубликуйте контейнер .

Расширенная конфигурация

Диспетчер тегов Google для мобильных устройств имеет ряд расширенных параметров конфигурации, которые позволяют выбирать значения на основе условий времени выполнения с помощью правил, вручную обновлять контейнер и получать дополнительные возможности для открытия контейнеров. В следующих разделах описаны некоторые из наиболее распространенных расширенных конфигураций.

Расширенные возможности открытия контейнеров

SDK Google Tag Manager предоставляет несколько методов открытия контейнеров, которые могут дать вам больше контроля над процессом загрузки:

openContainerById: обратный вызов:

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 в качестве аргументов этим обратным вызовам:

Тип обновления

Ценить Описание
kTAGContainerCallbackRefreshTypeSaved Запрос на обновление загружает локально сохраненный контейнер.
kTAGContainerCallbackRefreshTypeNetwork Запрос на обновление загружает контейнер по сети.

ОбновитьОшибка

Ценить Описание
kTAGContainerCallbackRefreshFailureNoSavedContainer Сохраненного контейнера нет.
kTAGContainerCallbackRefreshFailureIoError Ошибка ввода-вывода не позволила обновить контейнер.
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 секунды.

Оценка макросов во время выполнения с использованием правил

Контейнеры могут оценивать значения во время выполнения с помощью правил. Правила могут основываться на таких критериях, как язык устройства, платформа или любое другое значение макроса. Например, правила можно использовать для выбора локализованной строки отображения на основе языка устройства во время выполнения. Это можно настроить с помощью следующего правила:

Правило используется для выбора отображаемых строк на основе языка устройства во время выполнения: язык равен es. В этом правиле используется предварительно определенный макрос языка и двухсимвольный код языка ISO 639-1.
Рис. 1. Добавление правила для включения макроса сбора значений только для устройств, настроенных на использование испанского языка.

Затем вы можете создать макросы сбора значений для каждого языка и добавить это правило к каждому макросу, вставив соответствующий код языка. Когда этот контейнер будет опубликован, ваше приложение сможет отображать локализованные строки отображения в зависимости от языка пользовательского устройства во время выполнения.

Обратите внимание: если вашему контейнеру по умолчанию нужны правила, вы должны использовать двоичный файл контейнера в качестве контейнера по умолчанию.

Узнайте больше о настройке правил (Справочный центр).

Двоичные файлы-контейнеры по умолчанию

Контейнеры по умолчанию, для которых требуются правила, должны использовать двоичный файл контейнера вместо файла списка свойств или файла JSON в качестве контейнера по умолчанию. Двоичные контейнеры поддерживают определение значений макросов во время выполнения с помощью правил Диспетчера тегов Google, тогда как список свойств или файлы JSON этого не делают.

Двоичные файлы-контейнеры можно загрузить из веб-интерфейса Диспетчера тегов Google, и их следует добавить в основной пакет приложения, следуя соглашению об именах: GTM-XXXX , где имя файла представляет идентификатор вашего контейнера.

В случаях, когда присутствует файл списка свойств и/или файл JSON, а также файл двоичного контейнера, SDK будет использовать файл двоичного контейнера в качестве контейнера по умолчанию.

Использование макросов вызова функций

Макросы вызова функций — это макросы, которым присваивается возвращаемое значение указанной функции в вашем приложении. Макросы вызова функций можно использовать для включения значений времени выполнения в правила Диспетчера тегов Google, например, для определения во время выполнения, какую цену отображать пользователю на основе настроенного языка и валюты устройства.

Чтобы настроить макрос вызова функции:

  1. Определите макрос вызова функции в веб-интерфейсе Диспетчера тегов Google. Аргументы могут быть дополнительно настроены как пары ключ-значение.
  2. Определите обработчик, реализующий протокол 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
    
  3. Зарегистрируйте обработчик, используя TAGContainer::registerFunctionCallMacroHandler:forMacro: и имя функции, указанное в интерфейсе Диспетчера тегов Google:
  4. //
    // 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 .

Чтобы настроить тег вызова функции:

  1. Определите тег вызова функции в веб-интерфейсе Диспетчера тегов Google. Аргументы могут быть дополнительно настроены как пары ключ-значение.
  2. Реализуйте протокол 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
    
  3. Зарегистрируйте обработчик тега вызова функции, используя имя тега, настроенное в веб-интерфейсе Диспетчера тегов Google:
  4. //
    // 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
    

Установка пользовательского периода обновления

SDK Диспетчера тегов Google попытается получить новый контейнер, если текущий возраст контейнера превышает 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

SDK Диспетчера тегов Google по умолчанию печатает ошибки и предупреждения в журналах. Включение более подробного ведения журнала может быть полезно для отладки и возможно путем реализации собственного 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

Или вы можете установить LogLevel существующего Logger с помощью 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];