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

您可以使用原生廣告 API 自行設計想要的應用程式廣告,打造出最符合需求的廣告體驗。原生廣告 API 不會直接提供可立即刊登的廣告,而是提供標題、圖像、行動呼籲等眾多廣告屬性,讓您使用這些屬性自行建構用以顯示廣告的自訂 UIView。

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

我們將實作以下原生廣告版位。您將針對原生廣告建立下列檢視。

檢視 #1:廣告主圖示

檢視 #2:廣告標題

檢視 #3:贊助標籤

檢視 #4:廣告主選擇

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

檢視 #6:社群元素

檢視 #7:廣告內文

檢視 #8:廣告行動呼籲按鈕


步驟 1:在腳本中建立原生廣告檢視

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

步驟 3:如何取得內容長寬比並套用實際寬度和高度

步驟 4:驗證曝光和點擊紀錄

步驟 5:未顯示廣告時如何偵錯

步驟 6:載入廣告,不自動快取

步驟 7:測試廣告整合

請前往變更記錄查看已知問題

步驟 1:在腳本中建立原生廣告檢視

繼續操作前,請務必詳閱 Audience Network 新手指南iOS 新手指南

設計原生廣告和橫幅廣告時,請務必遵守 iOS 版面準則,以提供最佳用戶體驗。

  1. 在您參考 iOS 新手指南建立新專案後,請開啟 Main.storyboard。將 UIView 元素新增至 View 元素,並將其命名為 adUIView


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


  3. 您可能會注意到檢視控制器場景(View Controller Scene)旁顯示紅色箭頭。這通常表示版面配置缺少限制。


    您需要選擇場景中的所有檢視物件,然後點擊「解決版面配置問題」圖示,以新增缺少的限制。


  4. 現在您已建立顯示原生廣告所需的所有用戶介面元素,您需要在 ViewController 介面中參照這些用戶介面元素。首先開啟 ViewController.m(若使用 Swift,則開啟 ViewController.swift),接著將 adUIView 拖曳至 ViewController 物件內,可將其命名為 adUIView。之後,您需要針對 adIconImageViewadTitleLabeladCoverMediaViewadSocialContextadCallToActionButtonadOptionsViewadBodyLabelsponsoredLabel 進行相同操作。


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

現在您已建立顯示原生廣告所需的所有用戶介面元素,下一步是載入原生廣告並將內容繫結到用戶介面元素。

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

  1. 在檢視控制器(View Controller)來源檔中,匯入 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 會取代手動載入封面圖像的方式。建立 FBMediaView 時,其寬度和高度可由腳本中的自動版面配置限制決定,或是採用硬式編碼設定。但是 FBMediaView 的寬度和高度可能與稍後下載的實際廣告封面圖像不相符。若要解決此問題,以下範例說明取得內容長寬比並套用實際寬度和高度的方式:

  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 在 FBAudienceNetwork/samples 資料夾中提供了 NativeAdSample。使用 Xcode 開啟該專案,然後在裝置或模擬器上執行。

其他資源

新手指南

開始使用 Audience Network 的技術指南

程式碼範例

Audience Network 廣告整合範例

常見問題

Audience Network 常見問題

原生廣告範本

減少手動設定的原生廣告整合方式