InMobi原生广告支持静态广告和视频广告。您可以选择信息流广告、启动画面广告或前置广告格式。创建原生广告位的步骤如下。
InMobi原生广告支持静态广告和视频广告。您可以选择信息流广告、启动广告或前置广告格式。创建原生广告位的步骤如下。
原生广告位创建完成后,您将能够看到广告位 ID。

IMNative 类包含以下对象:
@objc public var adTitle: String?- 返回广告标题。@objc public var adDescription: String? - 返回广告描述。@objc public var adIcon: IMNativeImage?- 返回广告图标图像。@objc public var adCtaText: String?- 返回广告的点击操作文本。@objc public var adRating: String?- 返回广告评分(可选)。@objc public var advertiserName: String?- 返回广告的广告商名称。(可选)@objc public var adChoice: UIImageView? - 返回广告的选择视图。(可选)IMNative 类支持以下功能:
@objc public func load()- 将广告加载到内存中的功能。@objc public func isReady() -> Bool- True 表示广告已准备好展示。@objc public func getCustomAdContent() -> [String: Any]?- 这将包含附加信息(描述、图像 URL 等),可用于围绕广告的主要视图创建自定义 UI。@objc public func isVideoAd() -> Bool - True 表示该广告是视频广告。@objc public func registerViewForTracking(_ view: IMNativeViewData)- 注册您的原生广告 UI,以便进行可见性、展示次数和点击次数跟踪。@objc public func getMediaView() -> UIView? - 如果可用,则返回此广告的 SDK 管理的媒体视图(图像或视频)。导入 InMobi SDK 头文件。
#import <InMobiSDK/InMobiSDK.h>
import InMobiSDK
在您的信息流中声明您希望展示广告的位置。例如,将广告展示在第 4 位。
#define IM_AD_INSERTION_POSITION 4
let adInsertionPosition = 4
在您的应用程序中声明一个原生广告实例ViewController.m。
@interface TableViewController () <IMNativeDelegate>
@property(nonatomic,strong) IMNative *InMobiNativeAd;
@end
class ViewController: UIViewController, IMNativeDelegate {
var inMobiNativeAd: IMNative?
最终的ViewDidLoad代码应该如下所示:
- (void)viewDidLoad {
[super viewDidLoad];
self.InMobiNativeAd = [[IMNative alloc] initWithPlacementId:<Insert InMobi placement ID here>];
self.InMobiNativeAd.delegate = self;
[self.InMobiNativeAd load];
//Your app content
}
override func viewDidLoad() {
super.viewDidLoad()
inMobiNativeAd = IMNative(placementId: <Insert InMobi plc id> )
inMobiNativeAd?.delegate = self
inMobiNativeAd?.load()
// Your app content
}
实现IMNativeDelegate成功回调方法。成功回调表明广告已准备好在屏幕上显示。您需要在此处将 InMobiNativeAd 对象添加到 TableView 的数据源中。
-(void)nativeDidFinishLoading:(IMNative*)native{
[self.tableData insertObject:native atIndex:IM_AD_INSERTION_POSITION];
[self.tableView reloadData];
NSLog(@"Native Ad did finish loading");
}
func nativeDidFinishLoading(_ native: IMNative!) {
self.tableData.insert(native, at: IM_AD_INSERTION_POSITION)
self.tableView.reloadData()
NSLog("InMobi Native Did finished loading");
}
当您收到回调时,表示您已成功接收到原生广告nativeAdDidFinishLoading。以下示例展示了如何在 tableView 代理中获取 adView cellForRowAtIndexPath。
只有当原生广告的主视图位于屏幕可见区域时,才会触发展示事件。
使用故事板实现以下自定义单元格类。
#import <uikit uikit.h="">
@interface InFeedTableViewCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UIImageView *iconImage;
@property (nonatomic, weak) IBOutlet UILabel *titleLabel;
@property (nonatomic, weak) IBOutlet UILabel *subtitleLabel;
@property (nonatomic, weak) IBOutlet UILabel *descriptionLabel;
@property (nonatomic, weak) IBOutlet UILabel *ctaLabel;
@property (nonatomic, weak) IBOutlet UIView *adView;
@property (nonatomic, weak) IBOutlet UIImageView *adChoice;
@end
</uikit>
class InFeedTableViewCell: UITableViewCell {
@IBOutlet weak var iconImage : UIImage?
@IBOutlet weak var titleLabel : UILabel?
@IBOutlet weak var subtitleLabel : UILabel?
@IBOutlet weak var descriptionLabel : UILabel?
@IBOutlet weak var ctaLabel : UILabel?
@IBOutlet weak var adView : UIView?
@IBOutlet weak var adChoice: UIImageView!
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
InFeedTableCell *cell = ( *)[tableView dequeueReusableCellWithIdentifier:@"InFeedTableCell"];
id nativeAd = [self.tableData objectAtIndex:indexPath.row];
if ([nativeAd isKindOfClass:[IMNative Class]]]) {
IMNative * currentNativeAd = nativeAd;
cell.iconImage.image = currentNativeAd.adIcon.imageview;
cell.titleLabel.text = currentNativeAd.adTitle;
cell.subtitleLabel.text = @"Sponsored";
cell.descriptionLabel.text = currentNativeAd.adDescription;
cell.ctaLabel.text = currentNativeAd.adCtaText;
// Add ad choice view
[cell.adChoice addSubview:currentNativeAd.adChoice];
cell.adChoice.userInteractionEnabled = YES;
// Add media view
UIView *mediaView = [currentNativeAd getMediaView];
[cell.adView addSubview:mediaView];
// Register native ad views for tracking
IMNativeViewDataBuilder *builder = [[IMNativeViewDataBuilder alloc] initWithParentView:self.cell];
[builder setTitleView:cell.titleLabel];
[builder setDescriptionView:cell.descriptionLabel];
[builder setCTAView:cell.ctaLabel];
[builder setIconView:(UIImageView *)cell.iconImage];
IMNativeViewData *nativePubData = [builder build];
[currentNativeAd registerViewForTracking:nativePubData];
}
else{
//Your App’s TableCell implementation
}
return cell;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = (tableView.dequeueReusableCell(withIdentifier: "InFeedTableCell")! as! InFeedTableViewCell)
if let currentNativeAd = self.tableData?[indexPath.row] as? IMNative {
cell.iconImageView.image! = currentNativeAd.adIcon?.imageview
cell.titleLabel!.text! = currentNativeAd.adTitle
cell.subtitleLabel?.text! = "Sponsored"
cell.descriptionLabel.text! = currentNativeAd.adDescription
cell.ctaLabel?.text! = currentNativeAd.adCtaText
// Add ad choice view
cell.adChoice.addSubview(currentNativeAd.adChoice)
cell.adChoice.isUserInteractionEnabled = true
// Add media view
let mediaView = currentNativeAd.getMediaView()
adView.addSubview(mediaView)
// Register native ad views for tracking
let nativePubData = IMNativeViewData.Builder(parentView: cell)
.setTitleView(cell.adTitle)
.setDescriptionView(cell.descriptionLabel)
.setIconView(cell.adIcon)
.setCTAView(cell.CtaButton)
.build()
currentNativeAd?.registerViewForTracking(nativePubData)
}
else {
// Your app's Table Cell implementations
}
return cell
}
在可重用的表格视图单元格中投放广告时,务必在显示新广告之前清除所有先前加载的广告。为此,请 prepareForReuse() 在自定义 UITableViewCell 子类中重写相关方法。这样可以确保移除所有旧的广告视图或数据,从而防止单元格重用期间出现内容重叠、内存泄漏或广告渲染错误等问题。
- (void)prepareForReuse {
[super prepareForReuse];
// Remove previously added ad/media subviews
for (UIView *v in self.adView.subviews) {
[v removeFromSuperview];
}
// Optionally clear icon/title/etc. if you want:
// self.iconImage.image = nil; self.titleLabel.text = nil; ...
}
override func prepareForReuse() {
super.prepareForReuse()
_ = adView.subviews.map { $0.removeFromSuperview()}
// Optionally clear icon/title/etc. if you want:
// self.iconImage.image = nil; self.titleLabel.text = nil; ...
}
刷新广告- 您需要在不同时间点刷新广告,以优化广告对用户的曝光度。要刷新广告,您需要按以下顺序调用相应函数。
// Suggested approach
// Use`- (void)prepareForReuse` in UItableViewCell to clear out any ad before loading
//
-(void)refreshInMobiStrandAd {
[self.tableData removeObject:self.InMobiNativeAd];
[self.tableView reloadData];
self.InMobiNativeAd = [[IMNative alloc] initWithPlacementId:];
self.InMobiNativeAd.delegate = self;
[self.InMobiNativeAd load];
}
//Suggested approach
//Use `override func prepareForReuse()` in UItableViewCell to clear out any ad before loading
// any new Ad.
func refreshInMobiStrandAd() {
tableData = tableData?.filter({ (obj) -> Bool in
if obj is IMNative {
return false
}
return true
})
tableView.reloadData()
inMobiNativeAd = IMNative(placementId: )
inMobiNativeAd?.delegate = self
inMobiNativeAd?.load()
}
务必IMNative先从您的设置中移除该对象tableData并销毁当前的广告对象。然后,您需要创建一个新对象并调用其加载方法。
autolayout处理单元格和视图上的所有屏幕方向改变。广告将响应自动布局更改。你应该在类的方法中将InMobiNativeAd对象及其委托设置为 nil 。deallocViewController
-(void)dealloc {
self.InMobiNativeAd.delegate = nil;
self.InMobiNativeAd = nil;
}
deinit {
inMobiNativeAd?.delegate = nil
inMobiNativeAd = nil
}
IMNative。self.InMobiNativeAd.isReady函数来判断广告是否可以展示。有时,您的主线程可能被占用,因此您可能无法nativeDidFinishLoading及时收到通知。所以,最好在截止时间过后主动检查广告是否已准备就绪。重要提示:如果广告的第二个屏幕正在显示,则不应关闭该广告。您可以在代码中进行检查nativeWillPresentScreen,并在触发此委托时阻止广告关闭。示例实现如下:
@property(nonatomic,strong) bool *isSecondScreenDisplayed;// Use this to check if second screen has to be shown or not
-(void)nativeWillPresentScreen:(IMNative*)native{
NSLog(@"Native Ad will present screen");
isSecondScreenDisplayed = YES;
}
var isSecondScreenDisplayed: Bool = false// Use this to check if second screen has to be shown or not
func nativeWillPresentScreen(_ native: IMNative) {
print("Native Ad will present screen")
isSecondScreenDisplayed = true
}
你应该将InMobiNativeAd对象及其委托设置为 nil。
@property (nonatomic, strong) UIView* SplashAdView; // Use this view to check for visibility of splash screen
-(void)dismissAd{
if(isSecondScreenDisplayed){
NSLog(@"DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED");
}
else{
self.SplashAdView.hidden = true;
self.InMobiNativeAd = nil;
}
}
var splashAdView: UIView? // Use this to check visibility of second screen
func dismissAd() {
if isSecondScreenDisplayed {
print("DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED")
}
else {
splashAdView?.isHidden = true
inMobiNativeAd = nil
}
}
可以使用同一个类来实现前置视频广告体验IMNative。您需要在以下代理中关闭广告展示:
-(void)nativeDidFinishPlayingMedia:(IMNative *)native{
[self dismissAd];
}
func nativeDidFinishPlayingMedia(_ native: IMNative) {
self.dismissAd()
}
你应该将InMobiNativeAd对象及其委托设置为 nil。
@property (nonatomic, strong) UIView* PrerollAdView; //Use this to store the primaryView returned by the IMNative instance.
-(void)dismissAd{
self.PrerollAdView.hidden = true;
self.InMobiNativeAd = nil;
}
var prerollAdView: UIView? // Use this to store the primaryView returned by the IMNative instance.
func dismissAd() {
prerollAdView?.isHidden = true
inMobiNativeAd = nil
}
您可以通过以下步骤获取额外的回调。请在您的ViewController.m文件中实现以下委托方法:
-(void)nativeDidFinishLoading:(IMNative*)native{
NSLog(@"Native Ad load Successful"); // Ad is ready to be displayed
}
-(void)native:(IMNative*)native didFailToLoadWithError:(IMRequestStatus*)error{
NSLog(@"Native Ad load Failed"); // No Fill or error
}
-(void)nativeWillPresentScreen:(IMNative*)native{
NSLog(@"Native Ad will present screen"); //Full Screen experience is about to be presented
}
-(void)nativeDidPresentScreen:(IMNative*)native{
NSLog(@"Native Ad did present screen"); //Full Screen experience has been presented
}
-(void)nativeWillDismissScreen:(IMNative*)native{
NSLog(@"Native Ad will dismiss screen"); //Full Screen experience is going to be dismissed
}
-(void)nativeDidDismissScreen:(IMNative*)native{
NSLog(@"Native Ad did dismiss screen"); //Full Screen experience has been dismissed
}
-(void)userWillLeaveApplicationFromNative:(IMNative*)native{
NSLog(@"User leave"); //User is about to leave the app on clicking the ad
}
-(void)native:(IMNative *)native didInteractWithParams:(NSDictionary *)params{
NSLog(@"User clicked"); // Called when the user clicks on the ad.
}
-(void)nativeAdImpressed:(IMNative *)native{
NSLog(@"User viewed the ad"); // Called when impression event is fired.
}
-(void)nativeDidFinishPlayingMedia:(IMNative*)native{
NSLog(@"The Video has finished playing"); // Called when the video has finished playing. Used for preroll use-case
}
-(void)native:(IMNative*)native adAudioStateChanged:(BOOL)audioStateMuted {
if (audioStateMuted) {
NSLog(@"Inline video-ad audio state changed to mute");
}
else {
NSLog(@"Inline video-ad audio state changed to unmute");
}
//This is called when inline video audio state changes.
}
func nativeDidFinishLoading(_ native: IMNative) {
print("Native Ad load Successful") // Ad is ready to be displayed
}
func native(_ native: IMNative, didFailToLoadWithError error: IMRequestStatus) {
print("Native Ad load Failed") // No Fill or error
}
func nativeWillPresentScreen(_ native: IMNative) {
print("Native Ad will present screen") //Full Screen experience is about to be presented
}
func nativeDidPresentScreen(_ native: IMNative) {
print("Native Ad did present screen") //Full Screen experience has been presented
}
func nativeWillDismissScreen(_ native: IMNative) {
print("Native Ad will dismiss screen") //Full Screen experience is going to be dismissed
}
func nativeDidDismissScreen(_ native: IMNative) {
print("Native Ad did dismiss screen") //Full Screen experience has been dismissed
}
func userWillLeaveApplicationFromNative(_ native: IMNative) {
print("User leave") //User is about to leave the app on clicking the ad
}
func native(_ native: IMNative, didInteractWithParams params: [String : Any]?) {
print("User clicked") // Called when the user clicks on the ad.
}
func nativeAdImpressed(_ native: IMNative) {
print("User viewed the ad") // Called when impression event is fired.
}
func nativeDidFinishPlayingMedia(_ native: IMNative) {
print("The Video has finished playing") // Called when the video has finished playing. Used for preroll use-case
}
func native(_ native: IMNative, adAudioStateChanged audioStateMuted: Bool) {
if (audioStateMuted) {
print("Inline state changed to mute")
}
else {
print("Inline state changed to unmute")
}
}
InMobi 的 SDK 可以同时在您的原生广告位上投放 HTML 和原生广告单元。您可以根据为原生广告位预留的空间大小,投放以下几种广告尺寸。
要启用此功能,您需要联系相应的合作伙伴经理,并告知所需的填充大小。此外,您还需要在代码中按如下方式进行处理:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
InFeedTableCell *cell = (InFeedTableCell *)[tableView
dequeueReusableCellWithIdentifier:@"InFeedTableCell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"InFeedTableCell"
owner:self options:nil];
cell = [nib objectAtIndex:0];
id slide = [self.tableData objectAtIndex:indexPath.row];
if ([self isAdAtIndexPath:indexPath]) {
IMNative *currentNativeAd = slide;
NSString *customJSONstring = currentNativeAd.customAdContent;
NSData *data = [customJSONstring dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
BOOL isBackFillBanner = [[jsonDict objectForKey:@"isHTMLResponse"] boolValue];
if (isBackFillBanner) {
IMNative * currentNativeAd = slide;
//Depending on the selected backfill size, provide accurate width below
UIView* AdPrimaryViewOfCorrectWidth = [currentNativeAd primaryViewOfWidth:250];
AdPrimaryViewOfCorrectWidth.frame = CGRectMake((_screenWidth-300)/2, 0, 300, 250);
[cell addSubview:AdPrimaryViewOfCorrectWidth];
}
else
{
//continue with the current native implementation
IMNative * currentNativeAd = slide;
cell.iconImageView.image = currentNativeAd.adIcon;
cell.titleLabel.text = currentNativeAd.adTitle;
cell.subTitleLabel.text = @"Sponsored";
cell.descriptionLabel.text = currentNativeAd.adDescription;
cell.ctaLabel.text = currentNativeAd.adCtaText;
//Calculate your feed's primaryImageViewWidth and use it to fetch and Ad Primary view of same width.
UIView* AdPrimaryViewOfCorrectWidth = [currentNativeAd primaryViewOfWidth:primaryImageViewWidth];
//Set the frame of Ad Primary View same as that of your feed's Primary View
AdPrimaryViewOfCorrectWidth.frame = primaryImageViewFrame;
[cell addSubview:AdPrimaryViewOfCorrectWidth];
UITapGestureRecognizer *singleTapAndOpenLandingPage =
[[UITapGestureRecognizer alloc] initWithTarget:currentNativeAd
action:@selector(reportAdClickAndOpenLandingPage)];
cell.ctaLabel.userInteractionEnabled = YES;
[cell.ctaLabel addGestureRecognizer:singleTapAndOpenLandingPage];
}
}
else {
//Your App’s TableCell implementation
}
return cell;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = (tableView.dequeueReusableCell(withIdentifier: "InFeedTableCell")! as! InFeedTableViewCell)
if let currentNativeAd = self.tableData?[indexPath.row] as? IMNative {
let customJSONstring = currentNativeAd.customAdContent
if let data = customJSONstring?.data(using: .utf8) {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
if let isBackFillBanner = json["isHTMLResponse"] as? Bool, isBackFillBanner {
//Depending on the selected backfill size, provide accurate width below
let adPrimaryViewOfCorrectWidth: UIView = currentNativeAd.primaryView(ofWidth: 250)
adPrimaryViewOfCorrectWidth.frame = CGRect(x: (_screenWidth-300)/2, y: 0, width: 300, height: 250)
cell.addSubview(adPrimaryViewOfCorrectWidth)
} else {
//continue with the current native implementation
cell.iconImageView.image = currentNativeAd.adIcon
cell.titleLabel.text = currentNativeAd.adTitle
cell.subtitleLabel.text = "Sponsored"
cell.descriptionLabel.text = currentNativeAd.description
cell.ctaLabel?.text = currentNativeAd.adCtaText
//Calculate your feed's primaryImageViewWidth and use it to fetch and Ad Primary view of same width.
let adPrimaryViewOfCorrectWidth: UIView = currentNativeAd.primaryView(ofWidth: primaryImageViewWidth)
//Set the frame of Ad Primary View same as that of your feed's Primary View
let singleTapAndOpenLandingPage = UITapGestureRecognizer(target:currentNativeAd, action: #selector(self.reportAdClickAndOpenLandingPage))
cell.ctaLabel?.isUserInteractionEnabled = true
cell.ctaLabel?.addGestureRecognizer(singleTapAndOpenLandingPage)
}
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
}
return cell }
isHTMLResponse。By installing this SDK update, you agree that your Children Privacy Compliance setting remains accurate or that you will update that setting, whenever there is a change in your app's audience. You may update the app's Children Privacy Compliance settings at https://publisher.inmobi.com/my-inventory/app-and-placements.