5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutter で AdMob ネイティブ広告を実装する (iOS)

Last updated at Posted at 2022-12-16

やりたいこと

Flutter で AdMob のネイティブ広告(Native Ad)を導入したい。
codelabs にわかりやすく実装手順がまとまっているが、いくつか詰まったので共有。

環境

  • flutter: 3.3.9
  • google_mobile_ads: ^2.3.0

実装

基本的には codelab を順当に進め、最後の “iOS 用の NativeAdFactory を実装する (Swift)” を見ればいける。
ただ、そのまま実装してもエラーになってしまう。
とりまちゃっちゃと実装して以下のエラーに会いに行こう。

info.plist に SKAdNetWork の設定が必要

まず実行すると、SKAdNetWork の設定が info.plist にないぞって言われる。
こちらの記事を確認し SKAdNetworkItemsinfo.plist にコピペすれば OK。
やたら多いけど全部必要なのでコピペしよう。

テスト用を使う場合は AppDelegate に追記が必要

次は、実機で実行する。以下のようなエラー文が表示されるはず。

GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [ "任意のデバイスID?" ]

表示通りに AppDelegate に追記してあげる

import UIKit
import Flutter

import google_mobile_ads

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    
    let ad = NativeAdPostThumbnail()
    FLTGoogleMobileAdsPlugin.registerNativeAdFactory(
        self, factoryId: "admobPostThumbnail", nativeAdFactory: ad)
    
    // これを追記
    GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [ "任意のデバイスID?" ]
    // ここまで

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

これで何故か実機はもちろんエミュでもちゃんと動くようになる。よくわからん。
これでも問題があったら、こちらのスレッドを見る限り AdMob UI 上から直接デバイスIDを登録すればよさそう。

ListTileNativeAdView.xib に GADUnifiedNativeAdView クラスを適切に接続してあげる

また実行すると、GADUnifiedNativeAdView が見つからない的なエラーが出る。
CodeLab の ListTileNativeAdView.xib は Custom Class で GADUnifiedNativeAdView を参照しているが、どうやら見つからないっぽい。
実際試してみても GADUnifiedNativeAdView が出てこない...

スクリーンショット 2022-12-16 11.10.30.png

というわけで、こちらの回答をもとに GADNativeAd.h というヘッダーファイルを作成。

スクリーンショット 2022-12-16 11.16.05.png

あとは回答のコメントにあるこちらの記事の中身をコピペ。一応以下にも示す。

//
//  GADNativeAd.h
//  Google Mobile Ads SDK
//
//  Copyright 2017 Google LLC. All rights reserved.
//

#ifndef GADNativeAd_h
#define GADNativeAd_h

#endif /* GADNativeAd_h */

#import <Foundation/Foundation.h>
#import <GoogleMobileAds/GADAdChoicesView.h>
#import <GoogleMobileAds/GADAdLoaderDelegate.h>
#import <GoogleMobileAds/GADAdValue.h>
#import <GoogleMobileAds/GADMediaContent.h>
#import <GoogleMobileAds/GADMediaView.h>
#import <GoogleMobileAds/GADMuteThisAdReason.h>
#import <GoogleMobileAds/GADNativeAdAssetIdentifiers.h>
#import <GoogleMobileAds/GADNativeAdDelegate.h>
#import <GoogleMobileAds/GADNativeAdImage.h>
#import <GoogleMobileAds/GADResponseInfo.h>
#import <GoogleMobileAds/GADVideoController.h>
#import <UIKit/UIKit.h>

/// Native ad. To request this ad type, pass kGADAdLoaderAdTypeNative
/// (see GADAdLoaderAdTypes.h) to the |adTypes| parameter in GADAdLoader's initializer method. If
/// you request this ad type, your delegate must conform to the GADNativeAdLoaderDelegate
/// protocol.
@interface GADNativeAd : NSObject

#pragma mark - Must be displayed if available

/// Headline.
@property(nonatomic, readonly, copy, nullable) NSString *headline;

#pragma mark - Recommended to display

/// Text that encourages user to take some action with the ad. For example "Install".
@property(nonatomic, readonly, copy, nullable) NSString *callToAction;
/// Icon image.
@property(nonatomic, readonly, strong, nullable) GADNativeAdImage *icon;
/// Description.
@property(nonatomic, readonly, copy, nullable) NSString *body;
/// Array of GADNativeAdImage objects.
@property(nonatomic, readonly, strong, nullable) NSArray<GADNativeAdImage *> *images;
/// App store rating (0 to 5).
@property(nonatomic, readonly, copy, nullable) NSDecimalNumber *starRating;
/// The app store name. For example, "App Store".
@property(nonatomic, readonly, copy, nullable) NSString *store;
/// String representation of the app's price.
@property(nonatomic, readonly, copy, nullable) NSString *price;
/// Identifies the advertiser. For example, the advertiser’s name or visible URL.
@property(nonatomic, readonly, copy, nullable) NSString *advertiser;
/// Media content. Set the associated media view's mediaContent property to this object to display
/// this content.
@property(nonatomic, readonly, nonnull) GADMediaContent *mediaContent;

