Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

Implementation for native video ads

funakoshi-dev edited this page Mar 6, 2023 · 13 revisions

Preparation

Please refer to the link below if you have not created ad spot or downloaded the SDK.

Integrating the SDK

If you have not added the SDK into the Project, please add it by the following methods.

Native Video Ad Implementation

Load native video ad

Create native ad loader

First, generate the instance of NADNativeVideoLoader. Please set your spotID & apiKey to parameters, and also set click action types optionally. You can select these options for click action.

  • NADNativeVideoClickActionFullScreen: Play to full-screen on video clicked. This is default value.
  • NADNativeVideoClickActionLP: Open ad content on video clicked.
Swift
import NendAd
...

private let videoAdLoader = NADNativeVideoLoader(spotID: spotID, apiKey: "apiKey", clickAction: .fullScreen)
Objective-C
@import NendAd;
...

@property (nonatomic, strong) NADNativeVideoLoader *videoAdLoader;
...

self.videoAdLoader = [[NADNativeVideoLoader alloc] initWithSpotID:spotID apiKey:@"apiKey" clickAction:NADNativeVideoClickActionLP];

Optionals

You can implement these options for NADNativeVideoLoader if necessary.

Load fallback ad

If you can not display native video for reasons such as out of stock, you can display native ads instead. In order to use this function, you need to register ad space of native ads separately on the management screen.

Swift
videoAdLoader.setFillerStaticNativeAdID(spotID, apiKey: "apiKey")
Objective-C
[self.videoAdLoader setFillerStaticNativeAdID:spotID apiKey:@"apiKey"];

Loading ad

Then, load the ad using loadAdWithCompletionHandler: method.

- (void)loadAdWithCompletionHandler:(void(^)(NADNativeVideo * _Nullable, NSError * _Nullable))handler;
Swift
videoAdLoader.loadAd { (ad, error) in
    if let videoAd = ad {
        // success
    } else {
        // failure
    }
}
Objective-C
[self.videoAdLoader loadAdWithCompletionHandler:^(NADNativeVideo * _Nullable videoAd, NSError * _Nullable error) {
    if (videoAd) {
        // success
    } else {
        // failure
    }
}];

Error code at load failure is as follows.

Code Description
204 No delivery ads
400 BAD request
5XX Server error
600 Error in SDK
601 Ad download failed
603 Invalid network
604 Advertisement acquisition network error (timeout etc.)
605 Received invalid response data

In case of fallback ad option, please check video contents is included via hasVideo method of NADNativeVideo before showing native video ad.
If you show fallback ad, please check below.

Swift
videoAdLoader.loadAd { (ad, error) in
    if let videoAd = ad {
        // success
        if videoAd.hasVideo {
            // a native video ads can be displayed.
        } else if let staticNativeAd = videoAd.staticNativeAd {
            // staticNativeAd is `NADNative` class.
            ...
        }
    } else {
        // failure
    }
}
Objective-C
[self.videoAdLoader loadAdWithCompletionHandler:^(NADNativeVideo * _Nullable videoAd, NSError * _Nullable error) {
    if (videoAd) {
        // success
        if (videoAd.hasVideo) {
            // a native video ads can be displayed.
        } else {
            NADNative *staticNativeAd = videoAd.staticNativeAd;
            ...
        }
    } else {
        // failure
    }
}];

Show native video ad

Using NADNativeVideo that loaded previous term.
You should display an ad explicitly to denote that the content is an ads.

Required items

Required item to display native video ad.

Video

Using NADNativeVideoView class for displaying video. NADNativeVideoView is implemented from UIView class. So you can layout like as UIView.

Set UIViewController as presentingViewController via rootViewController property of NADNativeVideoView for FullScreen-playing that shown modal transition when initializing.

- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;
- (instancetype)initWithFrame:(CGRect)frame rootViewController:(UIViewController *)rootViewController;
Swift
class YourViewController: UIViewController {
    ...
    let yourVideoView = NADNativeVideoView(rootViewController: self)
    ...
}
Objective-C
@implementation YourViewController
    ...
    NADNativeVideoView *yourVideoView = [[NADNativeVideoView alloc] initWithRootViewController:self];
    ...
@end

If you use Interface Builder, set the relation to the rootViewController property.
Official Guide https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ConnectTheUIToCode.html

@property (readwrite, nonatomic, weak, nullable) IBOutlet UIViewController *rootViewController;

nendSDK uses rootViewController information for following display orientation, rotation, and state of viewing status-bar.

