Mapbox 地図にMapbox広告を表示してみよう iOS編
この記事は Mapbox Advent Calendar 2022 の 21日目の記事です。
はじめに
本記事はMapbox地図の上にMapbox広告を表示してみよう!という内容です。もしまだMapbox地図を使ったことがないという方は、下記の記事を参考に地図を表示するところから挑戦してみいただければと思います!
Mapbox広告とは
広告の表示方法の前に簡単にMapbox広告について紹介させていただきたいと思います。
Mapbox広告とは、現在マップボックス・ジャパン合同会社が主導して開発を進めている、デジタル地図上に広告を配信することができる、新しい形の広告プラットフォームです。
現在Mapbox広告として採用しているのは「プロモーテッド・ピン」という種類の広告になります。プロモーテッド・ピンは、地図上に広告主任意のデザインの広告ピンを表示でき、アプリユーザがピンをタップすると広告カードが表示されます。
広告カードには、基本情報はもちろん、動画バナーやお得なニュース、商品情報、写真などが表示されます。(表示内容は広告掲載プランによって異なります。広告について詳しくはこちらからお願いします)
このように広告主のピンやカードを表示することで、地図を利用したサービスでも簡単にマネタイズにつなげることが可能です。(マネタイズの詳細についてもこちらにお願いします)
地図に広告を表示してみよう
Mapbox広告を利用するには、Mapbox Ads SDKを使うことで簡単に実装が可能になっています。
Mapbox Ads SDK for iOS の 入手方法
早速試してみたい!と思われた方大変申し訳ありません。Mapbox Ads SDK for iOS は現在まだ非公開のSDKとなっておりますので、まずはこちらからご連絡をお願いします。
今後の開発予定にモジュールの公開(CocoapodsとSwift Package Manager)と、ソースコードのOSS化も検討しています。
Mapbox Ads SDK for iOS の 利用条件
Mapbox Ads SDK for iOS
は現状 Cocoapodsインストール の Mapbox Maps SDK for iOS
へのみ対応しております。
Mapbox Maps SDK for iOS
は Swift Package Manager をサポートを開始しているため、Mapbox Ads SDK for iOS
についても開発を進めております。
準備 その1
さて、SDKを入手された方は以下より先に進んで頂ければと思います。
SDKは、.xcframework
という拡張子となっております。こちらのファイルを Xcode上の任意のフォルダ(ここではFrameworksとします)にドラッグアンドドロップします。
すると、以下のようなウィンドが表示されるので、チェックを入れてFinishボタンを押します。
ファイルがコピーされていることを確認します。
プロジェクトファイル > Targets > アプリのスキーマ -> Frameworks, Libraries, and Embeded Content を確認して、.xcframework
が追加されているので、Embed 設定を Do Not Embed
から Embed & Sign
へ変更する
準備 その2
つづいて、以下の記述を Podfile
へ追記して、 pod install
します。
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
target 'MapboxPromotedAdsDemo' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
pod 'MapboxMaps', '10.9.1'
end
+ post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
+ end
+ end
+ end
導入 その1
SDKのインストールが完了したので、広告を表示するソースコードを記載していきます。
まずは、SDK本体となる MapboxPromotionManager
を以下のように初期化します。初期化するタイミングは、必ず 地図画面が表示される画面が初期化されるタイミングで行うようにしてください。
...
+ import MapboxPromoted
class ViewController: UIViewController {
...
+ private let promotionsManager = MapboxPromotionManager()
...
}
導入 その2
続いて、MapboxPromotionDelegate
を実装してSDKからの必要なコールバックを記述していきます。これらは、広告ピンが表示され、アプリのユーザがピンをタップした際に表示される広告カードの表示やユーザアクションのコールバックをアプリ側へ通知されるために使用されます。各デリゲートメソッドの解説はこちらをご確認ください。
extension ViewController: MapboxPromotionDelegate {
func promotionManager(
_: MapboxPromotionManager,
didSelect card: MapboxPromotedMBPCardView,
promotion: MapboxPromotion
){
card.attach(to: view, animated: true, completion: nil)
}
func promotionManager(
_: MapboxPromotionManager,
didDeselect card: MapboxPromotedMBPCardView,
promotion _: MapboxPromotion
){
card.detach(from: view, animated: true)
}
func promotionManager(
_: MapboxPromotionManager,
showAttribution controller: MapboxAdsAttributionViewController
){
present(controller, animated: true, completion: nil)
}
func promotionManager(
_: MapboxPromotionManager,
closeAttribution controller: MapboxAdsAttributionViewController
){
controller.dismiss(animated: true)
}
func promotionManager(
_: MapboxPromotionManager,
didTapCard action: MapboxPromotedMBPCardTapAction,
promotion: MapboxPromotion
){
print("didTapCard: \(action)")
}
func promotionManager(
_: MapboxPromotionManager,
didTransitionCard state: MapboxPromotedMBPCardTransition
){
print("did transition state:\(state)")
}
}
導入 その3
ここまでくればもうすぐ完了です。Mapのロードが完了した(mapLoaded
)タイミングで、loadPromotions
を呼び出して広告のロードしましょう。その際、必ず .staging
環境を指定しましょう。
override public func viewDidLoad() {
super.viewDidLoad()
....
+ mapView.mapboxMap.onNext(event: .mapLoaded) { [weak self] _ in
+ guard let self = self,
+ let mapView = self.mapView,
+ let layer = mapView.mapboxMap.style.allLayerIdentifiers.last?.id else {
+ return
+ }
+
+ self.promotionsManager.loadPromotions(
+ for: mapView,
+ below: layer, // 任意のレイヤーの下に表示したい場合に指定
+ with: .staging) // Staging 環境を指定
+ self.promotionsManager.delegate = self // その2で実装したMapboxPromotionDelegateを設定する
+ }
}
実行結果
実行結果は以下のようになります。Staging環境のため表示されているピンや広告カードの内容は仮のものになります。
広告ピン | 広告カード1 | 広告カード2 |
---|---|---|
![]() |
![]() |
![]() |
コード全体
最後に ViewController.swift
のコード全体は以下になります
import UIKit
import MapboxMaps
import MapboxPromoted
class ViewController: UIViewController {
internal var mapView: MapView!
private let tokyoStation = CLLocationCoordinate2D(latitude: 35.6812, longitude: 139.7671)
private let promotionsManager = MapboxPromotionManager()
override public func viewDidLoad() {
super.viewDidLoad()
let token = Bundle.main.object(forInfoDictionaryKey: "MBXAccessToken") as? String ?? ""
let option = MapInitOptions(
resourceOptions: ResourceOptions(accessToken: token),
cameraOptions: CameraOptions(center: tokyoStation, zoom: 14.5)
)
mapView = MapView(frame: view.bounds, mapInitOptions: option)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.view.addSubview(mapView)
mapView.mapboxMap.onNext(event: .mapLoaded) { [weak self] _ in
guard let self = self,
let mapView = self.mapView,
let layer = mapView.mapboxMap.style.allLayerIdentifiers.last?.id else {
return
}
self.promotionsManager.loadPromotions(
for: mapView,
below: layer, // this is optional
with: .staging) // ".staging" for development or ".production" for production.
self.promotionsManager.delegate = self
}
}
}
extension ViewController: MapboxPromotionDelegate {
func promotionManager(
_: MapboxPromotionManager,
didSelect card: MapboxPromotedMBPCardView,
promotion: MapboxPromotion
){
card.attach(to: view, animated: true, completion: nil)
}
func promotionManager(
_: MapboxPromotionManager,
didDeselect card: MapboxPromotedMBPCardView,
promotion _: MapboxPromotion
){
card.detach(from: view, animated: true)
}
func promotionManager(
_: MapboxPromotionManager,
showAttribution controller: MapboxAdsAttributionViewController
){
present(controller, animated: true, completion: nil)
}
func promotionManager(
_: MapboxPromotionManager,
closeAttribution controller: MapboxAdsAttributionViewController
){
controller.dismiss(animated: true)
}
func promotionManager(
_: MapboxPromotionManager,
didTapCard action: MapboxPromotedMBPCardTapAction,
promotion: MapboxPromotion
){
print("didTapCard: \(action)")
}
func promotionManager(
_: MapboxPromotionManager,
didTransitionCard state: MapboxPromotedMBPCardTransition
){
print("did transition state:\(state)")
}
}
最後に
いかがでしょうか?思ったよりも簡単に表示できるなと感じていただけたのではないでしょうか?
まだ未公開な部分もありますが、順次公開に向けて進めております。もし地図サービスのマネタイズに興味のある方、地図上に広告を出してみたい方は下記から問い合わせをお願いします!
各デリゲートメソッドについての解説
MapboxPromotionDelegateのデリゲートメソッドについての解説です。
メソッド | 解説 |
---|---|
didSelect | 広告のピンをタップした際に呼び出されます。サンプルのようにMapboxPromotedMBPCardView#attach を使用してviewを渡すことで、広告カードを表示させることができます。 |
didDeselect | 広告カードが表示されている状態で、地図エリアがタップされた際など広告カードを閉じる必要がある際に呼び出されます。MapboxPromotedMBPCardView#detach を呼び広告カードを閉じることができます。 |
showAttribution | 広告カード内にある「広告」ボタンがタップされた際に呼び出されます。広告に関する説明ViewとしてMapboxAdsAttributionViewController の表示できます。 |
closeAttribution | 広告に関する説明View内にある「完了」ボタンがタップされたら呼び出されます。MapboxAdsAttributionViewController の非表示できます。 |
didTapCard | 広告カード内にあるその他各種ボタン(詳細はこちら)がタップされたら呼び出されます。下記の詳細を参考に各ボタンタップの際に追加で処理を行いたい場合は追加できます。なお、MapboxPromotedMBPCardTapActionオブジェクトが externalLink の場合はURL情報が内包されていますので、基本的外部ブラウザ等で表示することが可能です。 |
didTransitionCard | 広告カードの状態が変更になった際に呼び出されます。全画面表示(expanded), 画面下部表示(collapsed), 非表示(closed)の状態が通知されます。 |
各種タップイベントの種類
MapboxPromotedMBPCardTapActionの各イベントについての解説です。
タイプ | 説明 |
---|---|
route | カード内の「経路」ボタンをタップ時に呼ばれます。ルート検索画面を表示してください。 |
navigation | カード内のナビゲーション表示のアクション時に呼ばれます。ナビゲーション画面を表示してください。(現在ナビゲーションボタンは非表示になっています) |
businessHours | カード内の営業時間の項目をタップした時に呼ばれます。営業時間の項目が開閉されます。特に実装の必要はありません。 |
address | カード内の住所の項目をタップした時に呼ばれます。特に実装の必要はありません。 |
externalLink | カード内の各種外部リンクボタンをタップ時に呼ばれます。下記を参考に、外部ブラウザ/内部ブラウザへの遷移を行なってください。 |
カード内の各種外部リンクボタンの種類
MapboxPromotedMBPCardTapActionイベントがexternalLink場合のMapboxPromotedMBPCardLinkTypeについての解説です。
タイプ | 説明 | 備考 |
---|---|---|
call | カード内の「電話」ボタン/「電話」の項目をタップ時に呼ばれます。外部ブラウザへの遷移を行なってください。 | e.g. tel:03-0000-0000 |
banner | カード内のバーナー画像をタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://www.mapbox.jp/ads |
detailSite | カード内の「公式サイト」ボタン/公式サイトの項目をタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://www.mapbox.jp/ads |
attributionLink | カード内の「この広告について」の画面「Mapbox広告ページへ」をタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://www.mapbox.jp/ads |
line | カード内の「公式LINE」ボタンをタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://line.me/R/ |
appStore | カード内の「App Store」ボタンをタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://apps.apple.com/app-name |
カード内の「Twitter」ボタンをタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://twitter.com/page | |
カード内の「Facebook」ボタンをタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://facebook.com/page | |
カード内の「Instagram」ボタンをタップ時に呼ばれます。外部ブラウザ/内部ブラウザへの遷移を行なってください。 | e.g. https://instagram.com/page |
Discussion