Guía de introducción de Objective-C

En esta guía para desarrolladores, se describe cómo implementar Google Tag Manager en una aplicación para dispositivos móviles.

Introducción

Google Tag Manager permite que los desarrolladores cambien los valores de configuración en sus aplicaciones para dispositivos móviles mediante su interfaz sin tener que volver a compilar y volver a enviar los objetos binarios de la aplicación a los mercados de apps.

Esto es útil para administrar cualquier valor de configuración o marca en tu aplicación que puedas tener que cambiar en el futuro, incluidos los siguientes:

  • Varias strings de configuración y visualización de la IU
  • Los tamaños, las ubicaciones o los tipos de anuncios que se publican en tu aplicación
  • Configuración de juegos

Los valores de configuración también se pueden evaluar en el entorno de ejecución a través de reglas, que habiliten opciones de configuración dinámicas como las siguientes:

  • Uso del tamaño de la pantalla para determinar el tamaño del banner del anuncio
  • Cómo usar el idioma y la ubicación para configurar los elementos de la IU

Google TagManager también permite la implementación dinámica de píxeles y etiquetas de seguimiento en las aplicaciones. Los desarrolladores pueden enviar eventos importantes a una capa de datos y decidir luego qué etiquetas o píxeles de seguimiento se deben activar. Actualmente, TagManager admite las siguientes etiquetas:

  • Google Analytics para aplicaciones para dispositivos móviles
  • Etiqueta de llamada a función personalizada

Antes de comenzar

Antes de usar esta guía de introducción, necesitarás lo siguiente:

Si es la primera vez que usas Google Tag Manager, te recomendamos que obtengas más información sobre los contenedores, las macros y las reglas (Centro de ayuda) antes de continuar con esta guía.

Getting Started

Esta sección guiará a los desarrolladores por un flujo de trabajo típico de Tag Manager:

  1. Agrega el SDK de Google Tag Manager a tu proyecto
  2. Establece valores de contenedor predeterminados
  3. Abre el contenedor
  4. Obtén valores de configuración del contenedor
  5. Envía eventos a DataLayer
  6. Obtén una vista previa del contenedor y publícalo

1. Cómo agregar el SDK de Google Tag Manager a tu proyecto

Antes de usar el SDK de Google Tag Manager, deberás agregar libGoogleAnalyticsServices.a y los archivos de encabezado de Google Tag Manager (GTM) del directorio Library del paquete del SDK a tu proyecto.

A continuación, agrega lo siguiente a las bibliotecas vinculadas del destino de tu aplicación si aún no están presentes:

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

Si deseas que tu aplicación acceda al identificador para anunciantes (IDFA) y a la marca de seguimiento que proporciona ese framework a través de las macros del SDK de Google Tag Manager, también deberás vincular estas bibliotecas adicionales:

  • libAdIdAccess.a
  • AdSupport.framework

2. Cómo agregar un archivo de contenedor predeterminado a tu proyecto

Google Tag Manager usa un contenedor predeterminado en la primera ejecución de tu aplicación. El contenedor predeterminado se usará hasta que la app pueda recuperar un contenedor nuevo a través de la red.

Para descargar y agregar un objeto binario de contenedor predeterminado a tu aplicación, sigue estos pasos:

  1. Accede a la interfaz web de Google Tag Manager.
  2. Selecciona la Versión del contenedor que deseas descargar.
  3. Haz clic en el botón Descargar para recuperar el objeto binario del contenedor.
  4. Agrega el archivo binario al directorio raíz del proyecto y a la carpeta "Archivos de respaldo" de tu proyecto.

El nombre de archivo predeterminado debe ser el ID del contenedor (por ejemplo, GTM-1234). Una vez que hayas descargado el archivo binario, asegúrate de quitar el sufijo de la versión del nombre de archivo para asegurarte de seguir la convención de nomenclatura correcta.

Aunque se recomienda usar el archivo binario, si tu contenedor no contiene reglas o etiquetas, puedes usar una lista de propiedades simple o un archivo JSON en su lugar. El archivo debe estar ubicado en el paquete principal y debe seguir esta convención de nombres: <Container_ID>.<plist|json>. Por ejemplo, si el ID de contenedor es GTM-1234, puedes especificar los valores predeterminados del contenedor en un archivo de lista de propiedades llamado GTM-1234.plist.

