> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# サンプル

> React Native SDKの様々な使用例を提供します。

## 概要

このドキュメントは、Adrop React Native SDKの実際の動作例を提供します。すべてのサンプルはTypeScriptで作成されており、実際のプロジェクトですぐに使用できます。

***

## サンプルプロジェクト

GitHubで完全なサンプルプロジェクトを確認できます。

<Card title="React Nativeサンプルプロジェクト" icon="github" href="https://github.com/OpenRhapsody/adrop-ads-react-native">
  TypeScriptで作成されたReact Nativeサンプルアプリ
</Card>

***

## バナー広告サンプル

refを使用してバナー広告を手動で読み込み、エラーを処理する完全なサンプルです。

<CodeGroup>
  ```typescript BannerExample.tsx theme={null}
  import React, { useMemo, useRef, useState } from 'react'
  import {
      Button,
      Dimensions,
      Platform,
      StyleSheet,
      Text,
      View,
  } from 'react-native'
  import { AdropBanner, type AdropBannerMetadata } from 'adrop-ads-react-native'

  interface IBanner {
      load: () => void
  }

  const BannerExample: React.FC = () => {
      const bannerRef = useRef<IBanner>(null)
      const emptyBannerRef = useRef<IBanner>(null)
      const [errorCode, setErrorCode] = useState('')
      const [emptyErrorCode, setEmptyErrorCode] = useState('')

      const unit = useMemo(() => {
          // 実際のバナー広告ユニットIDを使用してください
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_320_50'
              : 'PUBLIC_TEST_UNIT_ID_320_50'
      }, [])

      const loadBanner = () => {
          bannerRef.current?.load()
          setErrorCode('')
      }

      const loadEmptyBanner = () => {
          emptyBannerRef.current?.load()
          setEmptyErrorCode('')
      }

      const onAdClicked = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner clicked', unitId, metadata)

      const onAdReceived = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner received', unitId, metadata)

      const onAdFailedToReceive = (unitId: string, error?: string) => {
          console.log('banner onAdFailedToReceive', unitId, error)
          setErrorCode(error ?? '')
      }

      const onAdImpression = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner onAdImpression', unitId, metadata)

      const onEmptyAdFailedToReceive = (_: string, error?: string) => {
          console.log('banner onAdFailedToReceive', _, error)
          setEmptyErrorCode(error ?? '')
      }

      const screenWidth = Dimensions.get('window').width

      return (
          <View style={styles.container}>
              <Button title={'バナーを読み込む (テスト広告)'} onPress={loadBanner} />

              <AdropBanner
                  ref={bannerRef}
                  unitId={unit}
                  style={{ ...styles.banner, width: screenWidth }}
                  autoLoad={false}
                  onAdClicked={onAdClicked}
                  onAdReceived={onAdReceived}
                  onAdFailedToReceive={onAdFailedToReceive}
                  onAdImpression={onAdImpression}
              />

              {errorCode && (
                  <Text style={styles.error}>エラーコード: {errorCode}</Text>
              )}

              <View style={styles.divider} />

              <Button
                  title={'バナーを読み込む (空の広告)'}
                  onPress={loadEmptyBanner}
              />

              <AdropBanner
                  ref={emptyBannerRef}
                  unitId={'TEST_UNIT_ID'}
                  style={{ ...styles.banner, width: screenWidth }}
                  autoLoad={false}
                  onAdFailedToReceive={onEmptyAdFailedToReceive}
              />

              {emptyErrorCode && (
                  <Text style={styles.error}>エラーコード: {emptyErrorCode}</Text>
              )}
          </View>
      )
  }

  export default BannerExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
          paddingHorizontal: 16,
      },
      banner: {
          width: '100%',
          height: 80,
          marginVertical: 4,
      },
      error: {
          marginVertical: 2,
          color: 'black',
          textAlign: 'center',
      },
      divider: {
          width: '100%',
          height: 1,
          marginVertical: 16,
          backgroundColor: 'black',
      },
  })
  ```
</CodeGroup>

### 主な機能

