Skip to main content

Native Template Ad

Starting from NAM SDK version 8.7.0, you can easily implement native ads through the Native Simple Ad format without complex configurations and additional work. This guide explains the Native Template option, which is a method for loading and displaying native ads in the Native Simple Ad format.

Native Templates are designed to allow faster implementation and easier customization of native ads. Using Native Templates, you can implement even your first native ad in minutes and quickly customize the design and style with minimal code.

To effectively apply this guide, you should be familiar with implementing native ads.


Before You Start

Refer to the Native Simple Ads guide to learn how to load and display Native Simple Ads.


Add CocoaPods Dependency

Add the 'NAMSDK/AdRenderer' module along with the main NAMSDK pod.

If you are already integrating 'NAMSDK/MediationNDARich', the AdRenderer module will be included automatically.


source 'https://oss.navercorp.com/da-ssp-app-sdk/gfp-sdk-ios-podspec.git' // NAMSDK pods
source 'https://oss.navercorp.com/CocoaPods/Specs.git' // 네이버 공통 pods
source 'https://github.com/CocoaPods/Specs.git'

target 'MyApplication' do
pod 'NAMSDK'

pod 'NAMSDK/AdRenderer'
end

Template Option Settings

useNativeTemplate

Template-related options are provided through GFPNativeTemplateOptions. The useNativeTemplate property is the API used to enable or disable template application.

let nativeSimpleOption = GFPAdNativeSimpleOptions()

let templateOptions = GFPNativeTemplateOptions(useNativeTemplate: true, nativeOptions: nil)
nativeSimpleOption.templateOptions = templateOptions

Ad Rendering Settings

If you want to customize rendering when using templates, you must configure both Native and Native Simple settings. (If not configured, the default values will be applied.)

Setting adInterfaceStyle

The following sample code demonstrates how to configure the adInterfaceStyle property.

let nativeSimpleOption = GFPAdNativeSimpleOptions()

let simpleRenderingSetting = GFPNativeSimpleAdRenderingSetting()
simpleRenderingSetting.adInterfaceStyle = .system //set your style

let options = GFPAdNativeOptions()
let renderingSetting = GFPNativeAdRenderingSetting()
renderingSetting.adInterfaceStyle = .system //set your style
options.renderingSetting = renderingSetting

let templateOptions = GFPNativeTemplateOptions(useNativeTemplate: true, nativeOptions: options)

nativeSimpleOption.templateOptions = templateOptions

Others

Other settings can be customized via GFPNativeAdRenderingSetting and GFPNativeSimpleAdRenderingSetting. Please refer to the following guides: Native / Native Simple

Default Native Template

When applying default GfpNativeTemplateOptions as shown in the example above, native ads will be rendered through the default template built into the SDK as shown in the image below.

image

Custom Native Template

If you want to design the native ad layout from scratch while using Native Templates, please follow the example below.

1. Define Native Template View

Customize the view for each ad asset (title, body, etc.).

image

danger

For some APIs like DFP, the MediaView must be placed under the custom template view to enable UI click for video views.

1. Conform to GFPNativeTemplateViewProtocol

The custom template view must conform to the GFPNativeTemplateViewProtocol as shown below.

extension CustomTemplateView: GFPNativeTemplateViewProtocol {
public static func createView() -> UIView? {
let view = Bundle.main.loadNibNamed("CustomTemplateView", owner: nil)?.first
return view as? UIView
}
}

2. Assign Asset Views

Assign according to the assets defined in the custom template view. Only the assets defined in your custom template view should be assigned. If an asset is not defined, you can omit it.

extension CustomTemplateView: GFPNativeTemplateViewProtocol {
public func titleAssetView() -> UILabel? {
/* set your titleLabel */
}

public func bodyAssetView() -> UILabel? {
/* set your bodyLabel */
}

public func advertiseAssetView() -> UILabel? {
/* set your advertiserLabel */
}

public func ctaAssetView() -> UILabel? {
/* set your callToActionLabel */
}

public func adBadgeAssetView() -> UILabel? {
/* set your adBadgeLabel */
}

public func noticeAssetView() -> UILabel? {
/* set your noticeLabel */
}

public func iconContainerView() -> UIImageView? {
/* set your mediaView */
}

public func mediaContainerView() -> GFPMediaView? {
/* set your mediaView */
}

public func adChoicesContainerView() -> UIView? {
/* set your adChoicesContainerView */
}
}