Relate NADNativeVideo to NADNativeVideoView, then nendSDK prepare playing video.

NS_ASSUME_NONNULL_BEGIN
@interface NADNativeVideoView : UIView
...
@property (readwrite, nonatomic, strong) NADNativeVideo *videoAd;
...
@end
NS_ASSUME_NONNULL_END
Swift
@IBOutlet weak var videoView: NADNativeVideoView!
...

videoView.videoAd = videoAd
Objective-C
@property (nonatomic, weak) IBOutlet NADNativeVideoView *videoView;
...

self.videoView.videoAd = videoAd;

After change to Over 50% of NADNativeVideoView is displaying, video will start playing. Or also change to Less than 50% of NADNativeVideoView is displaying, video will be pausing.

And you can know video orientation from orientation property of NADNativeVideo.

extern const NSInteger kNADVideoOrientationVertical;
extern const NSInteger kNADVideoOrientationHorizontal;
...

@property (readonly, nonatomic) NSInteger orientation;
  • kNADVideoOrientationVertical: aspect ratio -> 9:16
  • kNADVideoOrientationHorizontal: aspect ratio -> 16:9

Optional items

Optional item to display native video ad.

Logo image

Get value from logoImage property of NADNativeVideo.

@property (readonly, nonatomic, strong, nullable) UIImage *logoImage;

Sometimes property will be nil: e.g. downloading of logo image is failed.
If you need logo image while property is nil, please retry downloading viadownloadLogoImageWithCompletionHandler: method of NADNativeVideo.

Swift
videoAd.downloadLogoImage { image in
    if let logoImage = image {
        // success
    }
}
Objective-C
[videoAd downloadLogoImageWithCompletionHandler:^(UIImage * _Nullable image) {
    if (image) {
        // success
    }
}];

Or you can get URL of logo image via logoImageUrl property of NADNativeVideo. So, you can also implement download function as your app.

@property (readonly, nonatomic, copy, nullable) NSString *logoImageUrl;

Title : promotion name

Get value from title property of NADNativeVideo.

@property (readonly, nonatomic, copy, nullable) NSString *title;

Advertiser name

Get value from advertiserName property of NADNativeVideo.

@property (readonly, nonatomic, copy, nullable) NSString *advertiserName;

Explanation

Get value from explanation property of NADNativeVideo.

@property (readonly, nonatomic, copy, nullable) NSString *explanation;

Rating

Get value from userRating property of NADNativeVideo.

@property (readonly, nonatomic) CGFloat userRating;

This is only using for App Store ad contents, others will be -1.0.

Rating count

Get value from userRatingCount property of NADNativeVideo.

@property (readonly, nonatomic) NSInteger userRatingCount;

This is only using for App Store ad contents, others will be -1.

Call To Action

Get value from callToAction property of NADNativeVideo.

@property (readonly, nonatomic, copy, nullable) NSString *callToAction;

Implementation example

This examples created layout by Interface Builder, relate via IBOutlet to ad information.

Swift
import UIKit
import Foundation
import NendAd

class ViewController: UIViewController {

    @IBOutlet private weak var videoView: NADNativeVideoView!
    @IBOutlet private weak var titleLabel: UILabel!
    @IBOutlet private weak var descriptionLabel: UILabel!
    @IBOutlet private weak var advertiserNameLabel: UILabel!
    @IBOutlet private weak var userRatingLabel: UILabel!
    @IBOutlet private weak var userRatingCountLabel: UILabel!
    @IBOutlet private weak var logoImageView: UIImageView!
    @IBOutlet private weak var callToActionButton: UIButton!

    private let loader = NADNativeVideoLoader(spotID: spotID, apiKey: "apiKey")

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        loader.loadAd { [weak self] (ad, error) in
            guard let `self` = self else { return }
            if let videoAd = ad {
                self.videoView.videoAd = videoAd

                self.titleLabel.text = videoAd.title
                self.descriptionLabel.text = videoAd.explanation
                self.advertiserNameLabel.text = videoAd.advertiserName
                self.callToActionButton.setTitle(videoAd.callToAction, for: .normal)

                if videoAd.userRating != -1.0 && videoAd.userRatingCount != -1 {
                    self.userRatingLabel.text = "\(videoAd.userRating)"
                    self.userRatingCountLabel.text = "\(videoAd.userRatingCount)"
                } else {
                    // not app ads
                }

                if let logoImage = videoAd.logoImage {
                    self.logoImageView.image = logoImage
                } else {
                    videoAd.downloadLogoImage { image in
                        if let logoImage = image {
                            self.logoImageView.image = logoImage
                        }
                    }
                }
            } else {
                print("error: \(error!)")
            }
        }
    }

}
Objective-C
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@import NendAd;