* **手動ロード**: `autoLoad={false}`に設定し、refを介して希望のタイミングで広告を読み込む
* **エラー処理**: `onAdFailedToReceive`コールバックでエラー状態を管理
* **複数のバナー**: 複数のバナーを独立して管理
* **プラットフォーム対応**: `Platform.OS`でプラットフォーム別のユニットIDを設定

***

## ネイティブ広告サンプル

WebViewと一緒にネイティブ広告を使用し、バックフィル広告も処理するサンプルです。

<CodeGroup>
  ```typescript NativeAdExample.tsx theme={null}
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
  import {
      AdropBodyView,
      AdropHeadLineView,
      AdropMediaView,
      AdropNativeAd,
      AdropNativeAdView,
      AdropProfileLogoView,
      AdropProfileNameView,
  } from 'adrop-ads-react-native'
  import { WebView } from 'react-native-webview'
  import {
      Button,
      Dimensions,
      ScrollView,
      StyleSheet,
      Text,
      View,
      Linking,
      Platform,
  } from 'react-native'
  import type { AdropNativeAdListener } from 'adrop-ads-react-native'

  const NativeAdExample: React.FC = () => {
      const [nativeAd, setNativeAd] = useState<AdropNativeAd>()
      const [isLoaded, setIsLoaded] = useState(false)
      const [errorCode, setErrorCode] = useState('')

      const disabledReset = !errorCode

      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_NATIVE'
              : 'PUBLIC_TEST_UNIT_ID_NATIVE'
      }, [])

      const openUrl = useCallback((url: string) => {
          Linking.openURL(url).catch((err) =>
              console.error('URLを開けませんでした:', err)
          )
      }, [])

      const listener = useMemo(
          (): AdropNativeAdListener => ({
              onAdReceived: (ad) => {
                  console.log(
                      `nativeAd received ${ad.unitId}`,
                      ad.properties,
                      ad.txId,
                      ad.campaignId,
                      ad.creativeId
                  )
                  setIsLoaded(true)
                  setErrorCode('')
              },
              onAdFailedToReceive: (_, error) => {
                  console.log('nativeAd onAdFailedToReceive', error)
                  setErrorCode(error)
              },
              onAdClicked: (ad) => console.log(`nativeAd clicked ${ad.unitId}`),
              onAdImpression: (ad) =>
                  console.log(`nativeAd impressed ${ad.unitId}`),
          }),
          []
      )

      const initialize = useCallback(
          (unitId: string) => {
              let adropNativeAd = new AdropNativeAd(unitId)
              adropNativeAd.listener = listener
              setNativeAd((prev) => {
                  prev?.destroy()
                  return adropNativeAd
              })
              setIsLoaded(false)
              setErrorCode('')
          },
          [listener]
      )

      useEffect(() => {
          initialize(unit)
      }, [initialize, unit])

      const load = () => nativeAd?.load()

      const resetTestAd = () => {
          initialize(unit)
      }

      const resetEmptyAd = () => {
          initialize('TEST_UNIT_ID')
      }

      const adView = useMemo(() => {
          if (!isLoaded) return null

          return (
              <AdropNativeAdView
                  nativeAd={nativeAd}
                  style={{
                      ...styles.adContainer,
                      width: Dimensions.get('window').width,
                  }}
              >
                  <View style={styles.rowContainer}>
                      <AdropProfileLogoView style={styles.icon} />
                      <AdropProfileNameView style={styles.name} />
                  </View>

                  <AdropHeadLineView style={styles.headline} />
                  <AdropBodyView style={styles.body} />

                  {!nativeAd?.isVideoAd || nativeAd?.isBackfilled ? (
                      <AdropMediaView style={styles.adStyle} />
                  ) : (
                      <WebView
                          source={{
                              html: nativeAd?.properties?.creative ?? '',
                          }}
                          style={styles.adStyle}
                          javaScriptEnabled={true}
                          mediaPlaybackRequiresUserAction={false}
                          allowsInlineMediaPlayback={true}
                          scrollEnabled={false}
                          onNavigationStateChange={(event) => {
                              // Android webviewイベント
                              if (
                                  event.url &&
                                  event.url !== 'about:blank' &&
                                  !event.url.startsWith('data:')
                              ) {
                                  openUrl(event.url)
                              }
                          }}
                          onOpenWindow={(event) => {
                              // iOS webviewイベント (window.open)
                              if (event.nativeEvent?.targetUrl) {
                                  openUrl(event.nativeEvent.targetUrl)
                              }
                          }}
                      />
                  )}
              </AdropNativeAdView>
          )
      }, [isLoaded, nativeAd, openUrl])

      return (
          <ScrollView>
              <View style={styles.container}>
                  <View style={styles.button}>
                      <Button title={'ネイティブ広告を読み込む'} onPress={load} />
                  </View>
                  <View style={styles.button}>
                      <Button
                          disabled={disabledReset}
                          title={'ネイティブ広告を初期化 (テスト広告)'}
                          onPress={resetTestAd}
                      />
                  </View>
                  {adView}
                  <Text style={styles.description}>
                      ネイティブ広告を初期化した後、読み込みボタンをクリックすると広告が表示されます。
                  </Text>
                  <View style={styles.button}>
                      <Button
                          disabled={disabledReset}
                          title={'ネイティブ広告を初期化 (空の広告)'}
                          onPress={resetEmptyAd}
                      />
                  </View>
                  <Text style={styles.description}>
                      ネイティブ広告を初期化した後、読み込みボタンをクリックするとエラーコールバックが呼び出されます。
                  </Text>
                  {errorCode && (
                      <Text style={styles.error}>エラーコード: {errorCode}</Text>
                  )}
              </View>
          </ScrollView>
      )
  }

  export default NativeAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          paddingVertical: 5,
          paddingHorizontal: 66,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
      adContainer: {
          paddingHorizontal: 16,
      },
      adStyle: {
          width: '100%',
          height: 360,
          marginBottom: 24,
      },
      icon: {
          width: 32,
          height: 32,
          marginRight: 8,
      },
      name: {
          fontSize: 14,
          fontWeight: 'bold',
          color: 'black',
      },
      headline: {
          fontSize: 16,
          fontWeight: 'bold',
          color: 'black',
      },
      body: {
          fontSize: 14,
          color: 'black',
          marginVertical: 16,
      },
      rowContainer: {
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'flex-start',
          alignItems: 'center',
          marginBottom: 8,
      },
  })
  ```
