# React Native 관련 네이티브 광고 통합

> 네이티브 광고를 React 기본 애플리케이션에 통합하여 사전 정의되거나 커스텀 템플릿으로 맞춤형 광고 경험을 제공합니다.

네이티브 광고는 앱의 다른 콘텐츠 블렌딩 커스터마이즈 수 있는 광고 형태입니다. 이렇게 하면 광고가 더 자연스럽게 표시되므로 사용자 경험 리텐션 향상됩니다.

## 필수 조건##prerequisites

레벨플레이 React 네이티브 플러그인 8.4.0 이상을 애플리케이션 올바르게 연동했는지 확인합니다. 통합은 [여기](/grow/levelplay/sdk/react/plugin-integration.md) 설명되어 있습니다.

## 레벨플레이 네이티브 광고 통합##integrate-levelplay-native-ads

React 네이티브 플러그인 사용하여 레벨플레이 네이티브 광고를 연동하는 방법에는 두 가지가 있습니다.

* **네이티브 템플릿:** 플러그인 제공하는 사전 정의된 템플릿(XML 및 XIB 파일)입니다.
* **커스텀 템플릿:** 개발자에 의해 스타일링 및 설계 커스텀 템플릿.

## 네이티브 템플릿##native-templates

네이티브 템플릿은 네이티브 광고 로직을 구현하는 사전 정의된 뷰입니다. 이 설정은 광고가 로드된 후의 조회 수를 처리하고 광고가 삭제된 후 삭제합니다.

두 가지 템플릿 옵션이 있습니다.

* 소형: 미디어 뷰가 포함되지 않는 템플릿입니다.
* 중간: 미디어 뷰를 제공하는 템플릿입니다.

일반적으로 스타일이 비슷하지만 원하는 대로 커스터마이즈 수도 있습니다.

네이티브 템플릿을 연동하려면 아래 단계를 따르십시오.

### 1단계. Create LevelPlayNativeAd Object##step-1.-create-levelplaynativead-object

광고를 LevelPlayNativeAdView 컨테이너에 로드하는 역할을 담당하는 LevelPlayNativeAd 오브젝트 생성합니다. 이 오브젝트 load, destroy와 같은 광고 메서드를 처리하고 이벤트 콜백의 광고 배치와 리스너를 정의합니다.

```js
import {
  LevelPlayNativeAd,
  type LevelPlayNativeAdListener,
  type LevelPlayAdInfo,
  type LevelPlayAdError,
} from 'Mediation

nativeAd = LevelPlayNativeAd.builder()
  .withPlacement('YOUR_PLACEMENT')
  .withListener(listener)
  .build();
```

### 2단계. 리스너 구현##step-2.-implement-the-listener

코드에 LevelPlayNativeAdListener를 구현합니다. 레벨플레이 SDK는 네이티브 광고 활동을 알려주는 여러 콜백을 작동시킵니다. SDK는 아래에 나열된 모든 이벤트를 리스너에게 알립니다.

```js
const 리스너: LevelPlayNativeAdListener = {
  /** 네이티브 광고가 클릭된 후 호출됩니다. */
  onAdClicked: (nativeAd: LevelPlayNativeAd, adInfo: LevelPlayAdInfo) => {},
  /** 네이티브 광고 노출이 기록된 후 호출됩니다. */
  onAdImpression(네이티브 광고): LevelPlayNativeAd, adInfo: LevelPlayAdInfo) => {},
  /** 네이티브 광고가 로드하려고 시도했지만 실패한 후 호출됩니다. */
  onAdLoadFailed: (nativeAd: LevelPlayNativeAd, error: LevelPlayAdError) => {},
  /** 네이티브 광고가 성공적으로 로드된 후 호출됩니다. */
  onAdLoaded: (nativeAd: LevelPlayNativeAd, adInfo: LevelPlayAdInfo) => {},
};
```

### 3단계. LevelPlayNativeAdView 생성##step-3.-create-levelplaynativeadview