@interface ViewController : UIViewController
@end

...

@interface ViewController ()

@property (nonatomic, weak) IBOutlet NADNativeVideoView *videoView;
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *descriptionLabel;
@property (nonatomic, weak) IBOutlet UILabel *advertiserNameLabel;
@property (nonatomic, weak) IBOutlet UILabel *userRatingLabel;
@property (nonatomic, weak) IBOutlet UILabel *userRatingCountLabel;
@property (nonatomic, weak) IBOutlet UIImageView *logoImageView;
@property (nonatomic, weak) IBOutlet UIButton *callToActionButton;
@property (nonatomic, strong) NADNativeVideoLoader *loader;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.loader = [[NADNativeVideoLoader alloc] initWithSpotID:spotID apiKey:@"apiKey"];

    __weak typeof(self) weakSelf = self;
    [self.adLoader loadAdWithCompletionHandler:^(NADNativeVideo * _Nullable ad, NSError * _Nullable error) {
        if (weakSelf) {
            if (ad) {
                weakSelf.videoView.videoAd = ad;

                weakSelf.titleLabel.text = ad.title;
                weakSelf.descriptionLabel.text = ad.explanation;
                weakSelf.advertiserNameLabel.text = ad.advertiserName;

                if (ad.userRating != -1.0 && ad.userRatingCount != -1) {
                    weakSelf.userRatingLabel.text = [NSString stringWithFormat:@"%f", ad.userRating];
                    weakSelf.userRatingCountLabel.text = [NSString stringWithFormat:@"%ld", (long)ad.userRatingCount];
                }

                if (ad.logoImage) {
                    weakSelf.logoImageView.image = ad.logoImage;
                } else {
                    [ad downloadLogoImageWithCompletionHandler:^(UIImage * _Nullable image) {
                        if (weakSelf && image) {
                            weakSelf.logoImageView.image = image;
                        }
                    }];
                }
            }
        } else {
            NSLog(@"error: %@", error);
        }
    }];
}

@end

Optionals

Detecting Event

You can detect event of native video ad via below delegate methods.

NADNativeVideo

@protocol NADNativeVideoDelegate <NSObject>

@optional
// notified when the ad imp is sent.
- (void)nadNativeVideoDidImpression:(NADNativeVideo *)ad;
// notified when the ad is clicked.
- (void)nadNativeVideoDidClickAd:(NADNativeVideo *)ad;
// notified when optout page will show.
- (void)nadNativeVideoDidClickInformation:(NADNativeVideo *)ad;

@end
Swift
class ViewController: UIViewController {

    private let loader = NADNativeVideoLoader(spotID: spotID, apiKey: "apiKey")

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        loader.loadAd { [weak self] (ad, error) in
            guard let `self` = self else { return }
            if let videoAd = ad {
                videoAd.delegate = self
                ...
            }
        }
    }

}

// MARK: - NADNativeVideoDelegate

extension ViewController: NADNativeVideoDelegate {

    func nadNativeVideoDidImpression(_ ad: NADNativeVideo) {
        print("\(#function)")
    }

    func nadNativeVideoDidClickAd(_ ad: NADNativeVideo) {
        print("\(#function)")
    }

    func nadNativeVideoDidClickInformation(_ ad: NADNativeVideo) {
        print("\(#function)")
    }

}
Objective-C
@interface ViewController () <NADNativeVideoDelegate>

@property (nonatomic, strong) NADNativeVideoLoader *loader;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.loader = [[NADNativeVideoLoader alloc] initWithSpotID:spotID apiKey:@"apiKey"];

    __weak typeof(self) weakSelf = self;
    [self.loader loadAdWithCompletionHandler:^(NADNativeVideo * _Nullable ad, NSError * _Nullable error) {
        if (weakSelf && ad) {
            ad.delegate = weakSelf;
            ...
        }
    }];
}

#pragma mark - NADNativeVideoDelegate

- (void)nadNativeVideoDidImpression:(NADNativeVideo *)ad
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoDidClickAd:(NADNativeVideo *)ad
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoDidClickInformation:(NADNativeVideo *)ad
{
    NSLog(@"%s", __FUNCTION__);
}

@end

NADNativeVideoView

@protocol NADNativeVideoViewDelegate <NSObject>

