본문으로 건너뛰기

iOS 에이전트 적용

설치 전 요구사항

iOS 에이전트를 설치하기 전에 다음 요구사항을 확인하세요.

  • iOS 15.0 이상
  • Xcode 15.0 이상
  • Swift 5.9 이상 또는 Objective-C

에이전트 설치

에이전트는 세 가지 방식으로 설치할 수 있습니다.

  • Swift Package Manager를 이용한 자동 설치 방식 (권장)
  • XCFramework을 이용한 수동 설치 방식
  • 로컬 파일을 이용한 폐쇄망 설치 방식

방법 1: Swift Package Manager (SPM), 권장

  1. Xcode에서 프로젝트를 열고 File → Add Package Dependencies를 선택합니다.

  2. 패키지 URL을 입력합니다.

    https://github.com/whatap/WhatapIOSAgent-Release

  3. 버전 2.7.3 이상을 선택하고 Add Package를 클릭합니다.

방법 2: 수동 XCFramework 설치

  1. XCFramework을 다운로드합니다.

    curl -O https://repo.whatap-mobile-agent.io/uploads/2.7.3/WhatapAgent.xcframework.zip
    unzip WhatapAgent.xcframework.zip
  2. Xcode 프로젝트에 추가합니다.

    • 프로젝트 타겟 선택 → General
    • Frameworks, Libraries, and Embedded Content 섹션
    • + 버튼 → Add OtherAdd Files
    • WhatapAgent.xcframework 선택
    • Embed & Sign 설정 확인

방법 3: 로컬 파일 설치 (폐쇄망 · 사내망)

외부 저장소 접근이 제한된 환경에서는 와탭에서 제공한 zip 파일을 받아 압축 해제 후 프로젝트에 추가합니다. 이후 방법 2와 동일하게 Xcode에서 Embed & Sign으로 추가합니다.

unzip whatap-ios-agent-2.7.3.zip
mv WhatapAgent.xcframework /path/to/YourApp/

Agent 초기화

Whatap iOS SDK는 앱의 성능 데이터를 수집하기 위해 앱 시작 시점에 초기화되어야 합니다. SDK 초기화는 앱이 시작될 때 가장 먼저 실행되어야 하며, 이를 통해 앱의 전체 생명주기 동안 발생하는 이벤트를 추적할 수 있습니다.

노트

초기화 시점

  • SwiftUI: @main struct의 init() - 앱 구조체가 생성되는 시점
  • UIKit: application:willFinishLaunchingWithOptions: - didFinishLaunching보다 먼저 호출됨

초기화 시점이 늦어지면 앱 시작 초기의 중요한 성능 데이터(pre-main time, 초기 메모리 사용량 등)를 놓칠 수 있습니다.

Swift

SwiftUI 앱에서 @main struct의 init()에서 SDK를 초기화합니다.

import SwiftUI
import WhatapAgent

@main
struct MyApp: App {
init() {
// 시작 시 SDK 초기화
let agent = WhatapAgentBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setPCode(<YOUR_PCODE>)
.setServerUrl("<YOUR_SERVER_URL>")
.build()

agent.initialize()
}

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

UIKit 기반 앱에서 AppDelegateapplication:willFinishLaunchingWithOptions:에서 SDK를 초기화하는 것을 권장합니다.

import UIKit
import WhatapAgent

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication,
willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// 가장 빠른 시점에 SDK 초기화 (권장)
let agent = WhatapAgentBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setServerUrl("<YOUR_SERVER_URL>")
.setPCode(<YOUR_PCODE>)
.build()

agent.initialize()

return true
}
}

Objective-C

willFinishLaunchingWithOptions 사용 (권장)

AppDelegate.m
#import "AppDelegate.h"
@import WhatapAgent;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// didFinishLaunching보다 먼저 실행되는 SDK 초기화
WhatapAgentBuilder *builder = [[WhatapAgentBuilder alloc] init];
[builder setProjectKey:@"<YOUR_PROJECT_ACCESS_KEY>"];
[builder setServerUrl:@"<YOUR_SERVER_URL>"];
[builder setPCode:<YOUR_PCODE>];

WhatapIOSAgent *agent = [builder build];
[agent initialize];

return YES;
}
@end

Builder 옵션

전송 및 버퍼 옵션

  • setFlushInterval(_:): 10.0초
  • setQueueSize(_:): 1,000
  • setMaxDiskBytes(_:): 500 × 1024
  • setMaxDiskFiles(_:): 5

수집 및 HTTP 옵션

주의

네트워크 수집은 opt-in입니다

iOS SDK 2.7.3부터 자동 네트워크 수집의 기본값은 false입니다. 활성화하면 URLProtocol을 통해 요청이 계측되므로, 인증서 pinning·사용자 정의 URLSessionDelegate·자체 쿠키 또는 인증 헤더·HTTP/2 협상에 의존하는 앱은 영향을 먼저 확인하세요. 보안에 민감한 요청은 별도 custom URLSession으로 분리하는 것을 권장합니다.

  • setCollectScreenLoading(_:): true
  • setCollectNetwork(_:): false
  • setKeepAlive(_:): true
  • setMaxConnectionsPerHost(_:): 4

커스텀 endpoint

  • setLogServerUrl(_:): serverUrl + "/log"
  • setSpanServerUrl(_:): serverUrl + "/trace"

ScreenGroup 및 추적 옵션

  • setGroupWaitingInterval(_:): 3.0초
  • setExcludeLifecycleEventsFromScreenGroup(_:): false
  • enableMethodTracing(_:): false
  • setSamplingRate(_:): 1.0
