cocos2dx-3.9 在iOS上整合admob

峻峰飛陽發表於2016-09-20

Part 1: 安裝GoogleMobileAds framework (即admob)

  1. 安裝Cocoapods,否則解決依賴關係和配置真的會把人不累死也得煩死

    sudo gem install cocoapods

    國內使用者安裝過程中可能遇到SSL連線出錯的問題,請參考 Cocoapod安裝過程中的么蛾子

  2. 在 xxx.xcodeproj 同級目錄下,加入新檔案Podfile,內容如下:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '7.0'
pod 'Google-Mobile-Ads-SDK', '~> 7.5'

source 指定pod從哪裡去下載新的framework
platform指定引入的工程使用平臺版本, 這個版本號可能會高於cocos2dx建立出的預設最低版本,需要注意

pod一行指定取哪個版本的sdk

  1. 關閉Xcode中開啟的xxx.xcodeproj, 在Podfile所在目錄下使用命令 pod update

  2. 現在Podfile目錄下多出了xxx.xcworkspace, Podfile.lock, Pods幾個檔案或資料夾,使用Xcode開啟xxx.xcworkspace, 然後編譯

  3. 如果編譯沒出錯,那麼就可以繼續咯!

Part2: 使用admob

在此之前,你應該先去讀一下 https://github.com/googleads/googleads-mobile-ios-examples 中的原始碼,看一下官方對Banner和Interstitial給出的示例。具體的程式碼照抄就可以了。

首先,官方案例是這麼import framework的:

@import GoogleMobileAds;

… bla bla~
然後在cocos2dx的工程中,你如果這麼寫,肯定會提示模組沒被啟用,如果你真要這麼寫,那就去Build Settings裡面把modules啟用好了

你可能會希望在.h中宣告一個C++類,然後在一個.mm中引入GoogleMobileAds,實現一個內部類,然後再用一個struct橋接到C++以供C++程式碼呼叫?放棄這種方式吧,因為:

@import語法只能在Objective-C中使用,目前Objective-C++不支援這種語法,哪怕你只是把副檔名改成.mm也不行

所以可以代替的辦法是醬紫:

#import <GoogleMobileAds/GoogleMobileAds.h>

基於一些以我目前水平無法解答的原因,我無法在一個.mm中引入GoogleMobileAds中的類,所以最後只好單獨在一套.h/.m檔案中實現一個Objective-C的類,然後在一個專門的.h/.mm中實現一個C++類橋接之。

關於橋接:

C++類無法直接把一個Objective-C的類作為成員引數,所以一般辦法是,在 .h中:

複製程式碼

struct AdBannerBridge;

class AdBanner
{
     //...
     AdBanner();
     ~AdBanner();
     protected:
     AdBannerBridge* _adBridge;
}

複製程式碼
然後在.mm中,就可以順理成章的引用Objective-C的實體了:

複製程式碼

struct AdBannerBridge
{
      GoogleAd* _googleAd;
      AppleAd* _appleAd;

      AdBannerBridge()
      {
             _appleAd = [[AppleAd alloc]init];
             //...
      }

      ~AdBannerBridge()
      {
              if( _appleAd != nil ) { 
                     [_appleAd release];
              }
              //...
      }
}

AdBanner::AdBanner()
{
    _adBridge = new AdBannerBridge();
}

AdBanner::~AdBanner()
{
     if( _adBridge ) {
         delete _adBridge; 
     }
}

複製程式碼
編譯Objective-C++時, Objective-C的注入@interface/@implementation/@protocol當然是按照Objective-C的方式編譯的,其它部分都是按照C++語法編譯的。C++中struct本質上就是class,所以這裡可以藉助這個特性直接在建構函式和解構函式裡完成分配和回收工作,免得程式碼寫的太長。

GoogleMobileAds使用還是蠻簡單的,解析example中的一部分程式碼:

複製程式碼

- (void)viewDidLoad {
  [super viewDidLoad];

  // Replace this ad unit ID with your own ad unit ID.
  self.bannerView.adUnitID = @"ca-app-pub-3940256099942544/2934735716";
  self.bannerView.rootViewController = self;

  GADRequest *request = [GADRequest request];
  // Requests test ads on devices you specify. Your test device ID is printed to the console when
  // an ad request is made. GADBannerView automatically returns test ads when running on a
  // simulator.
  request.testDevices = @[
    @"01d5d30957fabc2cce72c5559550686e"  // Eric's iPod Touch
  ];
  [self.bannerView loadRequest:request];
}

複製程式碼

  1. adUnitID 在開發時應該換成自己的ad unit ID

  2. Google政策上禁止開發期間點選自己的廣告,不過測試廣告還是可以點的。指定testDevices之後,在這些testDevices上執行時,都會返回一個測試廣告,這個測試廣告是可以點選的。

    testDevice的ID可以先直接變異執行,該ID會在log中顯示出來。

  3. 如果Delegate已經呼叫adViewDidReceiveAd,但是廣告卻顯示一個0,那麼很可能是因為GFW間歇性發作,你被牆了!可以在測試裝置上開啟VPNFQ測試

  4. 我在一個.h/.m中實現的GoogleMobileAd呼叫,但是希望在delegate中能夠呼叫C++部分的pause/resume來處理使用者點選廣告但是沒有離開程式的情形,這時候可以通過傳遞程式碼塊來解決

相關文章