2
4

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 3 years have passed since last update.

SwiftUIでAdMob対応(バナー編)

Last updated at Posted at 2021-03-25

要約

UIViewControllerRepresentableを使ってSwiftUIでいい感じにバナーを含んだ画面を表示します。

はじめに

SwiftUIでAdMobのバナーが表示したかったので、実装してみました。
AdMobの導入が済んでいる事が前提となります。
https://developers.google.com/admob/ios/quick-start?hl=ja

結果

こんな感じでプレビューでバナーが表示できました。

スクリーンショット 2021-03-25 16.35.32.png

Repository

概要

SwiftUIでAdMob対応をします。
手始めにバナーを表示します。

Life Cycle SwiftUI App対応

リポジトリではプロジェクトはSwiftUI Appでのプロジェクトになります。
AdMobはAppDelegateでGADMobileAds.sharedInstance().start(completionHandler: nil)の初期化を行う必要があるので、ひと手間必要です。

AppDelegateを作成し、プロジェクトのAppにUIApplicationDelegateAdaptorを追加して、AppDelegate内で初期化するようにします。

@main
struct SwiftUIAdMobApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        GADMobileAds.sharedInstance().start(completionHandler: nil)
        return true
    }
}

UIViewControllerRepresentableで広告表示用UIViewControllerを作成

AdMobのバナーには、広告の処理を行うためのフルスクリーンなrootViewControllerが必要です。
SwiftUI単体ではUIViewControllerを用意することができないため、これをUIViewControllerRepresentable経由で用意します。

ContainedAdViewControllerでUIViewControllerRepresentableに適合する処理を書きます。
makeUIViewControllerで提供するUIViewControllerはStoryboardで用意しました。

struct ContainedAdViewController<Content: View>: UIViewControllerRepresentable {
    let rootView: Content

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    func makeUIViewController(context: Context) -> UIViewController {
        let adViewController: AdViewController = UIStoryboard(name: "AdViewController", bundle: nil).instantiateInitialViewController()!
        adViewController.rootView = AnyView(rootView)
        return adViewController
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        
    }
    
    typealias UIViewControllerType = UIViewController
    
    class Coordinator: NSObject {
        var parent: ContainedAdViewController
        
        init(_ containedAdViewController: ContainedAdViewController) {
            parent = containedAdViewController
        }
    }
}

Storyboardの初期表示はAdViewControllerというUIViewController継承クラスで、その内部ではSwiftUIを表示するUIHostingControllerコンテナとその下で表示を行うバナーを格納しています。
広告バナーに対するrootViewControllerはAdViewControllerになります。

スクリーンショット 2021-03-25 16.53.26.png

SwiftUI側の表示

SwiftUI側はContainedAdViewControllerのrootViewに表示したいViewを実装すればOKです。

struct ContentView: View {
    var body: some View {
        ContainedAdViewController(rootView:
                                    Text("Hello, world!").padding()
        )
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

動作

表示できました。
Simulator Screen Shot - iPod touch (7th generation) - 2021-03-25 at 16.56.10.png

上記のRepositoryのコードはSceneもサポートしているので、複数画面でもばっちりアダプティブ広告が表示できます。
Simulator Screen Shot - iPad Pro (12.9-inch) (4th generation) - 2021-03-25 at 16.40.12.png

2
4
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
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?