在 iOS 應用程式加入原生廣告

原生廣告 API 可讓您針對自家應用程式中顯示的廣告,建立自訂的體驗。使用原生廣告 API 時,您不會收到可立即顯示的廣告,而是會收到如標題、圖像、呼籲字句等的一組廣告屬性,而您需要使用這些屬性來建構要用來顯示廣告的自訂 UIView。

設計應用程式中的原生廣告時,請參閱原生廣告指南

我們將會執行以下原生廣告版位。您會在我們的原生廣告中建立下列檢視項目。

檢視項目 #1:廣告客戶圖示

檢視項目 #2:廣告標題

檢視項目 #3:贊助標籤

檢視項目 #4:廣告客戶選擇

檢視項目 #5:廣告影音素材檢視

檢視項目 #6:社交元素

檢視項目 #7:廣告內文

檢視項目 #8:廣告呼籲字句按鈕


第 1 步:在 Storyboard 中建立原生廣告檢視項目

第 2 步:載入並顯示原生廣告

第 3 步:如何取得內容的長闊比例並套用自然的寬度與高度

第 4 步:驗證展示及點擊記錄

第 5 步:廣告無法顯示時的除錯方式

第 6 步:在不使用自動快取的情況下載入廣告

第 7 步:測試廣告整合

在變更記錄中查看已知問題

第 1 步:在 Storyboard 中建立原生廣告檢視項目

確保您在開始操作前,已經先行參閱 Audience Network 新手指南iOS 新手指南

在設計原生廣告和橫額廣告時,請務必遵循 iOS 版面配置指南,以提供用戶最佳體驗。

  1. 利用 iOS 新手指南建立新的專案後,請開啟 Main.storyboard。在主要的檢視元素中加入 UIView 元素,並將其命名為 adUIView


  2. 此外,在 adUIView 加入 adIconImageView(FBMediaView)、adTitleLabel(UILabel)、adCoverMediaView(FBMediaView)、adSocialContext(UILabel)、adCallToActionButton(UIButton)、adOptionsView(FBAdOptionsView)、adBodyLabel(UILabel)和 sponsoredLabel(UILabel),如下圖所示。


  3. 您或會留意到檢視控制器場景旁有個紅色箭頭。這通常代表您的版面缺少了某些限制。


    您必須選擇場景中的所有檢視物件,然後點擊「解決版面問題」圖示以加入缺少的限制。


  4. 現在您已建好所有展示原生廣告必備的用戶介面元素,您必須在檢視控制器介面中使用這些用戶介面元素。首先開啟 ViewController.m(若您使用 Swift,則開啟 ViewController.swift),然後拖曳 ViewController 物件中的 adUIView。您可以將其命名為 adUIView。之後,請按照上述步驟處理 adIconImageViewadTitleLabeladCoverMediaViewadSocialContextadCallToActionButtonadOptionsViewadBodyLabelsponsoredLabel


  5. 建立並執行專案。您應該會在裝置或模擬器上看到如下所示的空白內容:

現在您已建好所有展示原生廣告必備的用戶介面元素,下一步就是載入原生廣告,並將內容綁定至用戶介面元素。