WhatapAgentBuilder()
.setFlushInterval(120)
.setMaxDiskBytes(2 * 1024 * 1024)
.setMaxDiskFiles(5)
.setQueueSize(1000)
.setKeepAlive(true)
.setMaxConnectionsPerHost(4)
.setGroupWaitingInterval(3.0)
.build()

자동 수집 항목

  • 앱 시작 성능(Cold/Warm start, pre-main)
  • UIViewController 생명주기 기반 화면 이동 및 화면별 로딩 시간
  • 크래시·예외·시그널, CPU·메모리·배터리·열 상태

화면 추적

Swift
final class CheckoutViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
WhatapIOSAgent.trackViewController(self)
}
}

struct CheckoutView: View {
var body: some View {
ContentView()
.onAppear {
WhatapIOSAgent.trackViewController(UIHostingController(rootView: self))
}
}
}
Objective-C
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[WhatapIOSAgent trackViewController:self];
}

수동 연동

수동 Task API

결제나 이미지 로딩처럼 한 화면 안의 비동기 작업을 별도 span으로 기록할 수 있습니다.

WhatapIOSAgent.startTask("checkout", taskId: "task-001")
WhatapIOSAgent.endTask("task-001")

Method Tracing

Method Tracing은 opt-in 기능입니다. SDK 초기화 단계의 Builder에 enableMethodTracing(true)를 추가한 후 필요한 메서드 성능을 기록하세요.

  • methodStart / methodEnd
func validateBiometric(
agent: WhatapIOSAgent,
validate: () throws -> Void
) rethrows {
agent.methodStart(className: "AuthService", methodName: "validateBiometric")
defer {
agent.methodEnd(className: "AuthService", methodName: "validateBiometric")
}

try validate()
}
  • StackSpan
func charge(
agent: WhatapIOSAgent,
operation: () async throws -> Void
) async rethrows {
let stackSpan = agent.start(className: "PaymentService", methodName: "charge")

do {
try await operation()
stackSpan.end()
} catch {
stackSpan.endWithError(error)
throw error
}
}

전역 컨텍스트

ExtrasStore의 값은 모든 로그와 span에 자동으로 붙습니다.

Swift
import WhatapAgent

ExtrasStore.shared.setExtra(key: "user_id", value: userId)
ExtrasStore.shared.removeExtra(key: "user_id")
ExtrasStore.shared.clearExtras()
Objective-C
[[ExtrasStore shared] setExtraValue:userId forKey:@"user_id"];

ExtrasStore에 저장한 키는 Android 호환을 위해 전송 시 자동으로 .c suffix가 붙습니다. 예: user_iduser_id.c

ChainView
ChainView.shared.startChain(chainName: "LoginFlow")

ChainView.shared.endChain()

네트워크 & 크래시

네트워크 보안 설정

HTTPS 수집 endpoint에는 App Transport Security 예외가 필요하지 않습니다. 레거시 HTTP endpoint를 반드시 사용해야 하면 필요한 단일 도메인에만 별도 예외를 적용하고 하위 도메인이나 임의 로드는 허용하지 마세요.

크래시 리포팅

크래시는 자동으로 수집되어 다음 앱 실행 시 전송됩니다. 내장 리포터가 기본이며, PLCrashReporter 사용은 별도 라이브러리가 필요합니다.

WhatapAgentBuilder()
.useNativeCrashReporter()
.build()

WhatapAgentBuilder()
.usePLCrashReporter()
.build()

설치 확인 및 디버그

앱 실행 후 Xcode Console에서 초기화 로그를 확인하세요. 데이터가 수집되지 않으면 프로젝트 키·PCode·서버 URL, initialize() 호출, 샘플링 비율과 디스크 버퍼를 확인하세요.

#if DEBUG
WhatapLogger.isDebug = true
#endif

문제 해결 및 지원

문제 해결

SDK 초기화 실패

SDK 초기화가 실패하는 경우 다음 사항을 확인하세요.

  • 프로젝트 키와 PCode 확인: 올바른 값이 설정되었는지 확인합니다.
  • 네트워크 연결 상태 확인: 디바이스가 인터넷에 연결되어 있는지 확인합니다.
  • 서버 URL이 올바른지 확인: 제공받은 수집 서버 주소가 정확한지 확인합니다.

데이터가 수집되지 않음

모니터링 데이터가 대시보드에 표시되지 않는 경우 다음 사항을 확인하세요.

  • 샘플링 비율 확인: setSamplingRate(1.0)으로 100% 수집되도록 설정되어 있는지 확인합니다.
  • Info.plist의 네트워크 권한 확인: App Transport Security 설정이 올바른지 확인합니다.

크래시 리포트가 전송되지 않음

크래시 데이터가 수집되지 않는 경우 다음 사항을 확인하세요.

  • 앱을 재시작해야 이전 크래시가 전송됨: 크래시 발생 후 앱이 다시 실행될 때 이전 크래시 정보가 전송됩니다.
  • 시뮬레이터에서는 일부 크래시가 캡처되지 않을 수 있음: 실제 디바이스에서 테스트하는 것을 권장합니다.

지원

문제가 발생하면 다음 채널로 문의하세요.

기술 지원 요청 시 다음 정보를 함께 제공하면 더 빠른 해결이 가능합니다:

  • 프로젝트 키
  • iOS 버전
  • Xcode 버전
  • SDK 버전
  • 에러 메시지 또는 로그
  • 문제 재현 방법