anz blog

AdMob NativeAdのIBOutlet貼れない問題

あるよね?(笑)

環境

  • macOS Big Sur v11.4
  • Xcode v12.5
  • Google-Mobile-Ads-SDK v8.5

問題

Admob の Native フォーマットの実装周りを調査・検証するたみに、とりあえず軽く実装してみようかと思い、ドキュメント見つつやっていました。
Native フォーマットは初めて触るものの、AdMob は初めてというわけでもないので、まぁすんなり軽く動きを見るぐらいの実装はできると高をくくっていました。
ところが、カスタムViewをつくる手順でドハマりました。

手順的には xib で View を用意したら class には GADNativeAdView を指定して、そして必要は View などを設置、その後 IBOutlet で接続するという手順です。カスタムView を作るときの至って普通の手順です。
が、GADNativeAdView を class に指定して Assistant を開いても、GADNativeAdView は開かれないのです。しかたがないので、Auto ではなく自分で選択して GADNativeAdView を開いたとしても、ドラッグ等で接続することができないのです。

GADNativeAdView のサブクラスで別Viewを定義したとしても、必要な headlineView なんかを override することができないですし、GADNativeAdView を一旦無視して普通の UIView のサブクラスを用意してやったとしても、表示はできても imp とか click を記録できないので意味がないですし…
こまったな…どうしよう?っていう状態に陥りました。

回避策

自分が試した回避策を先に書いておきますと、

  • 一旦 Google-Mobile-Ads-SDK の 7.x を一旦入れます
  • ドキュメントの手順に沿ってViewを構築する際、class には GADUnifiedNativeAdView を指定します
  • Viewを構築して必要な IBOutlet を接続します
  • ビルドが通ることを確認します
  • Google-Mobile-Ads-SDK の最新版、今なら 8.5 を入れます
  • ビルドし直します

要は v7.x で一旦実装して v8.x に上げてマイグレーション(リネーム)しようという流れです。
これで最新版での動作確認ができるようになりました!

別解

こちらの Qiita の記事 にあるような手順でもできるそうです。
(僕は試していないので…「らしい」という感じですが)

なんかライブラリからファイルの中身をコピってきて組み込むというのが、ちょっと個人的に抵抗感強かったので採用しなかった感じです。

別解その2

最初の手順で書いてあるとおり、v7.x で GADUnifiedNativeAdView を使っておけば問題なくできるので、v7.x を使っておくという感じです。
ドキュメントの GADNativeAdViewGADUnifiedNativeAdView に置き換えて読めばほぼそのままでできそうです。たぶん(笑)

v8.x はメジャーバージョンが変わってるだけあって破壊的な変更も結構多くあるので、もう少し様子見ようかな?という考えです。
ただ、個人的にはよほど回避できない理由がない限りは最新バージョンを極力使いたいので、今回は一応回避策があったので採用はしませんでした。
広告周りはいろいろ変化が激しいので、SDKを最新に保っておきたい気持ちもありますね…

iOS 14 から推奨されている SKAdNetwork 対応版はこちらにあるとおり v7.64.0+ で対応されているので、いまいまで v8.x にしなければならない理由はおそらくはないかと思いますが。

ゴニョゴニョした話

上記までで、回避策は示したので、ここからは最初に紹介した回避策に至るまでの流れです。
読んでもとくにえられるものはありません(笑)

この問題に遭遇したときには、やれやれまたドキュメントが古いのかな?とかおもってサンプルコードを探し出し見てみました。

このリポのNativeAdvancedExampleというのが対象かと思います。

こちらで生成されている xib を見ると、たしかにちゃんと接続できていました。Podfile.lock を見てみると v8.2 と少しだけ古いですが、8.0+ なので参考にして問題なさそうでした。
そしてコードをざっくり見直してみても、なにかドキュメントに無いようなコードとか設定はなさそうでした。
いよいよ詰まったなーと思っていたところ、ちょっと古いバージョンのサンプルも見てみたのです。
(っていうか、リリースタグちゃんとうって 笑)

みてみると、先程みた v8.2 のものと xib まわりはほぼほぼ一緒だという事に気づいたのです。
class 名が GADNativeAdViewGADUnifiedNativeAdView の違いぐらいしかないのでは?という感じです。
実際リファレンスをみると、名前が違うだけで構成されている View は一緒の構成のように見えます。

そしてそれを示すように v8 へのマイグレーションのドキュメントにクラス名の変更という項目があり、どうやらリネームしただけのようという確証を得ました。

そして v8.x のサンプルコードで xib をよくよくみると、Outlets 部分を見るとたしかに接続されているという表示なのですが、Warning のアイコンが出ているのです(警告の内容はみえないのだけれど)

IBOutletの接続はできてるけどWarningが出ている

これらのことから、v7.x の GADUnifiedNativeAdView でつくってから、v8.x へ上げてリネームしたらいけるのでは?
このサンプルリポで作業した人も同じことしてっから、この問題に気づけていないのでは?
(いや、iOSかXcodeのバグという話もみたので、気づけても対応できないから放置しているかもですが...それだとしてもドキュメントに注釈ほしいけど)
と推測して、やってみたら無事に動いたという感じです。

あらためて書いてるとこれはこれで不安な通し方な気もしてきますね...v7.x の最新版使っておこうかな🤔

いやーこんなことしてたので、ただうごきをみるだけなのに結構時間とられちゃいました...。
広告周りの実装はやっぱしんどいですねー

参考