imqa.document

iOS SDK 설치 가이드

IMQA iOS SDK v1.1.0 설치 및 설정 방법을 안내합니다.

TipIMQA 서비스 추가 > 앱 추가 > 키 발급

IMQA 관리 계정 로그인 후 관리 > 서비스 관리 메뉴에서 새로운 서비스를 추가합니다. 관리 > 앱 관리 메뉴에서 해당 서비스에 새로운 앱을 등록하고 발급된 앱 키를 확인합니다. 등록한 서비스 이름앱 키를 사용하여 설치하세요.


1. 개요

IMQA iOS SDK는 iOS 애플리케이션의 성능을 실시간으로 모니터링하는 솔루션입니다. 본 문서는 SDK 설치부터 초기 설정까지의 전 과정을 안내합니다.


2. 요구 사항

  • iOS 12.0 이상

3. 설치 방법

방법 1: XCFramework 직접 설치

  1. IMQA iOS SDK XCFramework 파일을 Xcode 프로젝트로 드래그하여 추가합니다.
  2. "Copy items if needed" 옵션을 체크합니다.
  3. 메인 타겟에 추가되었는지 확인합니다.

방법 2: CocoaPods

Podfile에 아래 내용을 추가한 후 의존성을 설치합니다.

use_frameworks!

target 'YourApp' do
  pod 'IMQACore'
end

터미널에서 다음 명령어를 실행합니다.

pod install

방법 3: Swift Package Manager

아래 패키지 주소를 Xcode의 Swift Package Manager에 추가합니다.

https://github.com/idlerecord/imqa-ios-sdk-spm

4. API 소개 및 설정

4-1. Options 클래스

SDK 초기화 시 사용하는 설정 옵션 클래스입니다. 각 파라미터의 역할은 아래와 같습니다.

@objc(IMQAOptions) public final class Options: NSObject {

    /// 앱 키 (IMQA 콘솔에서 발급)
    public let serviceKey: String

    /// 데이터를 전송할 Collector 주소
    public let endpoints: IMQA.Endpoints?

    /// 데이터 수집 비율 (0.0 ~ 1.0)
    /// 0.0: 수집 안 함 / 1.0: 100% 수집 (기본값: 1.0)
    public var sampleRate: Double

    /// 기기 ID(UUID)를 Collector로 전송할지 여부
    /// 기기 ID는 UUID를 생성하여 Keychain에 저장한 값입니다.
    public var isDeviceIdEnable: Bool

    /// 서비스 공간 식별자 (콘솔에서 확인)
    public var namespace: String?

    /// API 응답값으로 SDK 수집 여부를 제어합니다.
    public var sdkCollectControl: IMQA.SDKCollectControl?

    /// 사용자 터치(클릭) 자동 수집 여부
    public var tapOption: IMQA.TapOption?

    /// HTTP 요청의 Header 및 Body 수집 여부
    /// 설정하지 않으면 XHR은 수집하되 Header와 Body는 수집하지 않습니다.
    public var xhrOption: IMQA.XHROption?

    /// WebView 세션 데이터 출처 설정
    /// true: Native가 전송한 데이터 사용 (기본값)
    /// false: WebView 자체에서 생성한 데이터 사용
    /// ※ Native 앱에서는 별도 설정이 필요 없습니다.
    public var webviewOption: IMQA.WebviewOption?

    /// 배포 환경 구분
    /// 운영 환경과 테스트 환경이 동일 서버를 사용하는 경우에만 설정합니다.
    public var deployEnvironment: IMQADeployEnvironment
}

파라미터 요약표

파라미터타입설명
serviceKeyString앱 키 (필수)
endpointsIMQA.Endpoints?Collector 주소
namespaceString?서비스 공간 식별자
sampleRateDouble수집 비율 (0.0~1.0, 기본값 1.0)
isDeviceIdEnableBool기기 UUID 전송 여부
deployEnvironmentIMQADeployEnvironment운영/테스트 환경 구분
sdkCollectControlSDKCollectControl?API 응답으로 수집 제어
tapOptionTapOption?터치 이벤트 자동 수집 → 4-2 참고
xhrOptionXHROption?HTTP Header/Body 수집 → 4-3 참고
webviewOptionWebviewOption?WebView 세션 연결 방식 → 4-4 참고

4-2. TapOption 상세

IMQA.TapOption은 사용자의 탭(클릭) 이벤트 수집 방식을 설정하는 옵션 클래스입니다.

초기화

let tapOption = IMQA.TapOption(
    isAutoCapture:             Bool,
    isAutoCaputrueButtonTitle: Bool,
    isAutoCaputrueButtonId:    Bool
)

