В этом руководстве для разработчиков описывается, как интегрировать Google Tag Manager в мобильное приложение.
Введение
Google Tag Manager позволяет разработчикам изменять параметры конфигурации в своих мобильных приложениях с помощью интерфейса Google Tag Manager без необходимости пересобирать и повторно отправлять бинарные файлы приложений в магазины приложений.
Это полезно для управления любыми значениями конфигурации или флагами в вашем приложении, которые вам может потребоваться изменить в будущем, включая:
- Различные настройки пользовательского интерфейса и строки отображения.
- Размеры, расположение или типы рекламных объявлений, показываемых в вашем приложении.
- Настройки игры
Значения конфигурации также могут оцениваться во время выполнения с помощью правил, что позволяет создавать динамические конфигурации, такие как:
- Размер экрана используется для определения размера рекламного баннера.
- Использование языка и местоположения для настройки элементов пользовательского интерфейса.
Google TagManager также позволяет динамически внедрять теги и пиксели отслеживания в приложения. Разработчики могут передавать важные события в слой данных и позже решать, какие теги или пиксели отслеживания должны быть активированы. TagManager поддерживает следующие теги:
- Google Mobile App Analytics
- Метка вызова пользовательской функции
Прежде чем начать
Перед использованием данного руководства вам потребуется следующее:
- Аккаунт Google Tag Manager
- Новый контейнер Tag Manager и макрос для сбора значений.
- Мобильное приложение для iOS, в которое можно внедрить Google Tag Manager.
- SDK Google Analytics Services , который содержит библиотеку Tag Manager.
Если вы новичок в Google Tag Manager, мы рекомендуем вам ознакомиться с информацией о контейнерах, макросах и правилах (Справочный центр), прежде чем продолжить изучение этого руководства.
Начиная
В этом разделе разработчики ознакомятся с типичным рабочим процессом менеджера тегов:
- Добавьте SDK Google Tag Manager в свой проект.
- Установить значения контейнера по умолчанию
- Откройте контейнер
- Получение значений конфигурации из контейнера
- Передача событий в DataLayer
- Предварительный просмотр и публикация контейнера
1. Добавление SDK Google Tag Manager в ваш проект
Перед использованием SDK Google Tag Manager необходимо добавить в проект файлы libGoogleAnalyticsServices.a и заголовочные файлы Google Tag Manager (GTM) из каталога Library пакета SDK.
Далее добавьте следующие библиотеки в связанные библиотеки целевого приложения, если они еще не присутствуют:
-
CoreData.framework -
SystemConfiguration.framework -
libz.dylib -
libsqlite3.dylib -
libGoogleAnalyticsServices.a
Если вы хотите, чтобы ваше приложение имело доступ к идентификатору рекламодателей (IDFA) и флагу отслеживания, предоставляемым этой платформой через макросы SDK Google Tag Manager, вам также потребуется подключить следующие дополнительные библиотеки:
-
libAdIdAccess.a -
AdSupport.framework
2. Добавление файла контейнера по умолчанию в ваш проект
Google Tag Manager использует контейнер по умолчанию при первом запуске вашего приложения. Этот контейнер будет использоваться до тех пор, пока приложение не сможет получить новый контейнер по сети.
Чтобы загрузить и добавить в ваше приложение исполняемый файл контейнера по умолчанию, выполните следующие действия:
- Войдите в веб-интерфейс Google Tag Manager.
- Выберите версию контейнера, которую хотите загрузить.
- Нажмите кнопку «Загрузить» , чтобы получить исполняемый файл контейнера.
- Добавьте исполняемый файл в корневой каталог вашего проекта, а также в папку "Вспомогательные файлы" вашего проекта.
По умолчанию имя файла должно совпадать с идентификатором контейнера (например, 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 — это карта, которая позволяет предоставлять макросам и тегам Tag Manager в контейнере информацию о вашем приложении в режиме реального времени, например, о событиях касания или просмотрах экрана.
Например, передавая информацию о просмотрах экранов в карту DataLayer, вы можете настроить теги в веб-интерфейсе Tag Manager для запуска пикселей конверсии и вызовов отслеживания в ответ на эти просмотры экранов, без необходимости жестко прописывать их в коде вашего приложения.
События передаются в 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), которые срабатывают для каждого просмотра экрана, создав следующее правило: equals "openScreen". Чтобы передать имя экрана одному из этих тегов, создайте макрос слоя данных, который ссылается на ключ "screenName" в слое данных. Вы также можете создать тег (подобный пикселю конверсии Google Ads), который срабатывает только для определенных просмотров экрана, создав правило, где equals "openScreen" && equals "ConfirmationScreen".
6. Предварительный просмотр и публикация контейнера
Значения макросов всегда будут соответствовать текущей опубликованной версии. Перед публикацией последней версии контейнера вы можете предварительно просмотреть черновой вариант контейнера.
Чтобы просмотреть содержимое контейнера, сгенерируйте URL-адрес предварительного просмотра в веб-интерфейсе Google Tag Manager, выбрав версию контейнера, которую вы хотите просмотреть, а затем нажав Preview . Сохраните этот URL-адрес предварительного просмотра, так как он понадобится вам на последующих шагах.

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

