Unity项目接入IOS的Admob Native(原生视频广告) IOS SDK
//定义OC方法(与IOS的方法对应) [DllImport("__Internal")] private static extern void initNativeAd(string appId, string nativeAd, bool isVideoStartMute); //C#调用IOS void InitNativeIOS(string appId, string nativeAd, bool isVideoStartMute) { initNativeAd(appId, nativeAd, isVideoStartMute); }
4.1 添加Admob IOS SDK,这里用的是GoogleMobileAdsSdkiOS-7.35.2
选择"Frameworks"文件夹右键"Add Files"
选择"GoogleMobileAds.framework",勾选"Copy items if needed",将SDK的库文件添加到工程
添加完成后
4.2 复制官方IOS Native Demo中的UI布局文件到项目
具体路径在Google下载的Demo文件夹下:
跟4.1操作一样,选择"Classes"文件夹右键"Add Files",添加"UnifiedNativeAdView.xib"文件到项目
将适配方式改为"Freeform" ,xib文件的UI布局及其他设置,可以根据实际需求再做一些修改
4.3 新建 .h 和 .m 文件
选择 .m 文件
命名为"NativeAdController"(类名)
保存到"Classes"下
.h 文件与 .m 文件创建方式一样,且需要与 .m 文件同名
两个文件创建完成后:
5. 仿照官方Demo中的"ViewController"类,修改"NativeAdController"类(即刚刚创建的.h和.m文件)
代码说明都加到注释了,附在文末 ~
6. 运行到手机看一下效果,视频广告正常显示,完美~
到这里大部分工作已经完成了,可以在Xcode工程中获取以下三个文件,对于正式项目,只需在Unity中写好调用方法,导出Xcode工程,将SDK和这三个文件添加到Xcode工程里,就可以正常加载显示Native广告了。
也可以在Unity中导入Unity的SDK,然后将这三个文件放到Unity项目中,导出Xcode时会自动加入这三个文件,这样在Xcode就不需要额外的操作了,直接出包即可。
-----------------------------
附一:
Unity中C#调用IOS的OC方法:
NativeAdController C#
using UnityEngine; using System.Runtime.InteropServices; using UnityEngine.UI; public class NativeAdController : MonoBehaviour { [SerializeField] Button showBtn; [SerializeField] Button hideBtn; string appIdIOS = "ca-app-pub-3940256099942544~1458002511"; string nativeAdIdIOS = "ca-app-pub-3940256099942544/2521693316"; bool nativeVideoAdStartMute = false; bool isInited = false; void Start() { showBtn.onClick.AddListener(() => { if (IsNativeReady()) ShowNative(0); }); hideBtn.onClick.AddListener(HideNative); InitNative(); } //----- public ----- public void InitNative() { if (isInited) return; isInited = true; if (!string.IsNullOrEmpty(appIdIOS) && !string.IsNullOrEmpty(nativeAdIdIOS)) InitNativeIOS(appIdIOS, nativeAdIdIOS, nativeVideoAdStartMute); } public bool IsNativeReady() { return IsNativeReadyIOS(); } public void ShowNative(float positionParame) { if (positionParame < 0) positionParame = 0; else if (positionParame > 1) positionParame = 1; ShowNativeIOS(positionParame); } public void HideNative() { HideNativeIOS(); } //----- IOS ----- //定义OC方法 [DllImport("__Internal")] private static extern void initNativeAd(string appId, string nativeAd, bool isVideoStartMute); [DllImport("__Internal")] private static extern bool isNativeAdReady(); [DllImport("__Internal")] private static extern void showNativeAd(float positionParame); [DllImport("__Internal")] private static extern void hideNativeAd(); //C#调用 void InitNativeIOS(string appId, string nativeAd, bool isVideoStartMute) { initNativeAd(appId, nativeAd, isVideoStartMute); } bool IsNativeReadyIOS() { return isNativeAdReady(); } void ShowNativeIOS(float positionParame) { showNativeAd(positionParame); } void HideNativeIOS() { hideNativeAd(); } }
IOS类:
NativeAdController.h
#import <UIKit/UIKit.h> //声明,外部接口 @interface NativeAdController : UIViewController @end
//添加库引用
#import "NativeAdController.h"
#import <GoogleMobileAds/GoogleMobileAds.h>
//标记广告是否加载完成
static bool isNativeReady;
//Native广告类
static GADUnifiedNativeAd *curNativeAd;
//Native广告Id
static NSString *nativeAdUnit;
//广告视频是否静音播放
static bool videoStartMute;
//声明,类似于定义内部接口
@interface NativeAdController () <GADUnifiedNativeAdLoaderDelegate,
GADVideoControllerDelegate,
GADUnifiedNativeAdDelegate>
@property(nonatomic, strong) GADAdLoader *adLoader;
//广告界面
//@property(nonatomic, strong) GADUnifiedNativeAdView *nativeAdView;
@property (nonatomic,strong) GADUnifiedNativeAdView *myView;
@property(nonatomic, strong) NSLayoutConstraint *heightConstraint;
@end
//实现,与声明对应
@implementation NativeAdController
static NativeAdController *myAdController;
//----- C方法,供Unity调用 -----
//初始化广告,Unity传参
void initNativeAd(char *appId, char *nativeAd, bool isVideoStartMute)
{
if(!myAdController)
myAdController = [NativeAdController new];
//C#的string不能直接转为OC的NSString,利用char转换
NSString *ocAppId = [NSString stringWithUTF8String:appId];
NSString *ocnativeAd = [NSString stringWithUTF8String:nativeAd];
[myAdController initNative:ocAppId nativeAd:ocnativeAd isVideoStartMute:isVideoStartMute];
}
//广告是否已加载
bool isNativeAdReady()
{
return [myAdController isNativeReady];
}
//展示广告界面
void showNativeAd(float positionParame)
{
[myAdController showNative:positionParame];
}
//隐藏广告界面
void hideNativeAd()
{
[myAdController hideNative];
}
//----- OC方法 -----
-(void)initNative:(NSString *)appId nativeAd:(NSString *)nativeAd isVideoStartMute:(bool)isVideoStartMute
{
//初始化注册Native
[GADMobileAds configureWithApplicationID:appId];
nativeAdUnit = nativeAd;
videoStartMute = isVideoStartMute;
//获取"UnifiedNativeAdView.xib",即广告界面布局文件
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"UnifiedNativeAdView" owner:nil options:nil];
self.myView = (GADUnifiedNativeAdView *)nibObjects.firstObject;
//初始化设置广告界面在屏幕的位置
CGFloat kscreenW = [UIScreen mainScreen].bounds.size.width;
CGFloat kscreenH = [UIScreen mainScreen].bounds.size.height;
self.myView.frame = CGRectMake(0, kscreenH - 275, kscreenW, 275);
// [self.view addSubview:self.myView];
[UnityGetGLView() addSubview:self.myView];
//隐藏广告界面
[self.myView setHidden:YES];
//请求广告
[self refreshAd];
}
-(Boolean) isNativeReady
{
//外部获取广告状态时,如果未加载,请求广告
if(!isNativeReady)
{
[self refreshAd];
}
return isNativeReady;
}
-(void) showNative:(float) positionParame
{
if(isNativeReady)
{
//刷新广告界面
[self showNativeAdView:positionParame];
//显示广告界面
[self.myView setHidden:NO];
}
}
-(void) hideNative
{
//隐藏广告界面
[self.myView setHidden:YES];
//请求广告
[self refreshAd];
}
//----------
- (void)refreshAd {
isNativeReady = false;
//请求广告
GADVideoOptions *videoOptions = [[GADVideoOptions alloc] init];
videoOptions.startMuted = videoStartMute;
self.adLoader = [[GADAdLoader alloc] initWithAdUnitID:nativeAdUnit
rootViewController:self
adTypes:@[ kGADAdLoaderAdTypeUnifiedNative ]
options:@[ videoOptions ]];
self.adLoader.delegate = self;
//发送请求
// //测试使用
// GADRequest *request = [GADRequest request];
// request.testDevices = @[@"9c8cbe613c43e2997f2dd0620fb6deb7"];
// [self.adLoader loadRequest:request];
//正式使用
[self.adLoader loadRequest: [GADRequest request]];
}
//设置星级
- (UIImage *)imageForStars:(NSDecimalNumber *)numberOfStars {
double starRating = numberOfStars.doubleValue;
if (starRating >= 5) {
return [UIImage imageNamed:@"stars_5"];
} else if (starRating >= 4.5) {
return [UIImage imageNamed:@"stars_4_5"];
} else if (starRating >= 4) {
return [UIImage imageNamed:@"stars_4"];
} else if (starRating >= 3.5) {
return [UIImage imageNamed:@"stars_3_5"];
} else {
return nil;
}
}
//加载失败回调
#pragma mark GADAdLoaderDelegate implementation
- (void)adLoader:(GADAdLoader *)adLoader didFailToReceiveAdWithError:(GADRequestError *)error {
NSLog(@"%@ failed with error: %@", adLoader, error);
}
//加载成功回调
#pragma mark GADUnifiedNativeAdLoaderDelegate implementation
- (void)adLoader:(GADAdLoader *)adLoader didReceiveUnifiedNativeAd:(GADUnifiedNativeAd *)nativeAd {
curNativeAd = nativeAd;
isNativeReady = true;
}
//刷新广告界面
-(void)showNativeAdView:(float)positionParame
{
if(curNativeAd!= nil)
{
GADUnifiedNativeAdView *nativeAdView = self.myView;
//设置广告界面在屏幕的位置
CGFloat kscreenW = [UIScreen mainScreen].bounds.size.width;
CGFloat kscreenH = [UIScreen mainScreen].bounds.size.height;
nativeAdView.frame = CGRectMake(0, (kscreenH - 265) * (1-positionParame), kscreenW, 265);
// Deactivate the height constraint that was set when the previous video ad loaded.
self.heightConstraint.active = NO;
nativeAdView.nativeAd = curNativeAd;
// Set ourselves as the ad delegate to be notified of native ad events.
curNativeAd.delegate = self;
//根据广告返回值刷新UI界面
// Populate the native ad view with the native ad assets.
// Some assets are guaranteed to be present in every native ad.
((UILabel *)nativeAdView.headlineView).text = curNativeAd.headline;
((UILabel *)nativeAdView.bodyView).text = curNativeAd.body;
[((UIButton *)nativeAdView.callToActionView)setTitle:curNativeAd.callToAction
forState:UIControlStateNormal];
// Some native ads will include a video asset, while others do not. Apps can
// use the GADVideoController's hasVideoContent property to determine if one
// is present, and adjust their UI accordingly.
if (curNativeAd.videoController.hasVideoContent) {
// This app uses a fixed width for the GADMediaView and changes its height
// to match the aspect ratio of the video it displays.
if (curNativeAd.videoController.aspectRatio > 0) {
self.heightConstraint =
[NSLayoutConstraint constraintWithItem:nativeAdView.mediaView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nativeAdView.mediaView
attribute:NSLayoutAttributeWidth
multiplier:(1 / curNativeAd.videoController.aspectRatio)
constant:-10];
self.heightConstraint.active = YES;
}
// By acting as the delegate to the GADVideoController, this ViewController
// receives messages about events in the video lifecycle.
curNativeAd.videoController.delegate = self;
// self.videoStatusLabel.text = @"Ad contains a video asset.";
} else {
// self.videoStatusLabel.text = @"Ad does not contain a video.";
}
// These assets are not guaranteed to be present, and should be checked first.
((UIImageView *)nativeAdView.iconView).image = curNativeAd.icon.image;
if (curNativeAd.icon != nil) {
nativeAdView.iconView.hidden = NO;
} else {
nativeAdView.iconView.hidden = YES;
}
((UIImageView *)nativeAdView.starRatingView).image = [self imageForStars:curNativeAd.starRating];
if (curNativeAd.starRating) {
nativeAdView.starRatingView.hidden = NO;
} else {
nativeAdView.starRatingView.hidden = YES;
}
((UILabel *)nativeAdView.storeView).text = curNativeAd.store;
if (curNativeAd.store) {
nativeAdView.storeView.hidden = NO;
} else {
nativeAdView.storeView.hidden = YES;
}
((UILabel *)nativeAdView.priceView).text = curNativeAd.price;
if (curNativeAd.price) {
nativeAdView.priceView.hidden = NO;
} else {
nativeAdView.priceView.hidden = YES;
}
((UILabel *)nativeAdView.advertiserView).text = curNativeAd.advertiser;
if (curNativeAd.advertiser) {
nativeAdView.advertiserView.hidden = NO;
} else {
nativeAdView.advertiserView.hidden = YES;
}
// In order for the SDK to process touch events properly, user interaction should be disabled.
nativeAdView.callToActionView.userInteractionEnabled = NO;
}
}
//广告视频播放完成回调
#pragma mark GADVideoControllerDelegate implementation
- (void)videoControllerDidEndVideoPlayback:(GADVideoController *)videoController {
NSLog(@"Video playback has ended.");
}
//其他回调
#pragma mark GADUnifiedNativeAdDelegate
- (void)nativeAdDidRecordClick:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)nativeAdDidRecordImpression:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)nativeAdWillPresentScreen:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)nativeAdWillDismissScreen:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)nativeAdDidDismissScreen:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
- (void)nativeAdWillLeaveApplication:(GADUnifiedNativeAd *)nativeAd {
NSLog(@"%s", __PRETTY_FUNCTION__);
}
@end