AI Search

原生广告

InMobi原生广告支持静态广告和视频广告。您可以选择信息流广告、启动画面广告或前置广告格式。创建原生广告位的步骤如下。

设置原生广告

InMobi原生广告支持静态广告和视频广告。您可以选择信息流广告、启动广告或前置广告格式。创建原生广告位的步骤如下。

  1. 从左侧导航栏中选择“库存” >“库存设置”
  2. 搜索您想要为其创建广告位的应用或网站,然后点击+ 添加广告位
  3. 点击“选择广告单元”,然后选择“原生广告”
  4. 点击“添加位置”开始设置您的 Native 设置。

原生广告位创建完成后,您将能够看到广告位 ID。

原生广告 API

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 管理的媒体视图(图像或视频)。

信息流广告整合

  1. 导入 InMobi SDK 头文件。

    Objective-C

    #import <InMobiSDK/InMobiSDK.h>
    

    Swift

    import InMobiSDK
    
  2. 在您的信息流中声明您希望展示广告的位置。例如,将广告展示在第 4 位。

    Objective-C

    #define IM_AD_INSERTION_POSITION 4
    

    Swift

    let adInsertionPosition = 4
    
  3. 在您的应用程序中声明一个原生广告实例ViewController.m

    Objective-C

    @interface TableViewController () <IMNativeDelegate> 
    @property(nonatomic,strong) IMNative *InMobiNativeAd; 
    @end
    

    Swift

    class ViewController: UIViewController, IMNativeDelegate {
    var inMobiNativeAd: IMNative?
    
  4. 最终的ViewDidLoad代码应该如下所示:

    Objective-C

    - (void)viewDidLoad { 
        [super viewDidLoad]; 
        self.InMobiNativeAd = [[IMNative alloc] initWithPlacementId:<Insert InMobi  placement ID here>]; 
        self.InMobiNativeAd.delegate = self; 
        [self.InMobiNativeAd load]; 
        //Your app content 
    }
    

    Swift

    override func viewDidLoad() {
        super.viewDidLoad()
        inMobiNativeAd = IMNative(placementId: <Insert InMobi plc id> )
        inMobiNativeAd?.delegate = self
        inMobiNativeAd?.load()
        // Your app content 
    }
    
    	
  5. 实现IMNativeDelegate成功回调方法。成功回调表明广告已准备好在屏幕上显示。您需要在此处将 InMobiNativeAd 对象添加到 TableView 的数据源中。

    Objective-C

    -(void)nativeDidFinishLoading:(IMNative*)native{
        [self.tableData insertObject:native atIndex:IM_AD_INSERTION_POSITION];
        [self.tableView reloadData];
        NSLog(@"Native Ad did finish loading");
    }
    
    

    Swift

    func nativeDidFinishLoading(_ native: IMNative!) {
         self.tableData.insert(native, at: IM_AD_INSERTION_POSITION)
         self.tableView.reloadData()
         NSLog("InMobi Native Did finished loading");
    }
    
    
    
  6. 原生广告渲染和展示次数跟踪

    当您收到回调时,表示您已成功接收到原生广告nativeAdDidFinishLoading。以下示例展示了如何在 tableView 代理中获取 adView cellForRowAtIndexPath

    笔记

    只有当原生广告的主视图位于屏幕可见区域时,才会触发展示事件。

    使用故事板实现以下自定义单元格类。

    Objective-C

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

    Swift

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

    Objective-C

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

    Swift

    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
    }
    
  7. 在可重用的表格视图单元格中投放广告时,务必在显示新广告之前清除所有先前加载的广告。为此,请 prepareForReuse() 在自定义 UITableViewCell 子类中重写相关方法。这样可以确保移除所有旧的广告视图或数据,从而防止单元格重用期间出现内容重叠、内存泄漏或广告渲染错误等问题。

    Objective-C

    - (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; ...
    }
    

    Swift

    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; ...
    }
    
    
  8. 刷新广告- 您需要在不同时间点刷新广告,以优化广告对用户的曝光度。要刷新广告,您需要按以下顺序调用相应函数。

    Objective-C

    // 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]; 
    }
    
    

    Swift

    //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并销毁当前的广告对象。然后,您需要创建一个新对象并调用其加载方法。

  9. 处理屏幕方向改变- 用于autolayout处理单元格和视图上的所有屏幕方向改变。广告将响应自动布局更改。
  10. 你应该在类的方法中将InMobiNativeAd对象及其委托设置为 nil deallocViewController

    Objective-C

    -(void)dealloc {
        self.InMobiNativeAd.delegate = nil;
        self.InMobiNativeAd = nil;
    }
    

    Swift

    deinit {
            inMobiNativeAd?.delegate = nil
            inMobiNativeAd = nil
        }
    

启动广告集成

  1. 可以使用同一个类来实现启动画面体验IMNative
  2. 您应该使用self.InMobiNativeAd.isReady函数来判断广告是否可以展示。有时,您的主线程可能被占用,因此您可能无法nativeDidFinishLoading及时收到通知。所以,最好在截止时间过后主动检查广告是否已准备就绪。
  3. 重要提示:如果广告的第二个屏幕正在显示,则不应关闭该广告。您可以在代码中进行检查nativeWillPresentScreen,并在触发此委托时阻止广告关闭。示例实现如下:

    Objective-C

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

    Swift

     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
        }
    	
  4. 你应该将InMobiNativeAd对象及其委托设置为 nil。

    Objective-C

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

    Swift

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

前置广告整合

  1. 可以使用同一个类来实现前置视频广告体验IMNative。您需要在以下代理中关闭广告展示:

    Objective-C

    -(void)nativeDidFinishPlayingMedia:(IMNative *)native{
        [self dismissAd];
    }
    
    

    Swift

    func nativeDidFinishPlayingMedia(_ native: IMNative) {
            self.dismissAd()
        }
    	
  2. 你应该将InMobiNativeAd对象及其委托设置为 nil。

    Objective-C

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

    Swift

     var prerollAdView: UIView? // Use this to store the primaryView returned by the IMNative instance.
     func dismissAd() {
            prerollAdView?.isHidden = true
            inMobiNativeAd = nil
        }
    

高级设置

您可以通过以下步骤获取额外的回调。请在您的ViewController.m文件中实现以下委托方法:

Objective-C

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

Swift

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 和原生广告单元。您可以根据为原生广告位预留的空间大小,投放以下几种广告尺寸。

  • 320x50 HTML 横幅广告
  • 300x250 HTML 横幅广告
  • 320x480 HTML 全屏横幅广告
  • 320x568 HTML 全屏横幅

要启用此功能,您需要联系相应的合作伙伴经理,并告知所需的填充大小。此外,您还需要在代码中按如下方式进行处理:

Objective-C

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

Swift

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    }

 

笔记

  • 为了检测响应是否为回填,customAdContent 将包含字符串isHTMLResponse
  • 请勿缩放HTML 横幅响应的宽度。例如,如果您选择回填尺寸为 300x250,请确保提供的宽度硬编码为 250。
  • 请勿在回填响应中添加 CTA 按钮。如果您在广告旁边添加了此按钮,则点击将无法变现

本页内容

最后更新于 : 10 Sep, 2026