파라미터 설명

파라미터타입기본값설명
isAutoCaptureBoolfalse탭 이벤트 자동 수집 활성화 여부
isAutoCaptureButtonTitleBooltrue버튼의 Title 텍스트 수집 여부
isAutoCaptureButtonIdBooltrue버튼의 ID 수집 여부

⚠️ isAutoCapturefalse인 경우, 나머지 옵션 값과 무관하게 탭 이벤트가 수집되지 않습니다.

특정 버튼 수집 제외

button.imqa_ignore = true

사용 예시

// 자동 수집 활성화, Title 수집 비활성화, ID 수집 활성화
let tapOption = IMQA.TapOption(
    isAutoCapture:             true,
    isAutoCaputrueButtonTitle: true,
    isAutoCaputrueButtonId:    true
)

4-3. XHROption 상세

IMQA.XHROption은 앱 내 HTTP 요청의 Header 및 Body 수집 여부를 제어하는 옵션 클래스입니다.

초기화

let xhrOption = IMQA.XHROption(
    isCaptureHttpRequestHeader: Bool,
    isCaptureHttpRequestBody:   Bool
)

파라미터 설명

파라미터타입기본값설명
isCaptureHttpRequestHeaderBoolfalseHTTP 요청의 Header 수집 여부
isCaptureHttpRequestBodyBoolfalseHTTP 요청의 Body 수집 여부

⚠️ XHROption을 설정하지 않으면 XHR 요청 자체는 수집되지만, Header와 Body는 수집되지 않습니다.

⚠️ Body 수집 시 민감한 개인정보(비밀번호, 토큰 등)가 포함될 수 있으므로, 수집 대상 API를 사전에 검토하고 적용하세요.

사용 예시

// Header, Body 모두 수집
let xhrOption = IMQA.XHROption(
    isCaptureHttpRequestHeader: true,
    isCaptureHttpRequestBody:   true
)

// Header만 수집
let xhrOption = IMQA.XHROption(
    isCaptureHttpRequestHeader: true,
    isCaptureHttpRequestBody:   false
)

4-4. WebviewOption 상세

IMQA.WebviewOption은 하이브리드 앱에서 Native 세션과 WebView 세션의 연결 방식을 제어하는 옵션 클래스입니다.

초기화

let webOption = IMQA.WebviewOption(
    isSharedSession: Bool,
    isNeedWebAgent:  Bool
)

파라미터 설명

파라미터타입기본값설명
isSharedSessionBooltrueNative 세션과 WebView 세션을 통합할지 여부
isNeedWebAgentBooltrueSDK가 WebView에 WebAgent 스크립트를 자동 주입할지 여부

💡 isSharedSession: true로 설정하면 Native와 WebView의 사용자 행동이 하나의 세션으로 통합되어 추적됩니다.

💡 isNeedWebAgent: false는 WebAgent 스크립트가 이미 별도로 로드된 경우 중복 주입을 방지하기 위해 사용합니다. 순수 Native 앱에서는 별도 설정이 필요 없습니다.

💡 isNeedWebAgent: false테스트 편의를 위해 추가한 옵션이니 false로 setting하여 사용하세요.

사용 예시

// 하이브리드 앱 — 세션 통합, WebAgent 자동 주입
let webOption = IMQA.WebviewOption(
    isSharedSession: true,
    isNeedWebAgent:  true
)

// WebAgent를 별도로 로드하는 경우 — 중복 주입 방지
let webOption = IMQA.WebviewOption(
    isSharedSession: true,
    isNeedWebAgent:  false
)

4-5. 주요 API

extension IMQA {

    /// SDK 초기화
    @discardableResult
    @objc public static func setup(options: IMQA.Options,
                                   isDebug: Bool = false) -> IMQA?

    /// SDK 시작
    @objc public func start()

    /// 사용자 ID 설정
    @objc public static func setUserId(id: String?)

    /// 현재 설정된 사용자 ID 반환
    @objc public static func getUserId() -> String?

    /// 커스텀 로그 전송
    @objc public static func customLog(level: IMQA.LogLevel, message: String)

    /// Span에 커스텀 속성 추가
    /// SDK start() 이전에 설정하면 이후 생성되는 모든 Span에 자동 포함됩니다.
    @objc public static func setAttribute(key: String, value: String?)

    /// Keychain에 저장된 기기 UUID 반환
    @objc public static func getDeviceId() -> String