</CodeGroup>

### 主な機能

* **プロフィール情報表示**: `AdropProfileLogoView`と`AdropProfileNameView`で広告主情報を表示
* **WebView統合**: HTMLクリエイティブをWebViewでレンダリング
* **バックフィル処理**: `isBackfilled`プロパティでバックフィル広告を分岐処理
* **URL処理**: WebViewのナビゲーションイベントを処理して外部リンクを開く
* **メモリ管理**: `destroy()`メソッドで広告オブジェクトをクリーンアップ

***

## インタースティシャル広告サンプル

Hookを使用してインタースティシャル広告を実装するサンプルです。

<CodeGroup>
  ```typescript InterstitialAdExample.tsx theme={null}
  import React, { useCallback, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import { useAdropInterstitialAd } from 'adrop-ads-react-native'

  const InterstitialAdExample: React.FC = () => {
      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
              : 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
      }, [])

      const [unitId, setUnitId] = useState(unit)

      const { load, show, errorCode, reset, isLoaded, isOpened, isReady } =
          useAdropInterstitialAd(unitId)

      const disabledReset = !(isOpened || errorCode)

      const loadAd = useCallback(() => {
          if (isReady) {
              load()
          }
      }, [isReady, load])

      const resetTestAd = useCallback(() => {
          reset()
          setUnitId(unit)
      }, [reset, unit])

      const resetEmptyAd = useCallback(() => {
          reset()
          setUnitId('TEST_UNIT_ID')
      }, [reset])

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'インタースティシャル広告を読み込む'} onPress={loadAd} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'インタースティシャル広告を表示'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'インタースティシャル広告を初期化 (テスト広告)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  インタースティシャル広告を初期化した後、読み込みボタンをクリックすると広告が読み込まれます。
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'インタースティシャル広告を初期化 (空の広告)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  インタースティシャル広告を初期化した後、読み込みボタンをクリックするとエラーコールバックが呼び出されます。
              </Text>
              {errorCode && (
                  <Text style={styles.error}>エラーコード: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default InterstitialAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### 主な機能

* **Hook使用**: `useAdropInterstitialAd` Hookで簡単な状態管理
* **状態確認**: `isLoaded`、`isOpened`、`isReady`状態で広告の状態を追跡
* **エラー処理**: `errorCode`でエラー状態を確認
* **初期化**: `reset()`メソッドで広告を初期化

<Note>
  インタースティシャル広告は画面全体を覆うため、ユーザーエクスペリエンスを考慮して適切なタイミングで表示することが重要です。
</Note>

***

## リワード広告サンプル

Hookを使用してリワード広告を実装するサンプルです。

<CodeGroup>
  ```typescript RewardedAdExample.tsx theme={null}
  import React, { useCallback, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import { useAdropRewardedAd } from 'adrop-ads-react-native'

  const RewardedAdExample: React.FC = () => {
      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_REWARDED'
              : 'PUBLIC_TEST_UNIT_ID_REWARDED'
      }, [])

      const [unitId, setUnitId] = useState(unit)

      const { load, show, errorCode, reset, isLoaded, isOpened, isReady } =
          useAdropRewardedAd(unitId)

      const disabledReset = !(isOpened || errorCode)

      const loadAd = useCallback(() => {
          if (isReady) {
              load()
          }
      }, [isReady, load])

      const resetTestAd = useCallback(() => {
          reset()
          setUnitId(unit)
      }, [reset, unit])

      const resetEmptyAd = useCallback(() => {
          reset()
          setUnitId('TEST_UNIT_ID')
      }, [reset])

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'リワード広告を読み込む'} onPress={loadAd} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'リワード広告を表示'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'リワード広告を初期化 (テスト広告)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  リワード広告を初期化した後、読み込みボタンをクリックすると広告が読み込まれます。
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'リワード広告を初期化 (空の広告)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  リワード広告を初期化した後、読み込みボタンをクリックするとエラーコールバックが呼び出されます。
              </Text>
              {errorCode && (
                  <Text style={styles.error}>エラーコード: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default RewardedAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### 主な機能

* **Hook使用**: `useAdropRewardedAd` Hookで簡単な状態管理
* **報酬処理**: リスナーを介して報酬付与タイミングを確認(リスナー設定方法は[リワード広告ガイド](/ja/sdk/react-native/rewarded)を参照)
* **状態管理**: `isLoaded`、`isOpened`、`isReady`で広告の状態を確認

<Warning>
  リワード広告は、ユーザーが広告を最後まで視聴する必要があります。`onAdEarnRewardHandler`コールバックでのみ報酬を付与してください。
</Warning>

***

## ポップアップ広告サンプル

クラスを使用してポップアップ広告を実装しカスタマイズするサンプルです。

<CodeGroup>
  ```typescript PopupAdExample.tsx theme={null}
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import {
      type AdropListener,
      AdropPopupAd,
      type AdropPopupAdColors,
  } from 'adrop-ads-react-native'

  const PopupAdExample: React.FC = () => {
      const [popupAd, setPopupAd] = useState<AdropPopupAd>()
      const [isLoaded, setIsLoaded] = useState(false)
      const [isShown, setIsShown] = useState(false)
      const [errorCode, setErrorCode] = useState('')

      const disabledReset = !(errorCode || isShown)

      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM'
              : 'PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM'
      }, [])

      const listener: AdropListener = useMemo(() => {
          return {
              onAdImpression: (ad: AdropPopupAd) =>
                  console.log(
                      `popup impressed: ${ad.unitId}, ${ad.creativeId}, ${
                          ad.txId
                      }, ${ad.campaignId} ${ad.destinationURL}`
                  ),
              onAdClicked: (ad: AdropPopupAd) => {
                  console.log(
                      `popup clicked: ${ad.unitId}, ${ad.destinationURL}`
                  )
                  ad.close()
              },
              onAdReceived: (ad: AdropPopupAd) => {
                  setIsLoaded(true)
                  console.log(`popup received: ${ad.unitId}`)
                  setErrorCode('')
              },
              onAdFailedToReceive: (_: AdropPopupAd, error: any) => {
                  console.log('popup onAdFailedToReceive', error)
                  setErrorCode(error)
              },
              onAdDidDismissFullScreen: (ad: AdropPopupAd) =>
                  console.log(`popup dismissed: ${ad.unitId}`),
              onAdDidPresentFullScreen: (ad: AdropPopupAd) =>
                  console.log(`popup presented: ${ad.unitId}`),
              onAdFailedToShowFullScreen: (_: AdropPopupAd, error: any) =>
                  setErrorCode(error),
          } as AdropListener
      }, [])

      useEffect(() => {
          return () => {
              popupAd?.destroy()
          }
      }, [popupAd])

      const initialize = useCallback(
          (unitId: string) => {
              // ポップアップ広告の色カスタマイズ
              let hideForTodayTextColor = '#456'
              let backgroundColor = 'rgba(53, 255, 63, 0.3)'
              let customColors: AdropPopupAdColors = {
                  hideForTodayTextColor,
                  backgroundColor,
              }

              let adropPopupAd = new AdropPopupAd(unitId, customColors)
              adropPopupAd.listener = listener
              setPopupAd((prev) => {
                  prev?.destroy()
                  return adropPopupAd
              })
          },
          [listener]
      )

      useEffect(() => {
          initialize(unit)
      }, [initialize, unit])

      const load = () => popupAd?.load()
      const show = () => {
          popupAd?.show()
          setIsShown(true)
      }
      const resetTestAd = () => {
          initialize(unit)
          resetState()
      }

      const resetEmptyAd = () => {
          initialize('TEST_UNIT_ID')
          resetState()
      }

      const resetState = () => {
          setIsLoaded(false)
          setIsShown(false)
          setErrorCode('')
      }

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'ポップアップ広告を読み込む'} onPress={load} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'ポップアップ広告を表示'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'ポップアップ広告を初期化 (テスト広告)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  ポップアップ広告を初期化した後、読み込みボタンをクリックすると広告が読み込まれます。
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'ポップアップ広告を初期化 (空の広告)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  ポップアップ広告を初期化した後、読み込みボタンをクリックするとエラーコールバックが呼び出されます。
              </Text>
              {errorCode && (
                  <Text style={styles.error}>エラーコード: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default PopupAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### 主な機能

* **クラスベース**: `AdropPopupAd`クラスを直接使用
* **カラーカスタマイズ**: `AdropPopupAdColors`でポップアップスタイルを設定
* **クリック時に閉じる**: `onAdClicked`で`ad.close()`を呼び出し
* **メモリ管理**: `useEffect`クリーンアップで`destroy()`を呼び出し

***

## ターゲティング設定サンプル

広告ターゲティングを設定するサンプルです。

<CodeGroup>
  ```typescript TargetingExample.tsx theme={null}
  import React, { useEffect } from 'react'
  import { View } from 'react-native'
  import { AdropMetrics, AdropProperties, AdropGender } from 'adrop-ads-react-native'

  const TargetingExample: React.FC = () => {
      useEffect(() => {
          // ユーザーの性別設定
          AdropMetrics.setProperty(AdropProperties.GENDER, AdropGender.MALE)

          // ユーザーの年齢設定
          AdropMetrics.setProperty(AdropProperties.AGE, 25)

          // ユーザーの生年月日設定
          AdropMetrics.setProperty(AdropProperties.BIRTH, '19980520')

          // カスタムプロパティ設定（文字列）
          AdropMetrics.setProperty('customKey', 'customValue')

          // カスタムプロパティ設定（数値）
          AdropMetrics.setProperty('level', 10)

          // カスタムプロパティ設定（ブール値）
          AdropMetrics.setProperty('isPremium', true)

          // イベント送信
          AdropMetrics.sendEvent('purchase', {
              item_id: 'SKU-001',
              price: 29900,
              currency: 'KRW',
          })
      }, [])

      return <View />
  }

  export default TargetingExample
  ```
</CodeGroup>

### 使用可能なターゲティングプロパティ

| プロパティ                    | タイプ                           | 説明                                         |
| ------------------------ | ----------------------------- | ------------------------------------------ |
| `AdropProperties.GENDER` | `AdropGender`                 | ユーザーの性別(`MALE`、`FEMALE`、`OTHER`、`UNKNOWN`) |
| `AdropProperties.AGE`    | `number`                      | ユーザーの年齢                                    |
| `AdropProperties.BIRTH`  | `string`                      | ユーザーの生年月日(yyyyMMdd)                        |
| カスタムキー                   | `string \| number \| boolean` | アプリで定義されたカスタムプロパティ                         |

<Note>
  ターゲティングプロパティは広告リクエスト時にサーバーに送信され、より関連性の高い広告を表示するために使用されます。
</Note>

***

## エラー処理ユーティリティ

エラーコードを人間が読めるメッセージに変換するユーティリティのサンプルです。

<CodeGroup>
  ```typescript ErrorUtils.ts theme={null}
  import { AdropErrorCode } from 'adrop-ads-react-native'

  export const descriptionOf = (errorCode: string): string => {
      switch (errorCode) {
          case AdropErrorCode.network:
              return 'ネットワーク状態が不安定です'
          case AdropErrorCode.internal:
              return 'SDK内部エラーが発生しました'
          case AdropErrorCode.initialize:
              return 'Adropを先に初期化する必要があります'
          case AdropErrorCode.invalidUnit:
              return '広告ユニットIDが無効です'
          case AdropErrorCode.notTargetCountry:
              return 'サポートされていない国ではSDKを使用できません'
          case AdropErrorCode.inactive:
              return 'アクティブな広告キャンペーンがありません'
          case AdropErrorCode.adNoFill:
              return '条件に合った広告を受信できません。もう一度お試しください'
          case AdropErrorCode.adDuplicated:
              return '広告受信後は再度ロードできません'
          case AdropErrorCode.adLoading:
              return '広告リクエスト後、サーバーの応答を待っています'
          case AdropErrorCode.adEmpty:
              return '受信した広告がありません'
          case AdropErrorCode.adShown:
              return 'この広告はすでに表示されています'
          case AdropErrorCode.adHideForToday:
              return '本日はこれ以上ロードできません'
          case AdropErrorCode.adLandscapeUnsupported:
              return '横向きモードでは広告を表示できません'
          case AdropErrorCode.backfillNoFill:
              return 'バックフィル広告を受信できません'
          case AdropErrorCode.undefined:
              return '未定義のエラーです'
          default:
              return ''
      }
  }
  ```

  ```typescript 使用例 theme={null}
  import { descriptionOf } from './ErrorUtils'

  const handleAdFailedToReceive = (unitId: string, errorCode?: string) => {
      if (errorCode) {
          const errorMessage = descriptionOf(errorCode)
          console.log('エラー:', errorMessage)
          Alert.alert('広告の読み込みに失敗しました', errorMessage)
      }
  }
  ```
</CodeGroup>

### エラーコードリスト

| エラーコード                   | 説明              |
| ------------------------ | --------------- |
| `network`                | ネットワーク接続の問題     |
| `internal`               | SDK内部エラー        |
| `initialize`             | SDK初期化が必要       |
| `invalidUnit`            | 無効なユニットID       |
| `notTargetCountry`       | サポートされていない国     |
| `inactive`               | アクティブなキャンペーンがない |
| `adNoFill`               | 広告がない           |
| `adDuplicated`           | 重複ロードの試み        |
| `adLoading`              | 広告ロード中          |
| `adEmpty`                | 広告未受信           |
| `adShown`                | すでに表示された広告      |
| `adHideForToday`         | 今日は表示しないを選択     |
| `adLandscapeUnsupported` | 横向きモード非対応       |
| `backfillNoFill`         | バックフィル広告なし      |

***

## 完全な統合サンプル

すべての広告フォーマットを1つのアプリで使用するサンプルです。

<CodeGroup>
  ```typescript App.tsx theme={null}
  import React, { useEffect } from 'react'
  import { NavigationContainer } from '@react-navigation/native'
  import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
  import { Adrop } from 'adrop-ads-react-native'
  import BannerExample from './views/BannerExample'
  import NativeAdExample from './views/NativeAdExample'
  import InterstitialAdExample from './views/InterstitialAdExample'
  import RewardedAdExample from './views/RewardedAdExample'
  import PopupAdExample from './views/PopupAdExample'

  const Tab = createBottomTabNavigator()

  const App = () => {
      useEffect(() => {
          // Adrop SDK初期化
          Adrop.initialize(false) // テストモード: false、本番: true
      }, [])

      return (
          <NavigationContainer>
              <Tab.Navigator>
                  <Tab.Screen
                      name="バナー"
                      component={BannerExample}
                  />
                  <Tab.Screen
                      name="ネイティブ"
                      component={NativeAdExample}
                  />
                  <Tab.Screen
                      name="インタースティシャル"
                      component={InterstitialAdExample}
                  />
                  <Tab.Screen
                      name="リワード"
                      component={RewardedAdExample}
                  />
                  <Tab.Screen
                      name="ポップアップ"
                      component={PopupAdExample}
                  />
              </Tab.Navigator>
          </NavigationContainer>
      )
  }

  export default App
  ```
</CodeGroup>

***

## ベストプラクティス

### 1. メモリ管理

広告オブジェクトは使用後に必ずクリーンアップしてください。

```typescript theme={null}
useEffect(() => {
    const nativeAd = new AdropNativeAd('YOUR_UNIT_ID')

    return () => {
        nativeAd.destroy()
    }
}, [])
```

### 2. エラーハンドリング

すべての広告ロード時にエラー処理を実装してください。

```typescript theme={null}
const [error, setError] = useState<string | null>(null)

const handleAdFailedToReceive = (unitId: string, errorCode?: string) => {
    setError(errorCode ?? '不明なエラー')
    // エラーログ、代替コンテンツの表示など
}
```

### 3. 状態管理

Hookを使用して広告の状態を追跡してください。

```typescript theme={null}
const { isLoaded, isOpened, isReady, errorCode } = useAdropInterstitialAd(unitId)

// ボタンを無効化
<Button
    disabled={!isLoaded}
    title="広告を表示"
    onPress={show}
/>
```

### 4. プラットフォーム分岐

プラットフォームごとに異なるユニットIDを使用してください。

```typescript theme={null}
const unitId = useMemo(() => {
    return Platform.OS === 'android'
        ? 'ANDROID_UNIT_ID'
        : 'IOS_UNIT_ID'
}, [])
```

### 5. テストユニットIDの使用

開発およびテスト時には常にテストユニットIDを使用してください。

```typescript theme={null}
const isProduction = false

const unitId = isProduction
    ? 'YOUR_PRODUCTION_UNIT_ID'
    : 'PUBLIC_TEST_UNIT_ID_320_50'
```

***

## 次のステップ

<CardGroup cols={2}>
  <Card title="APIリファレンス" href="/ja/sdk/react-native/reference">
    完全なAPIドキュメントを確認
  </Card>

  <Card title="バナー広告" href="/ja/sdk/react-native/banner">
    バナー広告の詳細ガイド
  </Card>

  <Card title="ネイティブ広告" href="/ja/sdk/react-native/native">
    ネイティブ広告の詳細ガイド
  </Card>

  <Card title="インタースティシャル広告" href="/ja/sdk/react-native/interstitial">
    インタースティシャル広告の詳細ガイド
  </Card>
</CardGroup>