로드된 네이티브 광고를 호스트 컨테이너를 정의하려면 LevelPlayNativeAdView 컴포넌트 생성합니다. 이 오브젝트 너비와 높이 또는 컨테이너의 상자 제약을 결정하여 네이티브 광고 경계를 정의합니다. 또한 다음과 같은 네이티브 광고 요소 스타일링을 처리 할 수 있습니다: 제목, 바디, 광고주 및 행동 버튼 호출.

> **Note:**
>
> 네이티브 템플릿의 기본 타입은 SMALL이며, 위젯 생성 시 템플릿 타입을 정의하여 변경할 수 있습니다.

```js
<LevelPlayNativeAdView
    style={{
       너비: 300,// 중간 타입에 권장 너비
       높이: 350 // 중간 타입의 권장 높이
    }}
    nativeAd={nativeAd} 
    templateType={LevelPlayTemplateType.Medium}
    templateStyle={[[LevelPlayNativeAdTemplateStyle] optional]}
  />
<LevelPlayNativeAdView
    style={{
       너비: 300,// 소형 타입에 권장 너비
       높이: 175 // 소형 타입에 권장 높이
    }}
    nativeAd={nativeAd} 
    templateType={LevelPlayTemplateType.Small}
    templateStyle={[[LevelPlayNativeAdTemplateStyle] optional]}
  />
```

### 3단계. 광고 로드##step-3.-load-the-ad

loadAd 메서드를 호출 네이티브 광고를 로드합니다. useEffect 후크 또는 개발자가 결정한 다른 타이밍에서 호출할 수 있습니다.

```js
nativeAd?.loadAd();
```

### 4단계. 네이티브 광고 제거##step-4.-destroy-the-native-ad

네이티브 광고를 삭제하려면 다음 메서드를 호출.

```js
nativeAd?.destroyAd();
```

삭제된 네이티브 광고는 더 이상 로드할 수 없습니다. 다시 게재하려면 광고 컨테이너 컴포넌트 다시 생성해야 합니다.

## 커스텀 템플릿 설정##custom-templates-setup

커스텀 템플릿을 사용하면 특정 요구 사항에 맞게 고유한 스타일과 기능을 디자인할 수 있습니다. 이를 통해 레이아웃과 기능을 개인화하여 고유한 사용자 경험 제공할 수 있습니다. 

이러한 템플릿은 광고 디자인에 대한 더 높은 수준의 제어가 필요한 경우에 주로 사용됩니다. Android 및 iOS 플랫폼 모두에서 구현할 수 있으며 추가 코드 구현이 필요합니다.

커스텀 템플릿을 만들려면 네이티브 코드를 작성하고 커스텀 레이아웃을 직접 개발해야 합니다. 통합하려면 아래 단계를 따르십시오.

### 1단계. NativeAdViewManager 생성##step-1.-create-nativeadviewmanager

LevelPlayNativeAdViewManager를 확장하고 로드된 광고를 커스터마이즈된 레이아웃 표시하는 클래스 Android 또는 iOS 구현입니다.

**Android**

```js
// Android Implementation
android.widget.Button 임포트
import android.widget.ImageView
import android.widget.TextView
import com.facebook.react.bridge.ReactApplicationContext
import com.ironsource.mediationsdk.ads.nativead.LevelPlayMediaView
import com.ironsource.mediationsdk.ads.nativead.LevelPlayNativeAd
import com.ironsource.mediationsdk.ads.nativead.NativeAdLayout
import com.ironsource.react_native_mediation.R
import com.ironsource.react_native_mediation.RCTLevelPlayNativeAdViewManager
class NativeAdViewManagerExample(
  reactApplicationContext: ReactApplicationContext,
  layoutId: Int
): RCTLevelPlayNativeAdViewManager(reactApplicationContext, layoutId) {
  override fun bindNativeAdToView(nativeAd: LevelPlayNativeAd?, nativeAdLayout: NativeAdLayout) {
    // Extract views
    val titleView = nativeAdLayout.findViewById<TextView>(R.id.adTitle)
    val bodyView = nativeAdLayout.findViewById<TextView>(R.id.adBody)
    val advertiserView = nativeAdLayout.findViewById<TextView>(R.id.adAdvertiser)
    val callToActionView = nativeAdLayout.findViewById<Button>(R.id.adCallToAction)
    val iconView = nativeAdLayout.findViewById<ImageView>(R.id.adAppIcon)
    val mediaView: LevelPlayMediaView? = nativeAdLayout.findViewById(R.id.adMedia)
    // Bind native ad to view
    if (nativeAd != null) {
      if (nativeAd.title != null) {
        titleView.text = nativeAd.title
        nativeAdLayout.setTitleView(titleView)
      }
      if (nativeAd.body != null) {
        bodyView.text = nativeAd.body
        nativeAdLayout.setBodyView(bodyView)
      }
      if (nativeAd.advertiser != null) {
        advertiserView.text = nativeAd.advertiser
        nativeAdLayout.setAdvertiserView(advertiserView)
      }
      if (nativeAd.callToAction != null) {
        callToActionView.text = nativeAd.callToAction
        nativeAdLayout.setCallToActionView(callToActionView)
      }
      if (nativeAd.icon != null) {
        iconView!!.setImageDrawable(nativeAd.icon!!.drawable)
        nativeAdLayout.setIconView(iconView)
      }
      if (mediaView != null) {
        nativeAdLayout.setMediaView(mediaView)
      }
      nativeAdLayout.registerNativeAdViews(nativeAd)
    }
  }
  override fun getName(): 문자열 {
    반환 "ExampleViewType"
  }
}
```