Откройте ссылку на эмуляторе или физическом устройстве, чтобы просмотреть черновой вариант контейнера в вашем приложении.
Когда вы будете готовы сделать значения конфигурации, созданные в черновом варианте, доступными для вашего приложения, опубликуйте контейнер .
Расширенные настройки
Google Tag Manager для мобильных устройств предлагает ряд расширенных параметров конфигурации, позволяющих выбирать значения на основе условий выполнения с помощью правил, вручную обновлять контейнер и получать дополнительные параметры для открытия контейнеров. В следующих разделах описаны несколько наиболее распространенных расширенных настроек.
Расширенные параметры открытия контейнеров
SDK Google Tag Manager предоставляет несколько методов открытия контейнеров, которые позволяют лучше контролировать процесс загрузки:
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 | Ошибка ввода-вывода помешала обновлению контейнера. |
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 в качестве контейнера по умолчанию. Бинарные контейнеры поддерживают определение значений макросов во время выполнения с помощью правил Google Tag Manager, в то время как файлы списка свойств или файлы JSON этого не делают.
Бинарные файлы контейнера можно загрузить из веб-интерфейса Google Tag Manager и добавить в основной пакет приложения, используя следующую систему именования: GTM-XXXX , где имя файла представляет собой идентификатор вашего контейнера.
В случаях, когда присутствуют файл списка свойств и/или JSON-файл, а также бинарный файл-контейнер, SDK будет использовать бинарный файл-контейнер в качестве контейнера по умолчанию.
Использование макросов вызова функций
Макросы вызова функций — это макросы, которые задаются возвращаемым значением указанной функции в вашем приложении. Макросы вызова функций можно использовать для включения значений, отображаемых во время выполнения, в правила Google Tag Manager, например, для определения во время выполнения, какую цену отображать пользователю в зависимости от настроенного языка и валюты устройства.
Для настройки макроса вызова функции:
- Определите макрос вызова функции в веб-интерфейсе Google Tag Manager. Аргументы могут быть дополнительно настроены в виде пар ключ-значение.
- Определите обработчик, реализующий протокол
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 Tag Manager:
// // 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 Tag Manager. Аргументы могут быть дополнительно настроены в виде пар ключ-значение.
- Реализуйте протокол
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 Tag Manager:
// // 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 Tag Manager попытается получить новый контейнер, если возраст текущего контейнера превышает 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 Tag Manager ошибки и предупреждения по умолчанию записываются в журналы. Включение более подробного логирования может быть полезно для отладки и возможно путем реализации собственного 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];