    /// xib 방식으로 WebView를 초기화한 경우, 스크립트를 수동으로 주입합니다.
    @objc public static func setWebviewConfiguration(
        userContentController: WKUserContentController)
}

API 요약표

API설명
IMQA.setup(options:isDebug:)SDK 초기화
.start()SDK 시작
IMQA.setUserId(id:)사용자 ID 설정
IMQA.getUserId()사용자 ID 조회
IMQA.customLog(level:message:)커스텀 로그 전송
IMQA.setAttribute(key:value:)Span에 커스텀 속성 추가
IMQA.getDeviceId()기기 UUID 조회
IMQA.setWebviewConfiguration(userContentController:)xib WebView 스크립트 수동 주입

5. SDK 초기화 예제

5-1. Swift 프로젝트 — 기본 예시

AppDelegatedidFinishLaunchingWithOptions에서 아래와 같이 초기화합니다.

import UIKit
import IMQACore

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        setupIMQASDK()
        return true
    }

    func setupIMQASDK() {
        let endpoint   = IMQA.Endpoints(collectorURL: "Collector 주소")
        let serviceKey = "서비스 키"

        // SDK 수집 여부를 API 응답으로 제어
        let sdkControl = IMQA.SDKCollectControl(remoteCollectionControlEnable: true)

        // HTTP 요청 Header, Body 수집
        let xhrOption  = IMQA.XHROption(
            isCaptureHttpRequestHeader: true,
            isCaptureHttpRequestBody:   true)

        // Native 세션 공유 (기본값: true)
        let webOption  = IMQA.WebviewOption(isSharedSession: true)

        // 터치 자동 수집, Title 비활성화, ID 활성화
        let tapOption  = IMQA.TapOption(
            isAutoCapture:             true,
            isAutoCaputrueButtonTitle: ture,
            isAutoCaputrueButtonId:    true)

        let option = IMQA.Options(
            namespace:         "namespace",
            serviceKey:        serviceKey,
            endpoints:         endpoint,
            deployEnvironment: .production,
            sampleRate:        1.0,
            isDeviceIdEnable:  true,
            sdkCollectControl: sdkControl,
            tapOption:         tapOption,
            xhrOption:         xhrOption,
            webviewOption:     webOption)

        // isDebug: true → 콘솔 로그 출력 활성화
        IMQA.setup(options: option, isDebug: true)?.start()
    }
}

5-2. Swift 프로젝트 — 실전 예시

실제 프로젝트에서는 Collector URL, 서비스 키, 네임스페이스를 별도의 매니저 클래스로 관리하는 것을 권장합니다.

func setupIMQASDK() {
    // Collector URL: 사용자가 선택한 IP를 우선 사용하고, 없으면 기본값으로 폴백
    let endpoint = IMQA.Endpoints(
        collectorURL: "collector 주소"
    )

    // API 응답으로 SDK 수집 여부 원격 제어
    let sdkControl = IMQA.SDKCollectControl(
        remoteCollectionControlEnable: true
    )

    // HTTP 요청의 Header 및 Body 수집 활성화
    let xhrOption = IMQA.XHROption(
        isCaptureHttpRequestHeader: true,
        isCaptureHttpRequestBody:   true
    )

    // Native 세션 공유, WebAgent 스크립트 중복 주입 방지
    let webOption = IMQA.WebviewOption(
        isSharedSession: true,
        isNeedWebAgent:  false
    )

    // 탭 이벤트 자동 수집 (Title 수집 비활성화, ID 수집 활성화)
    let tapOption = IMQA.TapOption(
        isAutoCapture:             true,
        isAutoCaputrueButtonTitle: true,
        isAutoCaputrueButtonId:    true
    )

    let option = IMQA.Options(
        namespace:         "namespace",
        serviceKey:        serviceKey,
        endpoints:         endpoint,
        deployEnvironment: .development,
        sampleRate:        1,
        isDeviceIdEnable:  true,
        sdkCollectControl: sdkControl,
        tapOption:         tapOption,
        xhrOption:         xhrOption,
        webviewOption:     webOption
    )

    // isDebug: true → 콘솔 로그 출력 활성화
    IMQA.setup(options: option, isDebug: true)?.start()
}

5-3. Objective-C 프로젝트

AppDelegatedidFinishLaunchingWithOptions에서 아래와 같이 초기화합니다.

#import "AppDelegate.h"
#import <IMQACore/IMQACore-Swift.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self setupIMQASDK];
    return YES;
}

