Objective-C 시작 가이드

이 개발자 가이드에서는 모바일 애플리케이션에서 Google 태그 관리자를 구현하는 방법을 설명합니다.

소개

Google 태그 관리자를 사용하면 개발자가 애플리케이션 바이너리를 다시 빌드하고 앱 마켓에 다시 제출하지 않고도 Google 태그 관리자 인터페이스를 사용하여 모바일 애플리케이션의 구성 값을 변경할 수 있습니다.

이 기능은 다음과 같이 애플리케이션에서 향후 변경이 필요할 수 있는 모든 구성 값 또는 플래그를 관리하는 데 유용합니다.

  • 다양한 UI 설정 및 표시 문자열
  • 애플리케이션에 게재되는 광고의 크기, 위치 또는 유형
  • 게임 설정

구성 값은 런타임 시 규칙을 사용하여 평가하여 다음과 같은 동적 구성을 사용 설정할 수도 있습니다.

  • 화면 크기를 사용하여 광고 배너 크기 결정
  • 언어 및 위치를 사용하여 UI 요소 구성

또한 Google TagManager를 사용하면 애플리케이션에서 추적 태그 및 픽셀을 동적으로 구현할 수 있습니다. 개발자는 중요한 이벤트를 데이터 영역으로 푸시하고 실행할 추적 태그 또는 픽셀을 나중에 결정할 수 있습니다. TagManager는 현재 다음과 같은 태그를 지원합니다.

  • Google 모바일 앱 애널리틱스
  • 맞춤 함수 호출 태그

시작하기 전에

이 시작 가이드를 사용하기 전에 다음 항목이 필요합니다.

Google 태그 관리자를 처음 사용하는 경우 이 가이드를 계속하기 전에 컨테이너, 매크로, 규칙 (고객센터)에 대해 자세히 알아보세요.

시작하기

이 섹션에서는 개발자에게 일반적인 태그 관리자 워크플로를 안내합니다.

  1. 프로젝트에 Google 태그 관리자 SDK 추가
  2. 기본 컨테이너 값 설정
  3. 컨테이너 열기
  4. 컨테이너에서 구성 값 가져오기
  5. 데이터 영역에 이벤트 푸시
  6. 컨테이너 미리보기 및 게시하기

1. 프로젝트에 Google 태그 관리자 SDK 추가

Google 태그 관리자 SDK를 사용하기 전에 SDK 패키지의 Library 디렉터리에서 libGoogleAnalyticsServices.a 및 Google 태그 관리자 (GTM) 헤더 파일을 프로젝트에 추가해야 합니다.

다음으로, 애플리케이션 타겟의 연결된 라이브러리에 다음을 추가합니다(아직 없는 경우).

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

애플리케이션에서 Google 태그 관리자 SDK 매크로를 통해 해당 프레임워크에서 제공하는 광고주용 식별자 (IDFA) 및 추적 플래그에 액세스하도록 하려면 이러한 추가 라이브러리도 연결해야 합니다.

  • libAdIdAccess.a
  • AdSupport.framework

2. 프로젝트에 기본 컨테이너 파일 추가

Google 태그 관리자는 애플리케이션을 처음 실행할 때 기본 컨테이너를 사용합니다. 기본 컨테이너는 앱이 네트워크를 통해 새로운 컨테이너를 검색할 수 있을 때까지 사용됩니다.

기본 컨테이너 바이너리를 다운로드하여 애플리케이션에 추가하려면 다음 단계를 따르세요.

  1. Google 태그 관리자 웹 인터페이스에 로그인합니다.
  2. 다운로드할 컨테이너의 버전을 선택합니다.
  3. 다운로드 버튼을 클릭하여 컨테이너 바이너리를 검색합니다.
  4. 프로젝트의 루트 디렉터리와 프로젝트의 'Support Files' 폴더에 바이너리 파일을 추가합니다.

기본 파일 이름은 컨테이너 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는 터치 이벤트 또는 화면 조회수와 같은 앱에 대한 런타임 정보를 컨테이너의 태그 관리자 매크로 및 태그에 사용할 수 있도록 하는 지도입니다.