第 2 步:載入並顯示原生廣告

  1. 在您的檢視控制器來源檔案中,匯入 SDK、宣告 ViewController 遵循 FBNativeAdDelegate 通訊協定,並新增 FBNativeAd 實例變數
    import UIKit
    import FBAudienceNetwork
    
    class ViewController: UIViewController, FBNativeAdDelegate {
        
      private var nativeAd: FBNativeAd?
    }
    #import <UIKit/UIKit.h>
    @import FBAudienceNetwork;
    
    @interface ViewController () <FBNativeAdDelegate>
    
    @property (strong, nonatomic) FBNativeAd *nativeAd;
    
    @end

  2. viewDidLoad 方法中,新增下列程式碼以載入原生廣告內容
    override func viewDidLoad() {
      super.viewDidLoad()
        
      let nativeAd = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
      nativeAd.delegate = self
      nativeAd.loadAd()
    }
    - (void)viewDidLoad 
    {
      [super viewDidLoad];
    
      FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
      nativeAd.delegate = self;
      [nativeAd loadAd];
    }

    YOUR_PLACEMENT_ID 顯示的編號為臨時編號,僅作測試之用。

    若您在實時代碼中使用此臨時編號,用戶將不會收到廣告(而是收到未供應廣告錯誤)。您必須在測試後返回此處,並將此臨時編號替換為實時版位編號。

    請參考 Audience Network 設定,了解產生實時版位編號的方法。

  3. 下一步是在內容準備就緒時顯示廣告。您需要 ViewController 來執行 nativeAdDidLoad 委派方法
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
        
      // 1. If there is an existing valid native ad, unregister the view
      if let previousNativeAd = self.nativeAd, previousNativeAd.isAdValid {
        previousNativeAd.unregisterView()
      }
        
      // 2. Retain a reference to the native ad object
      self.nativeAd = nativeAd
    
      // 3. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
      // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
      nativeAd.registerView(
        forInteraction: adUIView,
        mediaView: adCoverMediaView,
        iconView: adIconImageView,
        viewController: self,
        clickableViews: [adCallToActionButton, adCoverMediaView]
      )
        
      // 4. Render the ad content onto the view
      adTitleLabel.text = nativeAd.advertiserName
      adBodyLabel.text = nativeAd.bodyText
      adSocialContextLabel.text = nativeAd.socialContext
      sponsoredLabel.text = nativeAd.sponsoredTranslation
      adCallToActionButton.setTitle(nativeAd.callToAction, for: .normal)
      adOptionsView.nativeAd = nativeAd
    }
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
    {
      // 1. If there is an existing valid native ad, unregister the view
      if (self.nativeAd && self.nativeAd.isAdValid) {
        [self.nativeAd unregisterView];
      }
    
      // 2. Retain a reference to the native ad object
      self.nativeAd = nativeAd;
    
      // 3. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
      // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
      [self.nativeAd registerViewForInteraction:self.adUIView
                                      mediaView:self.adCoverMediaView
                                       iconView:self.adIconImageView
                                 viewController:self
                                 clickableViews:@[self.adCallToActionButton, self.adCoverMediaView]];
    
      // 4. Render the ad content onto the view
      self.adTitleLabel.text = self.nativeAd.advertiserName;
      self.adBodyLabel.text = self.nativeAd.bodyText;
      self.adSocialContextLabel.text = self.nativeAd.socialContext;
      self.sponsoredLabel.text = self.nativeAd.sponsoredTranslation;
      [self.adCallToActionButton setTitle:self.nativeAd.callToAction forState:UIControlStateNormal];
      self.adOptionsView.nativeAd = self.nativeAd; 
    }
  4. 控制可點擊的區域

    為了提供更優質的用戶體驗及更卓越的成效,您應時常考慮控制廣告中可點擊的區域,以避免發生用戶意外點擊的情況。若要進一步瞭解空白處不可點擊的相關規定,請參閱 Audience Network SDK 政策頁面。



  5. 選擇建立目標為裝置,並執行上述程式碼,您就會看到類似下方的內容:



在模擬器中刊登廣告時,請變更設定至測試模式以查看測試版廣告。請參閱如何使用測試模式以瞭解詳情。

第 3 步:如何取得內容的長闊比例並套用自然的寬度與高度

在上方的範例中,廣告的影音素材內容位於 adCoverMediaView,而其物件類型為 FBMediaView。從先前的步驟中,我們已說明如何使用 FBMediaView 從特定的 FBNativeAd 物件載入影音素材內容。這個檢視項目會取代手動載入封面圖像。建立 FBMediaView 時,其寬度與高度可透過在 Storyboard 中設定自動版面限制調整,或是透過硬式編碼設定。不過,檢視項目的寬度與高度不一定能貼合稍後下載的實際封面圖像。若要解決這個問題,請參考以下範例,了解如何取得內容的長闊比例並套用自然的寬度與高度:

  1. 宣告您的檢視控制器將會執行 FBMediaViewDelegate 通訊協定
    class ViewController: UIViewController, FBNativeAdDelegate, FBMediaViewDelegate {
      ...
    }
    @interface ViewController : UIViewController <FBNativeAdDelegate, FBMediaViewDelegate>
    ...
    @end

  2. 載入原生廣告後,將 FBMediaView 物件的委派設定為檢視控制器
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
      adCoverMediaView.delegate = self
    }
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd 
    {
      self.adCoverMediaView.delegate = self;
    }

  3. 在檢視控制器中執行 mediaViewDidLoad 方法
    func mediaViewDidLoad(_ mediaView: FBMediaView) {
      let currentAspect = mediaView.frame.size.width / mediaView.frame.size.height
      print(currentAspect)
      
      let actualAspect = mediaView.aspectRatio
      print(actualAspect)
    }
    - (void)mediaViewDidLoad:(FBMediaView *)mediaView
    {
      CGFloat currentAspect = mediaView.frame.size.width / mediaView.frame.size.height;
      NSLog(@"current aspect of media view: %f", currentAspect);
      
      CGFloat actualAspect = mediaView.aspectRatio;
      NSLog(@"actual aspect of media view: %f", actualAspect);
    }

    mediaView.aspectRatio 會傳回正數的 CGFloat;若目前沒有載入廣告,則會傳回 0.0。影音素材畫面載入後,其值就會生效。另外也有其他比較便利的方法,可以將 FBMediaView 物件的寬度與高度設定為載入的影音素材內容的長闊比例設定。您可以呼叫 applyNaturalWidthapplyNaturalHeight 以更新 FBMediaView 物件的寬度或高度,以貼合影音素材內容的長闊比例。