**iOS**

```js
// iOS Implementation 
/// h file
#import <Foundation/Foundation.h>
#import <LevelPlay/LevelPlay.h>
#import "RCTLevelPlayNativeAdViewManager.h"
@interface NativeAdViewManagerExample : RCTLevelPlayNativeAdViewManager <RCTLevelPlayNativeAdViewManagerDelegate>
@end
/// m file
#import "NativeAdViewManagerExample.h"
@implementation NativeAdViewManagerExample
RCT_EXPORT_MODULE(ExampleViewType) // 보기 유형 정의
- (인스턴스 타입)init
{
  self = [super initWithDelegate:self layoutName:@"MyCustomNativeAdViewTemplate"];
  return self;
}
- (void)bindNativeAdToView:(LevelPlayNativeAd *)nativeAd isNativeAdView:(ISNativeAdView *)isNativeAdView {
    // Extract views
    UILabel *titleView = isNativeAdView.adTitleView;
    UILabel *bodyView = isNativeAdView.adBodyView;
    UILabel *advertiserView = isNativeAdView.adBodyView;
    UIButton *callToActionView = isNativeAdView.adCallToActionView;
    UIImageView *iconView = isNativeAdView.adAppIcon;
    LevelPlayMediaView *mediaView = isNativeAdView.adMediaView;
    // Bind native ad to view
    if (nativeAd != nil) {
        if (nativeAd.title != nil) {
            titleView.text = nativeAd.title;
            [isNativeAdView setAdTitleView:titleView];
        }
        if (nativeAd.body != nil) {
            bodyView.text = nativeAd.body;
            [isNativeAdView setAdBodyView:bodyView];
        }
        if (nativeAd.advertiser != nil) {
            advertiserView.text = nativeAd.advertiser;
            [isNativeAdView setAdAdvertiserView:advertiserView];
        }
        if (nativeAd.callToAction != nil) {
            [callToActionView setTitle:nativeAd.callToAction forState:UIControlStateNormal];
            [isNativeAdView setAdCallToActionView:callToActionView];
        }
        if (nativeAd.icon != nil) {
            iconView.image = nativeAd.icon.image;
            [isNativeAdView setAdAppIcon:iconView];
        }
        if (mediaView != nil) {
            [isNativeAdView setAdMediaView:mediaView];
        }
        // Register native ad views with the provided native ad
        [isNativeAdView registerNativeAdViews:nativeAd];
    }
}
@end
```

커스텀 뷰 타입 문자열은 React Native 측의 LevelPlayNativeAdView 컴포넌트 지정된 viewType과 일치해야 합니다.

* Android의 경우에는 오버라이드된 getName 메서드에서 뷰 유형 문자열을 반환해야 합니다. 오버라이드 메서드 getName 뷰 유형 문자열을 반환해야 합니다.
* iOS의 경우 RCT\_EXPORT\_MODULE**에 언급된 뷰 유형 문자열을 지정해야 합니다.** 

