# 연동하기

본 가이드에서는 Android, iOS에서 하이브리드 앱을 연동했을 시의 가상의 시나리오를 다룹니다. HTML 뷰와 Native 뷰 간의 차이를 해소하여 HTML 뷰에서 이벤트를 기록하고 앱으로 보낼 수 있는 방법에 대해 설명합니다.

해당 방법을 적용하기 위해선 SDK 설치 및 연동 작업이 선행되어야 합니다.

* [Android 연동하기](https://adbrix.gitbook.io/developer-guide/platform/android/integration)
* [iOS 연동하기](https://adbrix.gitbook.io/developer-guide/platform/ios/integration)

더 자세히 알아보려면 [리소스 및 샘플](https://adbrix.gitbook.io/developer-guide/common/resource-and-sample)을 참조하세요.

## 자바스크립트 인터페이스

Android와 iOS 모두 web view에서 native code를 호출할 수 있는 네이티브 자바스크립트 인터페이스를 갖고 있습니다.

* Android: [JavascriptInterface](https://developer.android.com/guide/webapps/webview)
* iOS: [JavaScriptCore](https://developer.apple.com/documentation/javascriptcore)

구현은 다음 단계들로 구성됩니다.

1. Webview 또는 웹페이지를 위한 HTML 코드
2. Webview를 위한 네이티브 코드 구현

### Android

#### Android 용 HTML 코드 설정

**1. `adbrix-bridge.js` 파일을** [**다운로드**](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/web/adbrix-bridge.js) **합니다.**

**2. 다운로드 받은 `adbrix-bridge.js` 파일을 `{project}/src/main/main/assets/` 경로에 위치시킵니다.**

**3. 표시하려는 HTML 문서에 `adbrix-bridge.js`를 추가합니다.**

```html
<!DOCTYPE html>
<html>
<head>
    <title>Adbrix Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <script src="adbrix-bridge.js"></script>
</head>
```

**4. `adbrixBridge`를 사용하여 SDK를 호출합니다.**

```html
<button onclick="Login()">Login</button>
<script>
    function Login() {
        const parma = {}
        adbrixBridge.logEvent(ABEvent.LOGIN);
    }
</script>
```

**3. Android용 HTML 코드 설정이 완료되었습니다.**

#### WebView 설정

**1. `AdbrixJavascriptInterface.java` 파일을** [**다운로드**](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/android/java/app/src/main/java/com/igaworks/adbrixhybridappsample/AdbrixJavascriptInterface.java) **합니다.**

**2. 디운로드한 `AdbrixJavascriptInterface.java` 파일을 프로젝트에 추가합니다.**

**3. WebView에 `AdbrixJavascriptInterface`를 "adbrixWebBridge" 명칭으로 등록합니다.**

{% tabs %}
{% tab title="Java" %}

```java
myWebview.getSettings().setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new AdbrixJavascriptInterface(), "adbrixWebBridge");
myWebView.loadUrl("https://yourwebsite.com");
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
webView.settings.apply {
  this.javaScriptEnabled = true
}
myWebView.addJavascriptInterface(MainJsInterface(), "adbrixWebBridge")
myWebView.loadUrl("https://yourwebsite.com")
```

{% endtab %}
{% endtabs %}

**4. WebView 설정이 완료되었습니다.**

### iOS

#### iOS 용 HTML 코드 설정

**1. `adbrix-bridge.js` 파일을** [**다운로드**](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/web/adbrix-bridge.js) **합니다.**

**2. 다운로드 받은 `adbrix-bridge.js` 파일을 App Bundle에 포함시킵니다.**

**3. 표시하려는 HTML 문서에 `adbrix-bridge.js`를 추가합니다.**

```html
<!DOCTYPE html>
<html>
<head>
    <title>Adbrix Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <script src="adbrix-bridge.js"></script>
</head>
```

**4. `adbrixBridge`를 사용하여 SDK를 호출합니다.**

```html
<button onclick="Login()">Login</button>
<script>
    function Login() {
        const parma = {}
        adbrixBridge.logEvent(ABEvent.LOGIN);
    }
</script>
```

#### WKWebView 설정

**1. `AdbrixJavascriptInterface.swift` 파일을** [**다운로드**](https://github.com/IGAWorksDev/adbrix-hybrid-app-sample/blob/main/ios/AdbrixHybridSampleApp/AdbrixHybridSampleApp/AdbrixJavascriptInterface.swift) **합니다.**

**2. 디운로드한 `AdbrixJavascriptInterface.swift` 파일을 프로젝트에 추가합니다.**

**3. WKScriptMessageHandler가 연결된 ViewController 예시**

{% tabs %}
{% tab title="Swift" %}

```swift
import UIKit
import WebKit

final class ViewController: UIViewController, WKScriptMessageHandler {
    private let adbrixBridgeHandlerName = "adbrixWebBridge"
    private let adbrixJavascriptInterface = AdbrixJavascriptInterface()

    private lazy var webView: WKWebView = {
        let configuration = WKWebViewConfiguration()
        configuration.defaultWebpagePreferences.allowsContentJavaScript = true
        configuration.userContentController.add(self, name: adbrixBridgeHandlerName)
        return WKWebView(frame: .zero, configuration: configuration)
    }()

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

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        view.addSubview(webView)
        webView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])

        if let htmlURL = Bundle.main.url(forResource: "index", withExtension: "html") {
            webView.loadFileURL(htmlURL, allowingReadAccessTo: htmlURL.deletingLastPathComponent())
        }
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

        if let payload = message.body as? [String: Any] {
            if message.name == adbrixBridgeHandlerName {
                adbrixJavascriptInterface.handleBridgeMessage(payload)
            }
        } else if let jsonString = message.body as? String,
                  let data = jsonString.data(using: .utf8),
                  let dictionary = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
            if message.name == adbrixBridgeHandlerName {
                adbrixJavascriptInterface.handleBridgeMessage(dictionary)
            }
        } else {
            print("[Hybrid] Unsupported payload: \(message.body)")
        }
    }

}

```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
// ViewController.m
#import "ViewController.h"
#import <WebKit/WebKit.h>
#import "AdbrixJavascriptInterface.h"

static NSString * const kAdbrixBridgeHandlerName = @"adbrixWebBridge";

@interface ViewController () <WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) AdbrixJavascriptInterface *javascriptInterface;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    configuration.defaultWebpagePreferences.allowsContentJavaScript = YES;
    [configuration.userContentController addScriptMessageHandler:self name:kAdbrixBridgeHandlerName];

    self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
    self.webView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.webView];

    [NSLayoutConstraint activateConstraints:@[
        [self.webView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
        [self.webView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
        [self.webView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
        [self.webView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
    ]];

    self.javascriptInterface = [[AdbrixJavascriptInterface alloc] init];

    NSURL *htmlURL = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
    if (htmlURL) {
        [self.webView loadFileURL:htmlURL allowingReadAccessToURL:htmlURL.URLByDeletingLastPathComponent];
    }
}

- (void)dealloc {
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:kAdbrixBridgeHandlerName];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if (![message.name isEqualToString:kAdbrixBridgeHandlerName]) { return; }

    if ([message.body isKindOfClass:[NSDictionary class]]) {
        if ([message.name isEqualToString:kAdbrixBridgeHandlerName]) {
            [self.javascriptInterface handleBridgeMessage:(NSDictionary *)message.body];
        }
        return;
    }

    if ([message.body isKindOfClass:[NSString class]]) {
        NSData *data = [(NSString *)message.body dataUsingEncoding:NSUTF8StringEncoding];
        if (data) {
            NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            if ([dictionary isKindOfClass:[NSDictionary class]]) {
                if ([message.name isEqualToString:kAdbrixBridgeHandlerName]) {
                    [self.javascriptInterface handleBridgeMessage:dictionary];
                    return;
                }
            }
        }
    }
}

@end
```

{% endtab %}
{% endtabs %}