第 4 步:驗證展示及點擊記錄

您可自行選擇新增以下函數,以處理原生廣告關閉或用戶點擊廣告的情況

func nativeAdDidClick(_ nativeAd: FBNativeAd) {
  print("Native ad was clicked.")
}

func nativeAdDidFinishHandlingClick(_ nativeAd: FBNativeAd) {
  print("Native ad did finish click handling.")
}

func nativeAdWillLogImpression(_ nativeAd: FBNativeAd) {
  print("Native ad impression is being captured.")
}
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
  NSLog(@"Native ad was clicked.");
}

- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
  NSLog(@"Native ad did finish click handling.");
}

- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
  NSLog(@"Native ad impression is being captured.");
}

第 5 步:廣告無法顯示時的除錯方式

在您的檢視控制器中新增並執行下列兩個函數,以處理廣告載入錯誤

func nativeAd(_ nativeAd: FBNativeAd, didFailWithError error: Error) {
  print("Native ad failed to load with error: \(error.localizedDescription)")
}
- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error
{
  NSLog(@"Native ad failed to load with error: %@", error);
}

第 6 步:在不使用自動快取的情況下載入廣告

  1. 我們強烈建議您在任何情況下都將影音素材快取功能預設為開啟。但是,我們允許您覆寫預設設定。如果您決定覆寫預設影音素材快取,請務必小心操作
    let nativeAd = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
    nativeAd.delegate = self
    nativeAd.loadAd(withMediaCachePolicy: .none)
    FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
    nativeAd.delegate = self;
    [nativeAd loadAdWithMediaCachePolicy:FBNativeAdsCachePolicyNone];

  2. 首先,您需要手動下載原生廣告的所有影音素材
    func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
      
      ...
      
      self.adCoverMediaView.delegate = self
      nativeAd.downloadMedia()
      self.nativeAd = nativeAd
      
      ...
    }
    - (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
    {
      ...
    
      self.adCoverMediaView.delegate = self;
      [nativeAd downloadMedia];
      self.nativeAd = nativeAd;
    
      ...
    }

  3. 之後,請僅呼叫 registerViewForInteraction,並在完成 mediaViewDidLoad 回呼後展示廣告。所有影音素材都需要載入,才算是一次符合資格的廣告展示
    func mediaViewDidLoad(_ mediaView: FBMediaView) {
      guard let nativeAd = nativeAd else {
        return
      }
      
      // 1. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
      // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
      nativeAd.registerView(
        forInteraction: adUIView,
        mediaView: mediaView,
        iconView: adIconImageView,
        viewController: self,
        clickableViews: [adCallToActionButton, mediaView]
      )
        
      // 2. Render the ad content onto the view
      adTitleLabel.text = nativeAd.advertiserName
      adBodyLabel.text = nativeAd.bodyText
      adSocialContextLabel.text = nativeAd.socialContext
      sponsoredLabel.text = nativeAd.sponsoredTranslation
      adCallToActionButton.setTitle(nativeAd.callToAction, for: .normal)
      adOptionsView.nativeAd = nativeAd
    }
    - (void)mediaViewDidLoad:(FBMediaView *)mediaView 
    {
      if (!self.nativeAd) {
        return;
      }
    
      // 1. Register what views will be tappable and what the delegate is to notify when a registered view is tapped
      // Here only the call-to-action button and the media view are tappable, and the delegate is the view controller
      [self.nativeAd registerViewForInteraction:self.adUIView
                                      mediaView:mediaView
                                       iconView:self.adIconImageView
                              viewController:self
                             clickableViews:@[self.adCallToActionButton, mediaView]];
    
      // 2. Render the ad content onto the view
      self.adTitleLabel.text = self.nativeAd.advertiserName;
      self.adBodyLabel.text = self.nativeAd.bodyText;
      self.adSocialContextLabel.text = self.nativeAd.socialContext;
      self.sponsoredLabel.text = self.nativeAd.sponsoredTranslation;
      [self.adCallToActionButton setTitle:self.nativeAd.callToAction forState:UIControlStateNormal];
      self.adOptionsView.nativeAd = self.nativeAd; 
    }

後續步驟

  • 探索程式碼範例,瞭解如何使用原生廣告。SDK 在 NativeAdSample 資料夾中提供了 FBAudienceNetwork/samples。以 Xcode 開啟專案,然後在裝置或模擬器上執行該專案。

其他資源

新手指南

Audience Network 入門技術指南

程式碼範例

Audience Network 廣告整合範例

常見問題

Audience Network 常見問題

原生廣告範本

這是個較為輕鬆的原生廣告整合方法