@optional
// notified when the video is started.
- (void)nadNativeVideoViewDidStartPlay:(NADNativeVideoView *)videoView;
// notified when the video is stopped.
- (void)nadNativeVideoViewDidStopPlay:(NADNativeVideoView *)videoView;
// notified when the video is completed.
- (void)nadNativeVideoViewDidCompletePlay:(NADNativeVideoView *)videoView;
// notified when the video cannot play.
- (void)nadNativeVideoViewDidFailToPlay:(NADNativeVideoView *)videoView;
// notified when the ad did present a full screen.
- (void)nadNativeVideoViewDidOpenFullScreen:(NADNativeVideoView *)videoView;
// notified when the ad did dismiss a full screen.
- (void)nadNativeVideoViewDidCloseFullScreen:(NADNativeVideoView *)videoView;
// notified when the video is started at full screen.
- (void)nadNativeVideoViewDidStartFullScreenPlaying:(NADNativeVideoView *)videoView;
// notified when the video is stopped at full screen.
- (void)nadNativeVideoViewDidStopFullScreenPlaying:(NADNativeVideoView *)videoView;
@end
Swift
class ViewController: UIViewController {

    @IBOutlet private weak var videoView: NADNativeVideoView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        videoView.delegate = self
        ...
    }

}

// MARK: - NADNativeVideoViewDelegate

extension ViewController: NADNativeVideoViewDelegate {

    func nadNativeVideoViewDidStartPlay(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidStopPlay(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidCompletePlay(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidFail(toPlay videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidOpenFullScreen(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidCloseFullScreen(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidStartFullScreenPlaying(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

    func nadNativeVideoViewDidStopFullScreenPlaying(_ videoView: NADNativeVideoView) {
        print("\(#function)")
    }

}
Objective-C
@interface ViewController () <NADNativeVideoViewDelegate>

@property (nonatomic, weak) IBOutlet NADNativeVideoView *videoView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.videoView.delegate = self;
    ...
}

#pragma mark - NADNativeVideoViewDelegate

- (void)nadNativeVideoViewDidStartPlay:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidStopPlay:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidFailToPlay:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidCompletePlay:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidOpenFullScreen:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidCloseFullScreen:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidStartFullScreenPlaying:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)nadNativeVideoViewDidStopFullScreenPlaying:(NADNativeVideoView *)videoView
{
    NSLog(@"%s", __FUNCTION__);
}

@end

Set mute to play full-screen

Set mute to play full-screen using mutedOnFullScreen property.
And default value is false.

@property (readwrite, nonatomic, getter=isMutedOnFullScreen) BOOL mutedOnFullScreen;

Register interaction Views

Register views that click target using registerInteractionViews:.
Please interact click action to views including text materials.

- (void)registerInteractionViews:(nonnull NSArray<__kindof UIView *> *)views;

This example describe how to imprement that show ad content while click Call To Action button.

Swift
class ViewController: UIViewController {

    @IBOutlet private weak var callToActionButton: UIButton!

    private let loader = NADNativeVideoLoader(spotID: spotID, apiKey: "apiKey")

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        loader.loadAd { [weak self] (ad, error) in
            guard let `self` = self else { return }
            if let videoAd = ad {
                ...
                self.callToActionButton.setTitle(videoAd.callToAction, for: .normal)
                videoAd.registerInteractionViews([self.callToActionButton])
                ...
            }
        }
    }

}
Objective-C
@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIButton *callToActionButton;
@property (nonatomic, strong) NADNativeVideoLoader *loader;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.loader = [[NADNativeVideoLoader alloc] initWithSpotID:spotID apiKey:@"apiKey"];

    __weak typeof(self) weakSelf = self;
    [self.loader loadAdWithCompletionHandler:^(NADNativeVideo * _Nullable ad, NSError * _Nullable error) {
        if (weakSelf && ad) {
            ...
            [weakSelf.callToActionButton setTitle:ad.callToAction forState:UIControlStateNormal];
            [ad registerInteractionViews:@[weakSelf.callToActionButton]];
            ...
        }
    }];
}
@end

Unregister interaction Views

Unregister views that registed click target using unregisterInteractionViews.

- (void)unregisterInteractionViews;

Verification

Please use one of the following test modes for native video ads.

How to check IDFA

IDFA value will be printed in debug logs when SDK Log level set over Info & created NADNativeVideoLoader object. IDFA_console_log

日本語

nendSDK iOS について

SDKの組み込み

広告の表示

全般設定

導入サポート


English

About nendSDK iOS

SDK Implementation

Display Ads

Global Settings

Supports

Clone this wiki locally