# AdBrix WebView 이벤트 연동

WebView JavaScript 이벤트를 Native bridge를 거쳐 AdBrix SDK로 전송하는 아키텍처와 Android/iOS 설정 절차.

- 카테고리: AdBrix
- 소요 시간: 약 8분
- 난이도: 중간
- 업데이트: 2026.05.21
- 원문: /wiki/playbook/adbrix/how-to-connect-adbrix-webview-events

## 목차

- [이 문서의 목적](#purpose)
- [1단계 · 연동 구조 이해](#step-1)
- [2단계 · 필수 파일 추가](#step-2)
- [3단계 · Web 이벤트 작성](#step-3)
- [4단계 · Android bridge 등록](#step-4)
- [5단계 · iOS bridge 등록](#step-5)
- [6단계 · 테스트 이벤트 검증](#step-6)
- [7단계 · 주의사항](#step-7)
- [참고 링크](#references)
- [자주 묻는 질문](#faq)

이 문서는 WebView 안의 JavaScript 이벤트를 Native bridge를 거쳐 AdBrix SDK로 전달하는 방법만 다룹니다. 기본 SDK 설치와 초기화는 완료되어 있다고 가정하며, AppKey/SecretKey 설정이나 SDK 초기화 코드는 반복하지 않습니다.

> **이 문서 핵심**
>
> - Android/iOS 앱에서 AdBrix SDK 초기화가 먼저 끝나 있어야 합니다.
>
> - Web은 SDK를 직접 호출하지 않고 `adbrix-bridge.js`를 통해 Native bridge만 호출합니다.
>
> - 검증 이벤트는 운영 이벤트가 아니라 `webview_bridge_test` 하나로 먼저 확인합니다.

## 1단계. WebView 이벤트 연동 구조 이해

WebView 이벤트 연동은 **Web → Native bridge → AdBrix SDK → AdBrix Console** 흐름입니다. Web page는 이벤트 이름과 속성을 만들고, Native bridge가 이를 Android/iOS SDK 호출 형태로 변환합니다.

![WebView Web page에서 Native bridge와 AdBrix SDK를 거쳐 콘솔로 이벤트가 전송되는 아키텍처.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/01-architecture.png)

> **구조.** Web은 SDK를 직접 호출하지 않고 `adbrixWebBridge`라는 Native bridge로 이벤트를 넘깁니다.

| 레이어 | 책임 |
| --- | --- |
| Web | `adbrix-bridge.js`를 로드하고 `adbrixBridge.logEvent()`를 호출 |
| Native bridge | Web payload를 SDK 이벤트 API 인자로 변환 |
| AdBrix SDK | 이미 초기화된 SDK에서 이벤트를 큐에 적재하고 서버로 전송 |

## 2단계. 필수 bridge 파일 3개 추가

Web, Android, iOS 각각에 공식 bridge 파일을 추가합니다. Android 파일은 패키지 선언만 프로젝트에 맞게 바꾸고, 나머지 parser 본문은 공식 샘플을 유지하는 것을 권장합니다.

| 파일 | 넣을 위치 | 역할 | 링크 |
| --- | --- | --- | --- |
| `adbrix-bridge.js` | Web 프로젝트 | 이벤트 빌더와 bridge 호출 함수 제공 | [GitHub](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/web/adbrix-bridge.js) · [Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/web/adbrix-bridge.js) |
| `AdbrixJavascriptInterface.java` | Android Java 소스 | `@JavascriptInterface` 진입점 | [GitHub](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/android/java/app/src/main/java/com/igaworks/adbrixhybridappsample/AdbrixJavascriptInterface.java) · [Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/android/java/app/src/main/java/com/igaworks/adbrixhybridappsample/AdbrixJavascriptInterface.java) |
| `AdbrixJavascriptInterface.swift` | iOS 소스 | WKWebView payload를 SDK 호출로 변환 | [GitHub](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/ios/AdbrixHybridSampleApp/AdbrixHybridSampleApp/AdbrixJavascriptInterface.swift) · [Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/ios/AdbrixHybridSampleApp/AdbrixHybridSampleApp/AdbrixJavascriptInterface.swift) |

![프로젝트 루트 아래 web, android, ios에 필수 bridge 파일 3개가 배치된 구조.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/02-file-placement.png)

> **화면 1.** 필수 bridge 파일 배치 예시.

## 3단계. Web에서 bridge 로드와 검증 이벤트 작성

HTML에서 `adbrix-bridge.js`를 먼저 로드한 뒤 `adbrixBridge.logEvent()`를 호출합니다. 첫 검증은 운영 이벤트가 아니라 `webview_bridge_test` 같은 샘플 이벤트로 진행합니다. 운영 WebView URL에서 확인하는 것이 원칙이고, Android 로컬 asset 검증은 보조 수단으로만 사용합니다.

**index.html**
```html
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>AdBrix WebView Event Sample</title>
  <script src="adbrix-bridge.js"></script>
</head>
<body>
  <button onclick="sendBridgeTest()">Bridge Test</button>
  <script src="events.js"></script>
</body>
</html>
```

**events.js**
```javascript
function sendBridgeTest() {
  const props = ABProperty
    .customString("test_source", "webview_guide")
    .customString("test_platform", "webview")
    .build();

  adbrixBridge.logEvent("webview_bridge_test", props);
}
```

| 확인 항목 | 기준 |
| --- | --- |
| `adbrix-bridge.js` | Web page에서 정상 로드됨 |
| 검증 이벤트 | `webview_bridge_test` 이벤트를 호출함 |
| WebView URL | 앱 WebView가 접근 가능한 개발/스테이징 HTTPS URL |

![WebView 화면에서 Bridge Test 버튼을 누르면 webview_bridge_test 이벤트가 호출되는 예시.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/03-web-test-event.png)

> **화면 2.** Web 검증 이벤트 호출 예시.

## 4단계. Android WebView에 bridge 등록

`AdbrixJavascriptInterface.java`를 Android Java 소스 경로에 넣고 패키지 선언을 현재 프로젝트에 맞춥니다. 이 파일의 이벤트 진입점은 `logEvent()`이며, 내부에서 `Adbrix.getInstance().logEvent()`를 호출합니다.

**AdbrixJavascriptInterface.java**
```java
package {your.package};

@JavascriptInterface
public void logEvent(String eventName, String properties) {
    if (TextUtils.isEmpty(properties)) {
        Adbrix.getInstance().logEvent(eventName);
    } else {
        Adbrix.getInstance().logEvent(eventName, parsePropertiesJsonString(properties));
    }
}
```

WebView 생성 시 JavaScript를 켜고, bridge 이름을 정확히 `adbrixWebBridge`로 등록합니다. 이 이름은 `adbrix-bridge.js`가 찾는 고정 이름이므로 프로젝트 임의 이름으로 바꾸면 안 됩니다.

**MainActivity.kt**
```kotlin
webView = WebView(this).apply {
    settings.javaScriptEnabled = true
    webViewClient = WebViewClient()
    addJavascriptInterface(AdbrixJavascriptInterface(), "adbrixWebBridge")
}
```

> **주의**
>
> WebView에 JavaScript interface를 열면 Web content가 Native API에 접근할 수 있습니다. 검증 페이지와 운영 WebView URL은 신뢰 가능한 도메인으로 제한하고, 외부 임의 URL을 같은 WebView에 로드하지 않는 구성이 필요합니다.

![Android MainActivity에서 WebView에 adbrixWebBridge 이름으로 JavaScript interface를 등록하는 코드.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/06-android-webview-bridge.png)

> **화면 3.** Android WebView bridge 등록.

## 5단계. iOS WKWebView에 message handler 등록

`AdbrixJavascriptInterface.swift`를 iOS 소스에 추가합니다. 이 파일은 Web에서 넘어온 payload를 정규화한 뒤 SDK 이벤트 API로 전달합니다.

**AdbrixJavascriptInterface.swift**
```swift
case "logEvent":
    let eventName = payload["eventName"] as? String ?? ""
    let properties = normalizedProperties(from: payload["properties"])
    Adbrix.shared().logEvent(name: eventName, properties: properties)
```

ViewController에서 `WKScriptMessageHandler`를 채택하고, `adbrixWebBridge` 이름으로 message handler를 등록합니다. 받은 payload는 bridge 파일로 위임합니다.

**ViewController.swift**
```swift
final class ViewController: UIViewController, WKScriptMessageHandler {
    private let bridgeName = "adbrixWebBridge"
    private let adbrixJavascriptInterface = AdbrixJavascriptInterface()

    private lazy var webView: WKWebView = {
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: bridgeName)
        return WKWebView(frame: .zero, configuration: config)
    }()

    deinit {
        webView.configuration.userContentController.removeScriptMessageHandler(forName: bridgeName)
    }
}

func userContentController(_ userContentController: WKUserContentController,
                           didReceive message: WKScriptMessage) {
    guard message.name == "adbrixWebBridge" else { return }
    if let payload = message.body as? [String: Any] {
        adbrixJavascriptInterface.handleBridgeMessage(payload)
    }
}
```

![iOS WKWebViewConfiguration, WKScriptMessageHandler, AdBrix SDK로 이어지는 메시지 흐름.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/09-ios-wkwebview-flow.png)

> **화면 4.** iOS WKWebView 메시지 흐름.

> **주의**
>
> `WKUserContentController`가 handler를 strong reference로 잡기 때문에 `deinit`에서 `removeScriptMessageHandler`를 호출하세요.

## 6단계. webview_bridge_test로 bridge 경로 확인

고객사의 개발 또는 스테이징 WebView URL에 테스트 페이지를 배포하고, WebView console 로그와 Native bridge 진입 로그가 같은 실행에서 보이는지 확인합니다. 고객 운영용 Cloudflare URL 같은 공용 환경은 검증용으로 쓰지 않습니다.

### Android 에뮬레이터 확인

**Android build/install**
```bash
./gradlew :app:assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n {your.applicationId}/.MainActivity
```

**Android logcat**
```bash
adb logcat -v time DLTest:I abx.Adbrix:I '*:S'
```

**성공 로그 예시**
```text
WebView console — [WebView] → webview_bridge_test
Native bridge logEvent — webview_bridge_test
```

![Android logcat에 WebView console 로그와 Native bridge logEvent 진입 로그가 함께 보이는 화면.](/wiki-assets/playbook/how-to-connect-adbrix-webview-events/10-android-logcat-test.png)

> **화면 5.** Android logcat 기준 bridge 검증 예시.

Native bridge 진입 로그는 검증 중에만 임시로 넣고, 확인 후 제거합니다.

**임시 검증 로그**
```java
Log.i("DLTest", "Native bridge logEvent — " + eventName + ", properties=" + properties);
```

### iOS 시뮬레이터 확인

**iOS simulator build**
```bash
xcodebuild \
  -workspace YourApp.xcworkspace \
  -scheme YourApp \
  -configuration Debug \
  -sdk iphonesimulator \
  build
```

**iOS 성공 로그 예시**
```text
[Adbrix] logEvent -> webview_bridge_test
```

> **팁**
>
> iOS에서는 `print()`보다 `NSLog()`를 권장합니다. 시뮬레이터에서 Swift `print()`가 원하는 로그 스트림에 안정적으로 잡히지 않는 경우가 있습니다.

> **완료**
>
> 성공 기준은 `webview_bridge_test`가 Web console, Native bridge, SDK 이벤트 API까지 같은 실행에서 이어지는 것입니다. 확인 후 임시 로그는 제거합니다.

## 7단계. 운영 연결 전 주의사항

### bridge 이름은 고정

아래 이름은 Android와 iOS 모두 동일하게 사용합니다. 이름이 바뀌면 Web 이벤트가 Native로 들어오지 않습니다.

**Bridge name**
```text
adbrixWebBridge
```

### Android에서 iOS bridge not found 로그가 보일 수 있음

`adbrix-bridge.js`가 Android bridge와 iOS bridge를 모두 탐색하기 때문에 Android 테스트 중 iOS bridge 없음 로그가 보일 수 있습니다. 이 로그만으로 실패라고 판단하지 않습니다.

**무시 가능한 탐색 로그**
```text
iOS adbrixWebBridge not found.
```

| 실패 판단 기준 | 확인 방법 |
| --- | --- |
| `window.adbrixWebBridge` 존재 여부 | Android WebView에서 Native object가 노출되는지 확인 |
| `AdbrixJavascriptInterface.logEvent()` 진입 | 임시 로그로 eventName/properties 확인 |
| SDK 이벤트 API 호출 | `webview_bridge_test`가 SDK 로그 또는 콘솔 검증까지 이어지는지 확인 |

### 운영 이벤트로 첫 테스트하지 않기

처음 연결 확인은 샘플 이벤트 하나로만 진행합니다. bridge, SDK, 콘솔 수집이 확인된 뒤 운영 이벤트 택소노미를 연결합니다.

**첫 검증 이벤트**
```javascript
adbrixBridge.logEvent("webview_bridge_test", props);
```

## 참고 링크

- [AdBrix 공식 Hybrid App WebView Interface 가이드](https://adbrix.gitbook.io/developer-guide/platform/hybridapp/web-view-interface)
- [IGAWorks 공식 Hybrid App 샘플 저장소](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample)
- [`adbrix-bridge.js` Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/web/adbrix-bridge.js)
- [`AdbrixJavascriptInterface.java` Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/android/java/app/src/main/java/com/igaworks/adbrixhybridappsample/AdbrixJavascriptInterface.java)
- [`AdbrixJavascriptInterface.swift` Raw](https://raw.githubusercontent.com/IGAWorksDev/adbrix-hybrid-app-sample/main/ios/AdbrixHybridSampleApp/AdbrixHybridSampleApp/AdbrixJavascriptInterface.swift)

## 자주 묻는 질문

### WebView 이벤트에도 Web SDK를 설치해야 하나요?

아닙니다. 이 문서는 WebView 안의 웹 이벤트를 앱 SDK로 보내는 구조입니다. Web SDK를 별도로 설치하면 웹 플랫폼 수집과 앱 SDK 수집이 섞일 수 있으므로 목적을 분리해야 합니다.

### `adbrixWebBridge` 이름을 프로젝트 규칙에 맞게 바꿔도 되나요?

바꾸면 안 됩니다. 공식 WebView 가이드와 샘플의 `adbrix-bridge.js`가 이 이름으로 Native interface를 찾습니다.

### Android에서 `iOS adbrixWebBridge not found` 로그가 보이면 실패인가요?

그 로그만으로는 실패가 아닙니다. JS가 Android/iOS bridge를 모두 탐색하면서 생길 수 있습니다. 실제 실패 여부는 Native `logEvent()` 진입과 SDK 이벤트 로그로 판단합니다.

## Navigation

- [전체 플레이북 Markdown sitemap](/wiki/playbook/sitemap.md)

### AdBrix

- [AdBrix](/wiki/playbook/adbrix)
- [AdBrix SDK 초기화](/wiki/playbook/adbrix/how-to-initialize-adbrix-sdk)
- [AdBrix 딥링크 설정](/wiki/playbook/adbrix/how-to-set-up-adbrix-deeplinks)
- [AdBrix WebView 이벤트 연동](/wiki/playbook/adbrix/how-to-connect-adbrix-webview-events) (현재 문서)
- [AdBrix 이벤트 전송](/wiki/playbook/adbrix/how-to-send-adbrix-events)
- [AdBrix 연동 검증](/wiki/playbook/adbrix/how-to-verify-adbrix-integration)