예를 들어 화면 조회수에 대한 정보를 DataLayer 지도로 푸시하여 태그 관리자 웹 인터페이스에서 태그를 설정하여 앱에 하드 코딩하지 않고도 이러한 화면 조회에 대한 응답으로 전환 픽셀을 실행하고 호출을 추적할 수 있습니다.

이벤트는 push:를 사용하여 DataLayer에 푸시됩니다.

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

이제 웹 인터페이스에서 이 'openScreen'과 같은 규칙을 만들어 각 화면 조회에 실행할 태그 (예: Google 애널리틱스 태그)를 만들 수 있습니다. 이러한 태그 중 하나에 화면 이름을 전달하려면 데이터 영역의 'screenName' 키를 참조하는 데이터 영역 매크로를 만듭니다. 이 'openScreen'과 같고 이 'ConfirmationScreen'과 같은 규칙을 만들어 특정 화면 조회수에만 실행되는 태그(예: Google Ads 전환 픽셀)를 만들 수도 있습니다.

6. 컨테이너 미리보기 및 게시하기

매크로 값은 항상 현재 게시된 버전에 해당합니다. 컨테이너의 최신 버전을 게시하기 전에 임시 컨테이너를 미리 볼 수 있습니다.

컨테이너를 미리 보려면 Google 태그 관리자 웹 인터페이스에서 미리 보려는 컨테이너의 버전을 선택한 후 Preview를 선택하여 미리보기 URL을 생성합니다. 이후 단계에서 필요하므로 이 미리보기 URL을 기다려 주세요.

미리보기 URL은 태그 관리자 웹 인터페이스의 미리보기 창에서
           제공됩니다.
그림 1: 태그 관리자 웹 인터페이스에서 미리보기 URL 가져오기

컨테이너 미리보기를 사용 설정하려면 앱 대리자 구현 파일에 코드를 추가하고 프로젝트의 속성 목록에서 Google 태그 관리자 미리보기 URL 스키마를 정의해야 합니다.

먼저 굵게 표시된 다음 코드 스니펫을 앱 대리자 파일에 추가합니다.

@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 태그 관리자에는 규칙을 사용하여 런타임 조건에 따라 값을 선택하고, 컨테이너를 수동으로 새로고침하고, 컨테이너를 열기 위한 추가 옵션을 가져올 수 있는 다양한 고급 구성 옵션이 있습니다. 다음 섹션에서는 가장 일반적인 고급 구성 몇 가지를 간략히 설명합니다.

컨테이너 열기 고급 옵션

Google 태그 관리자 SDK는 로드 프로세스를 더욱 세밀하게 관리할 수 있는 컨테이너를 여는 몇 가지 방법을 제공합니다.

openContainerById:Callback과 함께 사용합니다.

openContainerById:callback:는 컨테이너를 열기 위한 가장 낮은 수준의 유연한 API입니다. 기본 컨테이너로 즉시 반환되며 저장된 컨테이너가 없거나 저장된 컨테이너가 최신이 아닌 경우(12시간 넘게) 디스크 또는 네트워크에서 컨테이너를 비동기식으로 로드합니다.

@interface ContainerCallback : NSObject<TAGContainerCallback>

@end

@implementation ContainerCallback

/**
 * Called before the refresh is about to begin.
 *
 * @param container The container being refreshed.
 * @param refreshType The type of refresh which is starting.
 */
- (void)containerRefreshBegin:(TAGContainer *)container
                  refreshType:(TAGContainerCallbackRefreshType)refreshType {
  // Notify UI that container refresh is beginning.
}

/**
 * Called when a refresh has successfully completed for the given refresh type.
 *
 * @param container The container being refreshed.
 * @param refreshType The type of refresh which completed successfully.
 */
- (void)containerRefreshSuccess:(TAGContainer *)container
                    refreshType:(TAGContainerCallbackRefreshType)refreshType {
  // Notify UI that container is available.
}

/**
 * Called when a refresh has failed to complete for the given refresh type.
 *
 * @param container The container being refreshed.
 * @param failure The reason for the refresh failure.
 * @param refreshType The type of refresh which failed.
 */
- (void)containerRefreshFailure:(TAGContainer *)container
                        failure:(TAGContainerCallbackRefreshFailure)failure
                    refreshType:(TAGContainerCallbackRefreshType)refreshType {
  // Notify UI that container request has failed.
}
@end

