네이티브 광고 옵션
광고 요청 타임아웃 (기본값 60초)
광고요청 이후 지정한 시간(초)경과 까지 광고 응답을 얻지 못하면 기존 요청이 무효화되며, GFPAdLoaderDelegate의 adLoader:didFailWithError:responseInfo: 메소드가 호출됩니다.
- Swift
- Objective-C
self.adLoader?.requestTimeoutInterval = ...
self.adLoader.requestTimeoutInterval = ...
GFPNativeAdRenderingSetting
이 섹션에서는 자주 사용되는 주요 옵션만 다룹니다. GFPNativeAdRenderingSetting이 제공하는 모든 옵션의 전체 목록은 네이티브 렌더링 옵션을 참고해 주세요.
DFP adChoicesView 위치 설정 옵션
DFP의 adChoiceView는 오버레이 형식으로 렌더링 됩니다. 따라서, adChoicesView가 자동으로 삽입될 네 귀퉁이중 한군데를 비워놓아야 합니다. DFP의 adChoicesView의 기본 위치는 오른쪽 상단 코너이며,
GFPNativeAdRenderingSetting의 preferredAdChoicesViewPosition 을 통해 설정 가능합니다.
- Swift
- Objective-C
let renderingSetting = GFPNativeAdRenderingSetting()
renderingSetting.preferredAdChoicesViewPosition = .topRightCorner
let nativeOption = GFPAdNativeOptions()
nativeOption.renderingSetting = renderingSetting
GFPNativeAdRenderingSetting *setting = [[GFPNativeAdRenderingSetting alloc] init];
setting.preferredAdChoicesViewPosition = GFPAdChoicesViewPositionTopRightCorner;
GFPAdNativeOptions *nativeOptions = [[GFPAdNativeOptions alloc] init];
nativeOptions.renderingSetting = setting;
구글 문서에는 adChoiceView를 직접 등록하면 오버레이형식이 아닌 직접 등록한 뷰에 그려진다고 되어있으나, 아직까지 정상 동작 하지 않으므로 우상단이 아닌 위치에 adChoiceView가 렌더링 되기를 원하시는 경우 이 세팅이 필요합니다.
미디어뷰가 없는 네이티브 광고 사용시
미디어뷰가 없는 네이티브 광고(예를들어 아이콘과 타이틀 클릭 버튼만으로 구성된 네이티브 광고)를 사용하려면, GFPNativeAdRenderingSetting 의 hasMediaView = NO를 설정해야 합니다. (기본값은 YES)
네이티브 뷰에 미디어 뷰 존재여부와 GFPNativeAdRenderingSetting.hasMediaView 상태가 다르면, 네이티브 광고 렌더링 시점에 오류가 발생합니다.
- Swift
- Objective-C
let setting = GFPNativeAdRenderingSetting()
setting.hasMediaView = false
let nativeOption = GFPAdNativeOptions()
nativeOption.renderingSetting = setting
GFPNativeAdRenderingSetting *setting = [[GFPNativeAdRenderingSetting alloc] init];
setting.hasMediaView = NO;
GFPAdNativeOptions *nativeOptions = [[GFPAdNativeOptions alloc] init];
nativeOptions.renderingSetting = setting;
네이티브 광고 Lazy Loading
Lazy Loading 활성화
네이티브 렌더링 옵션에서 useLazyMediaLoading 을 활성화하면 광고 로드 콜백은 먼저 호출되고, 미디어 뷰와 아이콘 뷰의 이미지 또는 동영상 리소스는 이후 비동기로 로딩됩니다.
- Swift
- Objective-C
let nativeOption = GFPAdNativeOptions()
nativeOption.renderingSetting.useLazyMediaLoading = true
adLoader.setNativeDelegate(self, nativeOptions: nativeOption)
adLoader.delegate = self
adLoader.loadAd()
GFPAdNativeOptions *nativeOptions = [[GFPAdNativeOptions alloc] init];
nativeOptions.renderingSetting.useLazyMediaLoading = YES;
[self.adLoader setNativeDelegate:self nativeOptions:nativeOptions];
self.adLoader.delegate = self;
[self.adLoader loadAd];
Lazy Loading 사용 시 앱의 광고 로드 콜백은 미디어 로딩 완료를 기다리지 않습니다. 미디어 뷰와 아이콘 뷰가 모두 성공적으로 로딩되면 GFPNativeAdDelegate 의 nativeAdDidLoadMediaData(_:) 가 호출되고, 둘 중 하나라도 실패하면 nativeAdDidFail(toLoadMediaData:) 가 호출됩니다.
광고 로드 콜백 시점에도 미디어 영역 높이를 잡을 수 있도록 nativeAd.mediaData 가 제공될 수 있습니다. 이 경우 preferredMediaWidth, preferredMediaHeight, preferredHeightWithFixedWidth(_:) 세 값을 사용할 수 있습니다. 이미지 광고는 광고 응답의 미디어 크기를 사용하고, 아웃스트림 네이티브 동영상 광고는 VAST 미디어 파일 정보를 확인해 값을 제공합니다.
preferredMediaWidth 와 preferredMediaHeight 가 0보다 큰 경우에만 유효한 크기 값으로 사용해 주세요. Lazy Loading 최초 광고 로드 콜백 시점의 사전 크기 제공은 일반 이미지 미디어와 아웃스트림 네이티브 동영상 광고를 대상으로 합니다.
단, 이 시점의 mediaData 는 레이아웃 계산용 정보일 수 있습니다. 동영상 리소스는 아직 로딩되지 않았으므로 mediaData.videoController 는 메인 미디어가 성공적으로 로딩된 이후에 참조해야 합니다. 아웃스트림 네이티브 동영상 광고는 광고 뷰가 실제 화면 계층에 attach 되는 시점에 동영상 로딩을 시작합니다.
플레이스홀더 표시
플레이스홀더는 nativeAdView.nativeAd = nativeAd 를 설정한 이후에 표시해야 합니다. 이 시점 이후에는 미디어 뷰와 아이콘 뷰의 크기와 위치가 결정되어 플레이스홀더가 각 뷰 영역에 맞게 표시됩니다.
- Swift
- Objective-C
func adLoader(_ unifiedAdLoader: GFPAdLoader!, didReceive nativeAd: GFPNativeAd!) {
nativeAd.delegate = self
nativeAdView.nativeAd = nativeAd
if nativeAd.mediaLoadingState == .loading {
nativeAdView.mediaView?.showPlaceholder { imageView in
imageView.image = UIImage(named: "my_media_placeholder")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
if nativeAd.iconLoadingState == .loading {
nativeAdView.showIconPlaceholder { imageView in
imageView.image = UIImage(named: "my_icon_placeholder")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
}
- (void)adLoader:(GFPAdLoader *)unifiedAdLoader didReceiveNativeAd:(GFPNativeAd *)nativeAd {
nativeAd.delegate = self;
self.nativeAdView.nativeAd = nativeAd;
if (nativeAd.mediaLoadingState == GFPNativeAdMediaLoadingStateLoading) {
[self.nativeAdView.mediaView showPlaceholderWith:^(UIImageView *imageView) {
imageView.image = [UIImage imageNamed:@"my_media_placeholder"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
}];
}
if (nativeAd.iconLoadingState == GFPNativeAdMediaLoadingStateLoading) {
[self.nativeAdView showIconPlaceholderWith:^(UIImageView *imageView) {
imageView.image = [UIImage imageNamed:@"my_icon_placeholder"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
}];
}
}
플레이스홀더 제거
Lazy Loading 으로 로딩된 미디어와 아이콘이 모두 성공적으로 로딩되면 SDK가 플레이스홀더를 자동으로 제거합니다. 따라서 일반적인 경우 앱에서 removePlaceholders() 를 직접 호출하지 않아도 됩니다.
미디어 로딩이 실패한 경우 SDK는 플레이스홀더를 자동으로 제거하지 않습니다. 실패 상태의 플레이스홀더를 보여주려면 nativeAdDidFail(toLoadMediaData:) 또는 nativeAdDidFailToLoadMediaData: 에서 새 플레이스홀더를 설정하거나, 필요에 따라 removePlaceholders() 를 직접 호출합니다.
SDK가 자동 제거하는 대상은 GFPMediaView.showPlaceholder 와 GFPNativeAdView.showIconPlaceholder 로 추가한 플레이스홀더입니다. 앱에서 별도 custom view를 직접 올린 경우에는 해당 custom view를 앱에서 직접 제거해야 합니다.
플레이스홀더가 제거되기 전에 페이드 아웃 같은 커스텀 효과를 적용하려면 placeholderWillRemoveHandler 를 설정합니다. 커스텀 효과가 끝난 뒤 반드시 removeHandler 를 호출해야 실제 플레이스홀더가 제거됩니다.
placeholderWillRemoveHandler 는 성공 시 SDK가 플레이스홀더를 자동 제거할 때와 앱에서 직접 플레이스홀더 제거를 요청할 때 호출됩니다.
- Swift
- Objective-C
nativeAdView.placeholderWillRemoveHandler = { placeholderView, removeHandler in
UIView.animate(withDuration: 0.25, animations: {
placeholderView.alpha = 0
}, completion: { _ in
removeHandler()
})
}
self.nativeAdView.placeholderWillRemoveHandler = ^(UIImageView *placeholderView, GFPPlaceholderRemovalHandler removeHandler) {
[UIView animateWithDuration:0.25 animations:^{
placeholderView.alpha = 0;
} completion:^(BOOL finished) {
removeHandler();
}];
};
재사용 셀 처리
테이블/컬렉션 셀을 재사용하는 경우에는 이전 광고의 플레이스홀더가 남지 않도록 prepareForReuse 등 reset 시점에 removePlaceholders() 호출을 권장합니다.
- Swift
- Objective-C
override func prepareForReuse() {
super.prepareForReuse()
nativeAdView.removePlaceholders()
}
- (void)prepareForReuse {
[super prepareForReuse];
[self.nativeAdView removePlaceholders];
}
비동기 미디어 로딩 콜백
미디어 뷰와 아이콘 뷰의 비동기 로딩이 모두 성공적으로 완료되면 nativeAdDidLoadMediaData(_:) 가 호출됩니다. 이 시점부터 실제 로드가 끝난 nativeAd.mediaData 를 기준으로 미디어 정보를 확인할 수 있습니다.
하나라도 로딩이 실패하면 nativeAdDidFail(toLoadMediaData:) 가 호출됩니다. 이 콜백은 첫 실패 시 한 번 호출됩니다. 실패 시 기존 플레이스홀더는 자동 삭제되지 않으므로, 실패 상태에 맞는 플레이스홀더를 다시 설정하거나 직접 제거해 주세요.
아이콘과 메인 미디어 중 어떤 asset의 상태가 바뀌었는지는 didChangeMediaAssetLoadingState 콜백 또는 iconLoadingState, mediaLoadingState 프로퍼티로 확인할 수 있습니다.
SDK 내부의 유효 노출(sc/12) 서버 보고는 메인 미디어 로딩 성공을 기준으로 진행됩니다. 따라서 아이콘 로딩 실패로 nativeAdDidFail(toLoadMediaData:) 가 호출된 경우에도 메인 미디어가 성공적으로 로딩되고 유효 노출 조건을 충족하면 sc/12 서버 보고가 진행될 수 있습니다.
- Swift
- Objective-C
// GFPNativeAdDelegate
func nativeAdDidLoadMediaData(_ nativeAd: GFPNativeAd) {
// SDK가 media/icon placeholder를 자동 제거합니다.
let mediaData = nativeAd.mediaData
if mediaData?.mediaType == .video {
let videoController = mediaData?.videoController
// Configure videoController if needed.
}
}
func nativeAdDidFail(toLoadMediaData nativeAd: GFPNativeAd) {
if nativeAd.mediaLoadingState == .failed {
nativeAdView.mediaView?.showPlaceholder { imageView in
imageView.image = UIImage(named: "my_fallback_media_placeholder")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
if nativeAd.iconLoadingState == .failed {
nativeAdView.showIconPlaceholder { imageView in
imageView.image = UIImage(named: "my_fallback_icon_placeholder")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
}
func nativeAd(_ nativeAd: GFPNativeAd,
didChangeMediaAssetLoadingState state: GFPNativeAdMediaLoadingState,
assetType: GFPNativeAdMediaAssetType) {
switch (assetType, state) {
case (.media, .failed):
// 메인 미디어 로딩 실패 처리
break
case (.icon, .failed):
// 아이콘 로딩 실패 처리
break
default:
break
}
}
// GFPNativeAdDelegate
- (void)nativeAdDidLoadMediaData:(GFPNativeAd *)nativeAd {
// SDK가 media/icon placeholder를 자동 제거합니다.
GFPMediaData *mediaData = nativeAd.mediaData;
if (mediaData.mediaType == GFPMediaTypeVideo) {
GFPVideoController *videoController = mediaData.videoController;
// Configure videoController if needed.
}
}
- (void)nativeAdDidFailToLoadMediaData:(GFPNativeAd *)nativeAd {
if (nativeAd.mediaLoadingState == GFPNativeAdMediaLoadingStateFailed) {
[self.nativeAdView.mediaView showPlaceholderWith:^(UIImageView *imageView) {
imageView.image = [UIImage imageNamed:@"my_fallback_media_placeholder"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
}];
}
if (nativeAd.iconLoadingState == GFPNativeAdMediaLoadingStateFailed) {
[self.nativeAdView showIconPlaceholderWith:^(UIImageView *imageView) {
imageView.image = [UIImage imageNamed:@"my_fallback_icon_placeholder"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
}];
}
}
- (void)nativeAd:(GFPNativeAd *)nativeAd
didChangeMediaAssetLoadingState:(GFPNativeAdMediaLoadingState)state
assetType:(GFPNativeAdMediaAssetType)assetType {
if (assetType == GFPNativeAdMediaAssetTypeMedia && state == GFPNativeAdMediaLoadingStateFailed) {
// 메인 미디어 로딩 실패 처리
} else if (assetType == GFPNativeAdMediaAssetTypeIcon && state == GFPNativeAdMediaLoadingStateFailed) {
// 아이콘 로딩 실패 처리
}
}
Lazy Loading 사용 시 광고 로드 콜백과 미디어 로딩 완료 콜백은 분리됩니다. 광고 렌더링, 클릭 등 기존 delegate 콜백은 동일하게 동작하며, SDK 내부의 유효 노출(sc/12) 서버 보고는 메인 미디어 로딩 성공 이후 진행됩니다.
GFPContentInfo
NativeNormal 타입 광고를 Communication Ad 으로 적용할 경우, ContentInfo 를 주입해야합니다.
- Swift
- Objective-C
let adParam = GFPAdParam()
adParam.contentInfo = GFPContentInfo(
sourceType: “0001”,
subtype: “menu”,
sourceId: “30907206:7”)
GFPContentInfo *contentInfo = [[GFPContentInfo alloc] initWithSourceType:@"0001" subtype:@"menu" sourceId:@"30907206:7"];
adParam.contentInfo = contentInfo;