#pragma mark - Other properties

/// Optional delegate to receive state change notifications.
@property(nonatomic, weak, nullable) id<GADNativeAdDelegate> delegate;

/// Reference to a root view controller that is used by the ad to present full screen content after
/// the user interacts with the ad. The root view controller is most commonly the view controller
/// displaying the ad.
@property(nonatomic, weak, nullable) UIViewController *rootViewController;

/// Dictionary of assets which aren't processed by the receiver.
@property(nonatomic, readonly, copy, nullable) NSDictionary<NSString *, id> *extraAssets;

/// Information about the ad response that returned the ad.
@property(nonatomic, readonly, nonnull) GADResponseInfo *responseInfo;

/// Called when the ad is estimated to have earned money. Available for allowlisted accounts only.
@property(nonatomic, nullable, copy) GADPaidEventHandler paidEventHandler;

/// Indicates whether custom Mute This Ad is available for the native ad.
@property(nonatomic, readonly, getter=isCustomMuteThisAdAvailable) BOOL customMuteThisAdAvailable;

/// An array of Mute This Ad reasons used to render customized mute ad survey. Use this array to
/// implement your own Mute This Ad feature only when customMuteThisAdAvailable is YES.
@property(nonatomic, readonly, nullable) NSArray<GADMuteThisAdReason *> *muteThisAdReasons;

/// Registers ad view, clickable asset views, and nonclickable asset views with this native ad.
/// Media view shouldn't be registered as clickable.
/// @param clickableAssetViews Dictionary of asset views that are clickable, keyed by asset IDs.
/// @param nonclickableAssetViews Dictionary of asset views that are not clickable, keyed by asset
///        IDs.
- (void)registerAdView:(nonnull UIView *)adView
       clickableAssetViews:
           (nonnull NSDictionary<GADNativeAssetIdentifier, UIView *> *)clickableAssetViews
    nonclickableAssetViews:
        (nonnull NSDictionary<GADNativeAssetIdentifier, UIView *> *)nonclickableAssetViews;

/// Unregisters ad view from this native ad. The corresponding asset views will also be
/// unregistered.
- (void)unregisterAdView;

/// Reports the mute event with the mute reason selected by user. Use nil if no reason was selected.
/// Call this method only if customMuteThisAdAvailable is YES.
- (void)muteThisAdWithReason:(nullable GADMuteThisAdReason *)reason;

@end

#pragma mark - Protocol and constants

/// The delegate of a GADAdLoader object implements this protocol to receive GADNativeAd ads.
@protocol GADNativeAdLoaderDelegate <GADAdLoaderDelegate>
/// Called when a native ad is received.
- (void)adLoader:(nonnull GADAdLoader *)adLoader didReceiveNativeAd:(nonnull GADNativeAd *)nativeAd;
@end

#pragma mark - Unified Native Ad View

/// Base class for native ad views. Your native ad view must be a subclass of this class and must
/// call superclass methods for all overridden methods.
@interface GADNativeAdView : UIView

/// This property must point to the native ad object rendered by this ad view.
@property(nonatomic, strong, nullable) GADNativeAd *nativeAd;

/// Weak reference to your ad view's headline asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *headlineView;
/// Weak reference to your ad view's call to action asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *callToActionView;
/// Weak reference to your ad view's icon asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *iconView;
/// Weak reference to your ad view's body asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *bodyView;
/// Weak reference to your ad view's store asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *storeView;
/// Weak reference to your ad view's price asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *priceView;
/// Weak reference to your ad view's image asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *imageView;
/// Weak reference to your ad view's star rating asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *starRatingView;
/// Weak reference to your ad view's advertiser asset view.
@property(nonatomic, weak, nullable) IBOutlet UIView *advertiserView;
/// Weak reference to your ad view's media asset view.
@property(nonatomic, weak, nullable) IBOutlet GADMediaView *mediaView;
/// Weak reference to your ad view's AdChoices view. Must set adChoicesView before setting
/// nativeAd, otherwise AdChoices will be rendered according to the preferredAdChoicesPosition
/// defined in GADNativeAdViewAdOptions.
@property(nonatomic, weak, nullable) IBOutlet GADAdChoicesView *adChoicesView;

@end

んで、ListTileNativeAdView.xib に戻って Custom Class に GADNativeAdView ってのが出てくるようになるはずなので、それを指定。
これで完了。

完成

スクリーンショット 2022-12-16 11.04.03.png

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?