로드 프로세스 전반에 걸쳐 openContainerById:callback:는 로드 요청이 시작되는 시점, 실패 또는 성공 여부와 이유, 컨테이너가 최종적으로 디스크 또는 네트워크에서 로드되었는지 여부를 코드에서 확인할 수 있도록 여러 수명 주기 콜백을 실행합니다.

애플리케이션에서 기본값을 사용하는 것이 허용되지 않는 한 이러한 콜백을 사용하여 저장된 컨테이너 또는 네트워크 컨테이너가 로드된 시점을 확인해야 합니다. 앱을 처음 실행하고 네트워크에 연결되어 있지 않으면 저장된 컨테이너 또는 네트워크 컨테이너를 로드할 수 없습니다.

openContainerById:callback:는 다음 enum 값을 이러한 콜백에 인수로 전달합니다.

RefreshType

설명
kTAGContainerCallbackRefreshTypeSaved 새로고침 요청이 로컬에 저장된 컨테이너를 로드하고 있습니다.
kTAGContainerCallbackRefreshTypeNetwork 새로고침 요청이 네트워크를 통해 컨테이너를 로드하고 있습니다.

RefreshFailure

설명
kTAGContainerCallbackRefreshFailureNoSavedContainer 저장된 컨테이너가 없습니다.
kTAGContainerCallbackRefreshFailureIoError I/O 오류로 인해 컨테이너를 새로고침할 수 없습니다.
kTAGContainerCallbackRefreshFailureNoNetwork 네트워크에 연결할 수 없습니다.
kTAGContainerCallbackRefreshFailureNetworkError 네트워크 오류가 발생했습니다.
kTAGContainerCallbackRefreshFailureServerError 서버에 오류가 발생했습니다.
kTAGContainerCallbackRefreshFailureUnknownError 분류할 수 없는 오류가 발생했습니다.

기본이 아닌 컨테이너 및 최신 컨테이너를 여는 메서드

TAGContainerOpeneropenContainerById:callback:를 래핑하고 컨테이너를 열기 위한 두 가지 편리한 메서드인 openContainerWithId:tagManager:openType:timeout:notifier:openContainerWithId:tagManager:openType:timeout:를 제공합니다.

이러한 각 메서드는 기본이 아닌 컨테이너 또는 최신 컨테이너를 요청하는 열거형을 사용합니다.

kTAGOpenTypePreferNonDefault는 대부분의 애플리케이션에 권장되며, 지정된 제한 시간 내에 디스크 또는 네트워크에서 사용 가능한 기본이 아닌 첫 번째 컨테이너를 반환하려고 시도합니다. 비활성 상태의 저장된 컨테이너를 반환하면 새 컨테이너에 대한 비동기 네트워크 요청도 실행됩니다. kTAGOpenTypePreferNonDefault 사용 시 사용할 수 있는 다른 컨테이너가 없거나 제한 시간을 초과하면 기본 컨테이너가 반환됩니다.

kTAGOpenTypePreferFresh는 지정된 제한 시간 내에 디스크 또는 네트워크에서 새 컨테이너를 반환하려고 시도합니다. 네트워크 연결을 사용할 수 없거나 제한 시간이 초과되면 저장된 컨테이너를 반환합니다.

UI 플래그 또는 표시 문자열과 같이 긴 요청 시간이 사용자 환경에 눈에 띄게 영향을 미칠 수 있는 경우에는 kTAGOpenTypePreferFresh를 사용하지 않는 것이 좋습니다. 언제든지 TAGContainer::refresh를 사용하여 네트워크 컨테이너 요청을 강제할 수도 있습니다.

두 가지 편의 메서드는 모두 비차단 방식입니다. openContainerWithId:tagManager:openType:timeout:TAGContainerFuture 객체를 반환합니다. 이 객체의 get 메서드는 로드되는 즉시 TAGContainer를 반환합니다. 하지만 그때까지는 차단됩니다. openContainerWithId:tagManager:openType:timeout:notifier: 메서드는 컨테이너를 사용할 수 있을 때 호출되는 단일 콜백을 취합니다. 두 메서드 모두 기본 제한 시간은 2.0초입니다.

규칙을 사용하여 런타임 시 매크로 평가