### 2단계. Android용 NativeAdViewManager 등록##step-2.-register-your-nativeadviewmanager-for-android

LevelPlayNativeAdViewManager 클래스를 확장하는 커스텀 네이티브 광고 클래스를 생성한 후 MainApplication에 Android 클래스를 등록합니다.

> **Note:**
>
> 커스텀 뷰 타입 문자열은 React Native 측의 LevelPlayNativeAdView 컴포넌트 설정된 viewType과 일치해야 합니다. iOS의 경우 모듈 익스포트 등록 역할을 하므로 추가 설정은 필요하지 않습니다.

```js
 // Android Implementation
package com.i언소스.reactnativetester
android.app.A플리케이션 임포트
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
com.facebook.react.ReactHost 임포트
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.soloader.SoLoader
import com.unity3d.reactnative.LevelPlayMediationPackage
클래스 MainApplication : 애플리케이션(), ReactApplication {
  오버라이드 val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): 목록<ReactPackage> =
            PackageList(this).packages.apply {
              // Packages that cannot be autolinked yet can be added manually here, for example:
                add(CustomPackage())
            }
        override fun getJSMainModuleName(): String = "index"
        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
        오버라이드 val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        오버라이드 val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
      }
  오버라이드 val reactHost: ReactHost
    get() = getDefaultReactHost(applicationContext, reactNativeHost)
  오버라이드 fun onCreate() {
    super.onCreate()
    SoLoader.init(이, false)
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      load()
    }
    // Register custom view managers
    LevelPlayMediationPackage.registerViewManager("ExampleViewType") { reactContext ->
        NativeAdViewManagerExample(reactContext, R.layout.my_custom_native_ad_view)
    }
  }
}
```

* Android에서 NativeAdView 레이아웃을 구성하는 예시는 [my\_custom\_native\_ad\_view\_template.xml](https://github.com/ironsource-mobile/react-native-SDK/blob/master/example/android/app/src/main/res/layout/my_custom_native_ad_view.xml)을 참조하십시오.
* iOS에서 NativeAdView 레이아웃을 구성하는 예시는 [GitHub](https://github.com/ironsource-mobile/react-native-SDK/tree/master/example/ios)를 참조하십시오.

### 3단계. LevelPlayNativeAdView 생성##step-3.-create-levelplaynativeadview

로드된 네이티브 광고를 호스트 컨테이너를 정의하려면 LevelPlayNativeAdView 컴포넌트 생성합니다. 이 오브젝트 너비와 높이 또는 컨테이너의 상자 제약을 결정하여 네이티브 광고 경계를 정의합니다. 또한 다음과 같은 네이티브 광고 요소 스타일링을 처리 할 수 있습니다: 제목, 바디, 광고주 및 행동 버튼 호출.

> **Note:**
>
> 커스텀 템플릿을 생성할 때 viewType이 네이티브 Android 또는 iOS 섹션에 지정된 고유한 뷰 타입과 일치하는지 확인합니다.

```js
<LevelPlayNativeAdView
    style={{
      너비: 300, // 네이티브 광고 컨테이너에 권장 너비
      높이: 350, // 권장 높이(예: 중간 스타일 레이아웃)
    }}
    nativeAd={nativeAd}
    viewType="ExampleViewType"
    templateStyle={templateStyle} // 선택 사항: LevelPlayNativeAdTemplateStyle
  />
```

### 4단계. 광고 로드##step-4.-load-the-ad

loadAd 메서드를 호출 네이티브 광고를 로드합니다. useEffect 또는 개발자가 결정한 다른 타이밍에서 호출할 수 있습니다.

```js
nativeAd?.loadAd();
```

### 5단계 네이티브 광고 제거##step-5.-destroy-the-native-ad

네이티브 광고를 삭제하려면 네이티브 광고 오브젝트 destroyAd 메서드를 호출하다.

```js
nativeAd?.destroyAd();
```

삭제된 네이티브 광고는 더 이상 로드할 수 없습니다. 다시 게재하려면 광고 컨테이너 컴포넌트 다시 생성해야 합니다.
