import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
AdropBodyView,
AdropHeadLineView,
AdropMediaView,
AdropNativeAd,
AdropNativeAdView,
AdropProfileLogoView,
AdropProfileNameView,
} from 'adrop-ads-react-native'
import type { AdropNativeAdListener } from 'adrop-ads-react-native'
import { WebView } from 'react-native-webview'
import {
Button,
Dimensions,
ScrollView,
StyleSheet,
Text,
View,
Linking,
Platform,
} from 'react-native'
const NativeAdExample: React.FC = () => {
const [nativeAd, setNativeAd] = useState<AdropNativeAd>()
const [isLoaded, setIsLoaded] = useState(false)
const [errorCode, setErrorCode] = useState('')
// URL 열기 핸들러
const openUrl = useCallback((url: string) => {
Linking.openURL(url).catch((err) =>
console.error('Failed to open URL:', err)
)
}, [])
// 광고 이벤트 리스너
const listener = useMemo(
(): AdropNativeAdListener => ({
onAdReceived: (ad) => {
console.log('광고 수신:', ad.unitId, ad.properties)
setIsLoaded(true)
setErrorCode('')
},
onAdFailedToReceive: (_, error) => {
console.log('광고 수신 실패:', error)
setErrorCode(error)
},
onAdClicked: (ad) => {
console.log('광고 클릭:', ad.unitId)
},
onAdImpression: (ad) => {
console.log('광고 노출:', ad.unitId)
},
}),
[]
)
// 광고 초기화
const initialize = useCallback(
(unitId: string) => {
const adropNativeAd = new AdropNativeAd(unitId)
adropNativeAd.listener = listener
setNativeAd((prev) => {
prev?.destroy()
return adropNativeAd
})
setIsLoaded(false)
setErrorCode('')
},
[listener]
)
// 컴포넌트 마운트 시 광고 초기화
useEffect(() => {
initialize('YOUR_UNIT_ID')
// 컴포넌트 언마운트 시 광고 해제
return () => {
nativeAd?.destroy()
}
}, [])
// 광고 로드
const load = () => nativeAd?.load()
// 광고 뷰 렌더링
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.profileLogo} />
<AdropProfileNameView style={styles.profileName} />
</View>
{/* 광고 제목 */}
<AdropHeadLineView style={styles.headline} />
{/* 광고 본문 */}
<AdropBodyView style={styles.body} />
{/* 미디어 영역 */}
{nativeAd?.isBackfilled ? (
// 백필 광고: AdropMediaView 사용
<AdropMediaView style={styles.media} />
) : (
// 일반 광고: WebView로 렌더링
<WebView
source={{
html: nativeAd?.properties?.creative ?? '',
}}
style={styles.media}
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>
{/* 광고 뷰 */}
{adView}
{/* 에러 표시 */}
{errorCode && (
<Text style={styles.error}>
Error: {errorCode}
</Text>
)}
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
paddingVertical: 5,
paddingHorizontal: 16,
},
button: {
marginVertical: 8,
},
adContainer: {
paddingHorizontal: 16,
},
rowContainer: {
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
marginBottom: 8,
},
profileLogo: {
width: 32,
height: 32,
marginRight: 8,
borderRadius: 16,
},
profileName: {
fontSize: 14,
fontWeight: 'bold',
color: 'black',
},
headline: {
fontSize: 16,
fontWeight: 'bold',
color: 'black',
marginTop: 8,
},
body: {
fontSize: 14,
color: 'black',
marginVertical: 8,
},
media: {
width: '100%',
height: 360,
marginTop: 8,
},
error: {
color: 'red',
marginVertical: 8,
},
})
export default NativeAdExample