3. Bind Data to Views

Override the bind method in your custom template view to map the ad assets to their corresponding views.

extension CustomTemplateView: GFPNativeTemplateViewProtocol {
public func bind(with asset: (any GFPNativeAssetProtocol)?) {
guard let asset = asset else { self.asset = nil; return }

self.asset = asset

self.titleLabel.text = asset.title
self.advertiserLabel.text = asset.advertiser
self.bodyLabel.text = asset.body
self.callToActionLabel.text = asset.callToAction
...
}
}
info
  • mediaView, iconView, adChoicesView are managed by the SDK internally, so no separate mapping is required. Just assign the assets.

4. Provide Estimated Height

Provide the estimated height of the custom template view. This height will be sent to GFPNativeSimpleAdDelegate via nativeSimpleAd:didChangeMediaViewSizeWith: when necessary.

extension CustomTemplateView: GFPNativeTemplateViewProtocol {
public func estimateHeight() -> CGFloat {
return /* set your view's height */
}
}

5. (Optional) Handle Interface Style Changes

extension CustomTemplateView: GFPNativeTemplateViewProtocol {
public func changeStyle(with isDarkMode: Bool) {
self.backgroundColor = isDarkMode ? /* set your darkMode's bgColor */ : /* set your lightMode's bgColor */
}
}

6. (Optional) Conform to GFPUserInterestDelegate

Conform to the GFPUserInterestDelegate in the custom view. The method ad:didChangeUserInterest: is called when the user's interest in the ad changes.

Call timing:

  • Interest Start: When more than 50% of the ad area is visible for 1 second, userInterest is set to true.
  • Interest End: When the ad is no longer visible, userInterest is set to false.

Example use case: You can change the color of the "Call to Action" button when the user shows interest in the ad, improving ad engagement.

extension CustomTemplateView: GFPUserInterestDelegate {
public func ad(_ ad: NSObject!, didChangeUserInterest userInterest: Bool) {
if userInterest {
UIView.animate(withDuration: 0.4) {
if let highlightBgColor = self.asset?.callToActionOption?.highlightBgColor {
self.ctaLabel.backgroundColor = highlightBgColor
} else {
self.ctaLabel.backgroundColor = GFPLabelOption.defaultHighlightBgColor
}
}
} else {
self.ctaLabel.backgroundColor = UIColor.gray
}
}
}

3. Register the Native Template

To use the custom native template view, you need to register it in GFPNativeTemplateOptions.

You can register it like this:

  • Use the method addTemplateWith:templateView:
  • Set kGFPTemplateVisualKey.defaultVisualKey as the visual key
  • Pass the custom native template view object created earlier
let templateOptions = GFPNativeTemplateOptions(useNativeTemplate: true, nativeOptions: /* set your nativeOptions */)

let customTemplateView = CustomTemplateView.createView()

if let customTemplateView = customTemplateView as? UIView & GFPNativeTemplateViewProtocol {
templateOptions.addTemplate(with: kGFPTemplateVisualKey.defaultVisualKey, templateView: customTemplateView)
}

4. Ad Request and Rendering

After completing the above steps, the ad request, rendering, and resource release processes remain the same as with regular native simple ads.

However, when using a native template, the native ad will be processed through the native simple ad format, so the following setup should not be included when building the GFPAdLoader.

If native ad options need to be configured, they should be passed through the templateOptions.

let adLoader = GFPAdLoader(unitID: "testUnitId", rootViewController: viewController, adParam: adParam)

// Native template should not include the following.
let nativeOptions = GFPAdNativeOptions()
adLoader.setNativeDelegate(self, nativeOptions: nativeOptions)

let templateOptions = GFPNativeTemplateOptions(useNativeTemplate: true, nativeOptions: nativeOptions)

let customTemplateView = CustomTemplateView.createView()

if let customTemplateView = customTemplateView as? UIView & GFPNativeTemplateViewProtocol {
templateOptions.addTemplate(with: kGFPTemplateVisualKey.defaultVisualKey, templateView: customTemplateView)
}

let nativeSimpleOptions = GFPAdNativeSimpleOptions()
nativeSimpleOptions.templateOptions = templateOptions

adLoader.setNativeSimpleDelegate(self, nativeSimpleOptions: nativeSimpleOptions)

adLoader.loadAd()