Skip to main content

Native Ad Options

Ad Request Timeout (default: 60 seconds)

If no ad response is received within the specified time (in seconds) after the ad request, the existing request is invalidated and the adLoader:didFailWithError:responseInfo: method of GFPAdLoaderDelegate is called.

self.adLoader?.requestTimeoutInterval = ...

GFPNativeAdRenderingSetting

info

This section covers only the most commonly used options. For the full list of all options provided by GFPNativeAdRenderingSetting, refer to Native Rendering Options.

DFP adChoicesView Position Setting

The DFP adChoiceView is rendered as an overlay. Therefore, one of the four corners where the adChoicesView will be automatically inserted must be left empty. The default position of the DFP adChoicesView is the top-right corner, and it can be configured via GFPNativeAdRenderingSetting's preferredAdChoicesViewPosition.

let renderingSetting = GFPNativeAdRenderingSetting()
renderingSetting.preferredAdChoicesViewPosition = .topRightCorner

let nativeOption = GFPAdNativeOptions()
nativeOption.renderingSetting = renderingSetting
info

The Google documentation states that manually registering an adChoiceView renders it directly onto the registered view rather than as an overlay, but this does not yet work correctly. If you want the adChoiceView rendered at a position other than the top-right, this setting is required.

Using Native Ads Without a Media View

To use a native ad without a media view (for example, a native ad composed only of an icon and a title/CTA button), set hasMediaView = NO on GFPNativeAdRenderingSetting. (The default value is YES.)

danger

If the presence of a media view in the native view does not match the GFPNativeAdRenderingSetting.hasMediaView state, an error will occur at the time of native ad rendering.

let setting = GFPNativeAdRenderingSetting()
setting.hasMediaView = false

let nativeOption = GFPAdNativeOptions()
nativeOption.renderingSetting = setting

Native Ad Lazy Loading

Enabling Lazy Loading

When useLazyMediaLoading is enabled in the native rendering options, the ad load callback is called first, and the image or video resources of the media view and icon view are loaded asynchronously afterwards.

self.adLoader = GFPAdLoader(unitID: "UnitId", rootViewController: self, adParam: adParam)

let nativeOption = GFPAdNativeOptions()
nativeOptions.renderingSetting.useLazyMediaLoading = true
self.adLoader?.setNativeDelegate(self, nativeOptions: nativeOption)

self.adLoader?.delegate = self
self.adLoader?.loadAd()

With Lazy Loading, the ad load callback doesn't wait for the media to finish loading. Once the media view and icon view both load successfully, GFPNativeAdDelegate's nativeAdDidLoadMediaData(_:) is called; if either one fails, nativeAdDidFail(toLoadMediaData:) is called instead.

To help you size the media area at the ad load callback, nativeAd.mediaData may already be available, exposing preferredMediaWidth, preferredMediaHeight, and preferredHeightWithFixedWidth(_:). Image ads use the size from the ad response, and outstream native video ads derive it from the VAST media file. Treat these values as valid only when preferredMediaWidth and preferredMediaHeight are greater than 0. This early sizing is available only for standard image media and outstream native video ads.

Keep in mind that mediaData may hold only layout information at this stage. The video resource hasn't loaded yet, so access mediaData.videoController only after the main media has loaded successfully. For outstream native video, loading begins once the ad view is actually attached to the view hierarchy.

Showing a Placeholder

Show placeholders only after you set nativeAdView.nativeAd = nativeAd. By then the media view and icon view have their final size and position, so each placeholder fits its view.

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
}
}
}

Removing Placeholders

Once both the media and icon load successfully, the SDK removes the placeholders for you, so you usually don't need to call removePlaceholders() yourself.

If media loading fails, the SDK leaves the placeholders in place. To show a failure state, set a new placeholder in nativeAdDidFail(toLoadMediaData:) (nativeAdDidFailToLoadMediaData:), or call removePlaceholders() yourself.

The SDK only removes placeholders added through GFPMediaView.showPlaceholder and GFPNativeAdView.showIconPlaceholder. If you added your own custom view, you're responsible for removing it.

To run a custom effect such as a fade-out before a placeholder disappears, set placeholderWillRemoveHandler. The placeholder isn't removed until you call removeHandler, so be sure to call it once your animation finishes. This handler runs both when the SDK removes a placeholder automatically on success and when you request removal yourself.

nativeAdView.placeholderWillRemoveHandler = { placeholderView, removeHandler in
UIView.animate(withDuration: 0.25, animations: {
placeholderView.alpha = 0
}, completion: { _ in
removeHandler()
})
}

Reusable Cells

When reusing table/collection cells, we recommend calling removePlaceholders() at a reset point such as prepareForReuse so that the previous ad's placeholder does not remain.

override func prepareForReuse() {
super.prepareForReuse()

nativeAdView.removePlaceholders()
}

Async Media Loading Callbacks

Once the media view and icon view both finish loading successfully, nativeAdDidLoadMediaData(_:) is called. At that point nativeAd.mediaData is fully loaded, so you can read the final media information from it.

If either one fails, nativeAdDidFail(toLoadMediaData:) is called — once, on the first failure. The SDK doesn't clear placeholders on failure, so set a failure-state placeholder or remove it yourself.

To see which asset changed — the icon or the main media — use the didChangeMediaAssetLoadingState callback or the iconLoadingState / mediaLoadingState properties.

The SDK reports the valid impression (sc/12) to the server only after the main media loads successfully. So even if nativeAdDidFail(toLoadMediaData:) fires because the icon failed to load, the sc/12 report can still be sent as long as the main media loaded and the impression is valid.

// GFPNativeAdDelegate
func nativeAdDidLoadMediaData(_ nativeAd: GFPNativeAd) {
// The SDK removes the media/icon placeholders automatically.
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):
// Handle main media loading failure
break
case (.icon, .failed):
// Handle icon loading failure
break
default:
break
}
}
info

With Lazy Loading, the ad load callback and the media-loaded callback are separate. Other delegate callbacks (rendering, clicks, and so on) behave exactly as before, and the SDK sends the valid-impression (sc/12) report after the main media loads successfully.

GFPContentInfo

When applying a NativeNormal type ad as a Communication Ad, you must inject ContentInfo.

let adParam = GFPAdParam()
adParam.contentInfo = GFPContentInfo(
sourceType: "0001",
subtype: "menu",
sourceId: "30907206:7")