- (void)setupIMQASDK {
    IMQAEndpoints *endpoint =
        [[IMQAEndpoints alloc] initWithCollectorURL:@"Collector 주소"];
    NSString *serviceKey = @"서비스 키";

    IMQASDKCollectControl *sdkControl =
        [[IMQASDKCollectControl alloc] initWithRemoteCollectionControlEnable:YES];

    IMQAXHROption *xhrOption =
        [[IMQAXHROption alloc] initWithIsCaptureHttpRequestHeader:YES
                               isCaptureHttpRequestBody:YES];

    IMQAWebviewOption *webOption =
        [[IMQAWebviewOption alloc] initWithIsSharedSession:YES];

    IMQATapOption *tapOption =
        [[IMQATapOption alloc] initWithIsAutoCapture:YES];

    IMQAOptions *option = [[IMQAOptions alloc]
        initWithNamespace:         @"namespace"
        serviceKey:                serviceKey
        endpoints:                 endpoint
        deployEnvironment:         IMQADeployEnvironmentProduction
        sampleRate:                1.0
        isDeviceIdEnable:          YES
        sdkCollectControl:         sdkControl
        tapOption:                 tapOption
        xhrOption:                 xhrOption
        webviewOption:             webOption];

    [[IMQA setupWithOptions:option isDebug:YES] start];
}

@end

6. 웹뷰 페이지 세션 연결

하이브리드 앱(WebView 사용) 안내 iOS SDK, Android SDK, WebAgent는 각 환경에 맞는 데이터를 독립적으로 수집합니다. iOS 앱의 WebView를 통해 웹 페이지를 호출하는 경우, 하나의 사용자 세션으로 통합하고 WebView 데이터를 수집하려면 아래 WKWebViewConfiguration 설정이 필요합니다.

네이티브 세션과 WebView 세션을 통합하려면 세션 공유 여부를 먼저 설정합니다. 기본값은 true(공유)입니다.

IMQA.setSharedSession(session: Bool)
초기화 방식처리 방법
코드로 WKWebView 초기화SDK가 자동으로 스크립트 주입 → 별도 설정 불필요
xib로 WKWebView 초기화IMQA.setWebviewConfiguration(userContentController:) 수동 호출
Bridge 사용IMQASDKBridge(webView:) 초기화, 화면 이탈 시 removeScriptMessageHandler() 호출

방법 1: 코드로 WKWebView를 초기화하는 경우

let config = WKWebViewConfiguration()
let view   = WKWebView(frame: .zero, configuration: config)

방법 2: xib로 WKWebView를 초기화하는 경우

let request = URLRequest(url: URL(string: "https://example.com/")!)

IMQA.setWebviewConfiguration(
    userContentController: wkWebView.configuration.userContentController
)
wkWebView.load(request)

방법 3: Bridge를 통해 WebAgent에 파라미터를 전달하는 경우

// WebViewVC에서 Bridge 초기화 시 WebView 인스턴스를 전달합니다.
self.bridge = IMQASDKBridge(webView: wkWebView)

// WebViewVC가 pop 또는 disappear될 때 반드시 연결을 해제합니다.
IMQASDKBridge.removeScriptMessageHandler()

7. Objective-C 전용 프로젝트 통합

프로젝트가 Objective-C로만 구성된 경우, Swift 런타임을 로드하기 위해 아래 절차를 따릅니다.

  1. SwiftRuntimeLoader.swift 파일을 생성합니다.
  2. "브리징 헤더를 생성하겠습니까?" 창이 나타나면 "Don't create" 를 선택합니다.
  3. 생성한 파일에 아래 내용을 추가합니다.
import Foundation
@objc class SwiftRuntimeLoader: NSObject {}

이 클래스는 Objective-C 프로젝트에서 Swift 런타임이 정상적으로 로드되도록 보장합니다.

SwiftUI 렌더 추적 추가

SwiftUI 뷰의 생명주기를 추적하려면 SceneDelegate에 아래 코드를 추가합니다.

import IMQACore

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(
            rootView: LandmarkList()
                .imqaTrackLifecycle(viewName: nil)
                .environmentObject(UserData()))
        self.window = window
        window.makeKeyAndVisible()
    }
}

8. 권장 사항

  • AppDelegatedidFinishLaunchingWithOptions에서 SDK를 초기화합니다.
  • 개발 환경과 운영 환경에 각각 적합한 Collector URL을 분리하여 사용합니다.
  • 의미 있는 사용자 ID를 설정하여 세션 추적의 정확도를 높입니다.
  • SDK 초기화 오류 발생 여부를 별도로 모니터링합니다.

9. 지원

추가 문의 사항은 IMQA 고객 지원팀으로 연락해 주시기 바랍니다.