컨테이너는 규칙을 사용하여 런타임에 값을 평가할 수 있습니다. 규칙은 기기 언어, 플랫폼, 기타 매크로 값과 같은 기준을 기반으로 할 수 있습니다. 예를 들어 규칙을 사용하여 런타임 시 기기의 언어에 따라 현지화된 표시 문자열을 선택할 수 있습니다. 이는 다음 규칙을 사용하여 구성할 수 있습니다.

규칙은 런타임 시 기기 언어에 따라 표시 문자열을 선택하는 데 사용됩니다. 언어 같음은 es입니다. 이 규칙은 사전 정의된 언어 매크로와
            2자리 ISO 639-1 언어 코드를 사용합니다.
그림 1: 스페인어를 사용하도록 구성된 기기에만 값 수집 매크로를 사용 설정하는 규칙 추가

그런 다음 각 언어에 대한 값 수집 매크로를 만들고 적절한 언어 코드를 삽입하여 이 규칙을 각 매크로에 추가할 수 있습니다. 이 컨테이너가 게시되면 애플리케이션은 런타임에 사용자 기기의 언어에 따라 현지화된 표시 문자열을 표시할 수 있습니다.

기본 컨테이너에 규칙이 필요한 경우 바이너리 컨테이너 파일을 기본 컨테이너로 사용해야 합니다.

규칙 구성에 대해 자세히 알아보기 (고객센터)

바이너리 기본 컨테이너 파일

규칙이 필요한 기본 컨테이너는 기본 컨테이너로 속성 목록 파일 또는 JSON 파일 대신 바이너리 컨테이너 파일을 사용해야 합니다. 바이너리 컨테이너는 Google 태그 관리자 규칙을 사용하여 런타임 시 매크로 값을 결정할 수 있는 기능을 제공하지만, 속성 목록 또는 JSON 파일은 그렇지 않습니다.

바이너리 컨테이너 파일은 Google 태그 관리자 웹 인터페이스에서 다운로드할 수 있으며 GTM-XXXX 이름 지정 규칙에 따라 기본 애플리케이션 번들에 추가해야 합니다. 여기서 파일 이름은 컨테이너 ID를 나타냅니다.

속성 목록 파일 또는 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. Google 태그 관리자 인터페이스에 지정된 TAGContainer::registerFunctionCallMacroHandler:forMacro: 및 함수 이름을 사용하여 핸들러를 등록합니다.
  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
    

맞춤 새로고침 기간 설정

현재 컨테이너 사용 기간이 12시간을 초과하면 Google 태그 관리자 SDK가 새 컨테이너를 검색하려고 시도합니다. 커스텀 컨테이너 새로고침 기간을 설정하려면 다음 예시와 같이 NSTimer를 사용합니다.

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

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

로거로 디버깅

Google 태그 관리자 SDK는 기본적으로 오류 및 경고를 로그에 출력합니다. 더 자세한 로깅을 사용 설정하면 디버깅에 도움이 될 수 있으며 다음 예와 같이 자체 Logger를 구현하면 가능합니다.

// MyAppDelegate.h
// This example assumes this file is using ARC.
// This Logger class will print out not just errors and warnings (as the default
// logger does), but also info, debug, and verbose messages.
@interface MyLogger: NSObject<TAGLogger>
@end

@implementation MyLogger
- (void)error:(NSString *)message {
  NSLog(@"Error: %@", message);
}

- (void)warning:(NSString *)message {
  NSLog(@"Warning: %@", message);
}

- (void)info:(NSString *)message {
  NSLog(@"Info: %@", message);
}

- (void)debug:(NSString *)message {
  NSLog(@"Debug: %@", message);
}

- (void)verbose:(NSString *)message {
  NSLog(@"Verbose: %@", message);
}
@end

// MyAppDelegate.m
// This example assumes this file is using ARC.
@implementation MyAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  self.tagManager = [TAGManager instance];
  
  self.tagManager.logger = [[MyLogger alloc] init];
  
  // Rest of Tag Manager and method implementation.
  return YES;
}
// Rest of app delegate implementation.
@end

또는 다음 예시와 같이 TagManager::logger::setLogLevel를 사용하여 기존 로거의 LogLevel을 설정할 수 있습니다.

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