3. Cómo abrir un contenedor

Antes de recuperar valores de un contenedor, tu aplicación debe abrirlo. Cuando abres un contenedor, se carga desde el disco (si está disponible) o se solicita desde la red (si es necesario).

La forma más fácil de abrir un contenedor en iOS es usar openContainerWithId:tagManager:openType:timeout:notifier:, como en el siguiente ejemplo:

// 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. Obtén valores de configuración del contenedor

Una vez que el contenedor está abierto, los valores de configuración se pueden recuperar mediante los métodos <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"];

Las solicitudes realizadas con una clave que no existe mostrarán un valor predeterminado apropiado para el tipo solicitado:

// 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. Envía valores a DataLayer

DataLayer es un mapa que permite que la información del tiempo de ejecución de tu app, como eventos táctiles o vistas de pantalla, esté disponible para las macros y etiquetas de Tag Manager en un contenedor.

Por ejemplo, si envías información sobre vistas de pantalla al mapa de DataLayer, puedes configurar etiquetas en la interfaz web de Tag Manager para activar píxeles de conversión y hacer un seguimiento de las llamadas en respuesta a esas vistas de pantalla sin necesidad de codificarlas en tu app.

Los eventos se envían a DataLayer mediante 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

En la interfaz web, ahora puedes crear etiquetas (como las de Google Analytics) que se activarán para cada vista de pantalla creando esta regla: equivale a "openScreen". Para pasar el nombre de pantalla a una de estas etiquetas, crea una macro de capa de datos que haga referencia a la clave "screenName" en la capa de datos. También puedes crear una etiqueta (como un píxel de conversión de Google Ads) para que se active solo en vistas de pantallas específicas. Para ello, debes crear una regla en la que equivalga a "openScreen" & y sea igual a "ConfirmationScreen".

6. Vista previa y publicación de un contenedor

Los valores de la macro siempre corresponderán a la versión publicada actual. Antes de publicar la versión más reciente de un contenedor, puedes obtener una vista previa del contenedor en borrador.

Si deseas obtener una vista previa de un contenedor, genera una URL de vista previa en la interfaz web de Google Tag Manager. Para ello, selecciona la versión del contenedor de la que deseas obtener una vista previa y, luego, Preview. Mantén esta URL de vista previa, ya que la necesitarás en pasos posteriores.

Las URLs de vista previa están disponibles en la ventana de vista previa de la interfaz web
 de Tag Manager
Figura 1: Obtención de una URL de vista previa de la interfaz web de Tag Manager.

Para habilitar las vistas previas de los contenedores, debes agregar código al archivo de implementación del delegado de la app y definir el esquema de URL de vista previa de Google Tag Manager en la lista de propiedades del proyecto.

Primero, agrega los siguientes fragmentos de código en negrita al archivo delegado de tu app:

@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;
}

Luego, registra el siguiente identificador y esquema de URL en la clave de tipos de URL del archivo de lista de propiedades de tu aplicación:

URL identifier: your.package_name
URL scheme: tagmanager.c.your.package.name
Registra el esquema de URL de vista previa de Tag Manager en el archivo de lista de propiedades de tu aplicación.
Figura 3: Agrega el esquema de URL de vista previa de Tag Manager al archivo de lista de propiedades de tu aplicación.

Abre el vínculo en un emulador o dispositivo físico para obtener una vista previa del contenedor de borrador en tu app.

Cuando tengas todo listo para que los valores de configuración de borrador estén disponibles para tu aplicación, publica el contenedor.

Configuración avanzada

Google Tag Manager para dispositivos móviles tiene varias opciones de configuración avanzada que te permiten seleccionar valores según las condiciones de tiempo de ejecución mediante reglas, actualizar el contenedor de forma manual y obtener opciones adicionales para abrir contenedores. En las siguientes secciones, se describen varias de las configuraciones avanzadas más comunes.

Opciones avanzadas para abrir contenedores

El SDK de Google Tag Manager proporciona varios métodos para abrir contenedores que pueden darte más control sobre el proceso de carga:

openContainerById:devolución de llamada:

openContainerById:callback: es el nivel más bajo y la API más flexible para abrir un contenedor. Se muestra de inmediato con un contenedor predeterminado y también carga un contenedor de forma asíncrona desde el disco o la red si no existe un contenedor guardado o si el contenedor guardado no está actualizado (tiene más de 12 horas de antigüedad).

@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

Durante el proceso de carga, openContainerById:callback: emite varias devoluciones de llamada de ciclo de vida para que tu código pueda determinar cuándo comienza la solicitud de carga, si falla o se realiza de forma correcta, y si el contenedor se cargó en última instancia desde el disco o la red.

A menos que sea aceptable que tu aplicación use los valores predeterminados, deberás usar estas devoluciones de llamada para saber cuándo se cargó un contenedor de red o guardado. Ten en cuenta que no podrás cargar un contenedor de red o guardado si es la primera vez que se ejecuta la app y no hay conexión de red.

openContainerById:callback: pasa los siguientes valores enum como argumentos a estas devoluciones de llamada:

RefreshType

ValorDescripción
kTAGContainerCallbackRefreshTypeSaved La solicitud de actualización está cargando un contenedor guardado localmente.
kTAGContainerCallbackRefreshTypeNetwork La solicitud de actualización está cargando un contenedor a través de la red.

RefreshFailure

ValorDescripción
kTAGContainerCallbackRefreshFailureNoSavedContainer No hay ningún contenedor guardado disponible.
kTAGContainerCallbackRefreshFailureIoError Un error de E/S impidió que se actualizara el contenedor.
kTAGContainerCallbackRefreshFailureNoNetwork No hay ninguna conexión de red disponible.
kTAGContainerCallbackRefreshFailureNetworkError Se produjo un error de red.
kTAGContainerCallbackRefreshFailureServerError Se produjo un error en el servidor.
kTAGContainerCallbackRefreshFailureUnknownError Se produjo un error que no se puede categorizar.

Métodos para abrir contenedores nuevos y no predeterminados

TAGContainerOpener une openContainerById:callback: y proporciona dos métodos convenientes para abrir contenedores: openContainerWithId:tagManager:openType:timeout:notifier: y openContainerWithId:tagManager:openType:timeout:.

Cada uno de estos métodos toma una enumeración que solicita un contenedor nuevo o no predeterminado.

Se recomienda kTAGOpenTypePreferNonDefault para la mayoría de las aplicaciones y trata de mostrar el primer contenedor no predeterminado disponible dentro de un período de tiempo de espera determinado, ya sea desde el disco o la red, incluso si el contenedor tiene más de 12 horas de antigüedad. Si muestra un contenedor guardado inactivo, también realizará una solicitud de red asíncrona para uno nuevo. Cuando se usa kTAGOpenTypePreferNonDefault, se mostrará un contenedor predeterminado si no hay ningún otro contenedor disponible o si se excede el tiempo de espera.

kTAGOpenTypePreferFresh intenta mostrar un contenedor nuevo desde el disco o la red dentro del tiempo de espera determinado. Muestra un contenedor guardado si una conexión de red no está disponible o si se supera el tiempo de espera.

No se recomienda usar kTAGOpenTypePreferFresh en lugares donde un tiempo de solicitud más largo puede afectar notablemente la experiencia del usuario, como con marcas de IU o strings de visualización. También puedes usar TAGContainer::refresh en cualquier momento para forzar una solicitud de contenedor de red.

Ambos métodos de conveniencia no realizan bloqueos. openContainerWithId:tagManager:openType:timeout: muestra un objeto TAGContainerFuture, cuyo método get muestra un TAGContainer en cuanto se carga (pero se bloqueará hasta ese momento). El método openContainerWithId:tagManager:openType:timeout:notifier: recibe una sola devolución de llamada, que se llama cuando el contenedor está disponible. Ambos métodos tienen un tiempo de espera predeterminado de 2.0 segundos.

Evalúa macros en el entorno de ejecución mediante reglas

Los contenedores pueden evaluar valores en el entorno de ejecución mediante reglas. Las reglas pueden basarse en criterios como el idioma del dispositivo, la plataforma o cualquier otro valor de macro. Por ejemplo, se pueden usar reglas para seleccionar una string de pantalla localizada según el idioma del dispositivo en el tiempo de ejecución. Esto se puede configurar con la siguiente regla:

Se usa una regla para seleccionar strings de visualización según el idioma del dispositivo durante el tiempo de ejecución: idioma es igual a es. Esta regla usa la macro de idioma predefinida y un código de idioma ISO 639-1 de dos caracteres.
Figura 1: Se agregó una regla para habilitar una macro de recopilación de valores solo en dispositivos configurados para usar el idioma español.

Luego, puedes crear macros de colección de valores para cada idioma y agregar esta regla a cada macro e insertar el código de idioma adecuado. Cuando se publique este contenedor, tu aplicación podrá mostrar strings de visualización localizadas según el idioma del dispositivo del usuario durante el tiempo de ejecución.

Ten en cuenta que, si tu contenedor predeterminado necesita reglas, debes usar un archivo de contenedor binario como tu contenedor predeterminado.

Obtén más información para configurar reglas (Centro de ayuda).

Archivos de contenedores binarios predeterminados

Los contenedores predeterminados que necesitan reglas deben usar un archivo de contenedor binario en lugar de un archivo de lista de propiedades o un archivo JSON como contenedor predeterminado. Los contenedores binarios son compatibles con la determinación de valores de macros en el entorno de ejecución con las reglas de Google Tag Manager, mientras que los archivos de lista de propiedades o JSON no lo hacen.

Los archivos de contenedor binario se pueden descargar desde la interfaz web de Google Tag Manager y se deben agregar a tu paquete de aplicación principal con esta convención de nombres: GTM-XXXX, en la que el nombre del archivo representa el ID de tu contenedor.

En los casos en que haya un archivo de lista de propiedades o JSON, así como un archivo de contenedor binario, el SDK usará el archivo del contenedor binario como contenedor predeterminado.

Cómo usar macros de llamada a funciones

Las macros de llamada a funciones son macros que se configuran con el valor que se muestra de una función específica en tu aplicación. Las macros de llamada a funciones se pueden usar para incorporar valores del entorno de ejecución con las reglas de Google Tag Manager, como determinar en el entorno de ejecución qué precio mostrar a un usuario en función del idioma y la moneda configurados de un dispositivo.

Para configurar una macro de llamada a función, haz lo siguiente:

  1. Define la macro de llamada a función en la interfaz web de Google Tag Manager. De manera opcional, los argumentos se pueden configurar como pares clave-valor.
  2. Define un controlador que implemente el protocolo 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. Registra el controlador con TAGContainer::registerFunctionCallMacroHandler:forMacro: y el nombre de la función especificado en la interfaz de Google Tag Manager:
  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
    

Cómo usar etiquetas de llamada a funciones

Las etiquetas de llamada a función permiten que se ejecuten funciones con registro previo cada vez que se envíe un evento a la capa de datos y las reglas de la etiqueta se evalúen como true.

Para configurar una etiqueta de llamada a función, sigue estos pasos:

  1. Define la etiqueta de llamada a función en la interfaz web de Google Tag Manager. De manera opcional, los argumentos se pueden configurar como pares clave-valor.
  2. Implementa el protocolo 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. Registra el controlador de la etiqueta de llamada a la función con el nombre de la etiqueta configurado en la interfaz web de Google Tag Manager:
  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
    

Cómo establecer un período de actualización personalizado

El SDK de Google Tag Manager intentará recuperar un contenedor nuevo si su antigüedad actual supera las 12 horas. Para establecer un período personalizado de actualización del contenedor, usa NSTimer, como en el siguiente ejemplo:

- (void)refreshContainer:(NSTimer *)timer {
  [self.container refresh];
}

self.refreshTimer = [NSTimer scheduledTimerWithTimeInterval:<refresh_interval>
                                                     target:self
                                                   selector:@selector(refreshContainer:)
                                                   userInfo:nil
                                                    repeats:YES];

Depuración con Logger

El SDK de Google Tag Manager imprime errores y advertencias en los registros de forma predeterminada. Habilitar un registro más detallado puede ser útil para la depuración y es posible si implementas tu propio Logger, como en este ejemplo:

// 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

O bien, puedes establecer el nivel de registro del registrador existente con TagManager::logger::setLogLevel, como en este ejemplo:

// Change the LogLevel to INFO to enable logging at INFO and higher levels.
self.tagManager = [TAGManager instance];
[self.tagManager.logger setLogLevel:kTAGLoggerLogLevelInfo];