◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/アプリ開発
◇ アプリ開発/2026-05-24上級

Rork プロジェクトに AppLovin MAX を後付けした実装ノート — 初期化順序・ATT 同意・eCPM 検証の三軸メモ

Rork で組み立てた iOS アプリに AppLovin MAX を後付けする際の初期化順序、ATT 同意との噛み合わせ、AdMob との並走で eCPM を比較する実装メモを、個人開発の現場目線でまとめます。

Rork585AppLovin MAXAdMob73iOS115ATT9eCPM5メディエーション10

✦ プレミアム記事

個人でアプリ開発を 2014 年から続けている廣川政樹です。最近、Rork で叩き台を作った iOS アプリに AppLovin MAX を後付けする作業をしていて、想像していたよりも段取りが繊細でした。AdMob 単体運用を長くやってきた身からすると、初期化の順序ひとつで起動直後のバナーが沈黙したり、ATT 同意ダイアログの裏側で広告ネットワークの同意状態がずれたりと、検証しないと気付けない落とし穴がいくつもあります。

Rork は素早くアプリの骨格を吐き出してくれますが、収益化レイヤーは自分で組み上げる必要があります。本ノートは、累計 5,000 万 DL を超えた壁紙アプリ群の運用で蓄積した感覚を、Rork が出した雛形に流し込むときの実装手順としてまとめました。AdMob から AppLovin MAX へ「乗り換える」のではなく、AdMob メディエーション経由で AppLovin MAX を併走させ、運用しながら判断材料を集める方向性です。

なぜ AdMob 単体から AppLovin MAX 併走へ動いたか

きっかけは Beautiful HD Wallpapers の最新アップデートで、AdMob のバナーと AppOpen の eCPM が地域別に明確な天井に張り付いた日が連続したことでした。同じインプレッション量で 4 月の中旬から 5 月の初旬にかけて、米国とインドネシアの eCPM が前月比でそれぞれ約 18% と約 22% 沈んだ週がありました。フィルレートは 95% 以上を維持しているのに収益が落ちる状況で、メディエーションの分母を増やす実験を本気で検討する時期だと感じました。

AppLovin MAX は AdMob メディエーション経由で組み込む形にすると、既存の GoogleMobileAds の呼び出し側コードをほぼ触らずに済みます。私の場合、Rork が吐き出したコードベースは React Native ベースですが、iOS ネイティブのブリッジを薄く挟んでメディエーションを完結させる構成にしました。これにより JavaScript 側のロジックは AdMob のままで、ネイティブ側だけで AppLovin MAX を増設できる形にしています。

実体験として、SDK を 2 社並走させる場合に最も時間を持っていかれるのは、コードの追加そのものではなく初期化の順序と同意状態の同期です。本記事はここを重点的にメモします。

SwiftPM 経由で AppLovin MAX を入れるときの初期化順序

Rork が出力した iOS ターゲットに AppLovin MAX を SwiftPM で追加する場合、依存解決は Xcode の Package Dependencies から https://github.com/AppLovin/AppLovin-MAX-SDK-iOS を指定する手順で完結します。CocoaPods から SwiftPM への移行と並行している場合、Firebase 側の SPM 化を先に終わらせておくと Podfile と Package.resolved の衝突が起きません。Firebase SPM 移行については Apps/iOS Apps/_documents/firebase-cocoapods-to-spm-migration-plan-ja.md に作業手順をまとめてあるので、SPM 統一を済ませてから AppLovin MAX を足す順序にしています。

初期化の順序は、以下の流れを守るとアダプタ初期化のタイミング不整合を避けやすくなります。

  1. application(_:didFinishLaunchingWithOptions:) で Firebase の FirebaseApp.configure() を最初に呼ぶ
  2. ATT のリクエストを applicationDidBecomeActive(_:) に切り出して遅延起動する
  3. ATT の応答結果を受けてから ALSdk.shared().initialize(with: config) を呼ぶ
  4. AppLovin の初期化完了コールバックを待ってから GADMobileAds.sharedInstance().start(completionHandler:) を呼ぶ
  5. 4 が完了してから React Native 側に「広告 SDK 準備 OK」のイベントを送出する

「ATT が確定する前に GADMobileAds.start を呼ばない」のがポイントです。ATT の応答前に GADMobileAds を初期化すると、IDFA 取得を前提とした AdMob 直接配信のターゲティングが意図と違う形で確定し、復旧に再起動が必要になるケースがありました。

import AppTrackingTransparency
import AppLovinSDK
import GoogleMobileAds
import FirebaseCore
 
final class AdsBootstrap {
    static let shared = AdsBootstrap()
    private(set) var isReady = false
    private var initInFlight = false
 
    func configureOnLaunch() {
        FirebaseApp.configure()
    }
 
    func startAfterActive() {
        guard !isReady, !initInFlight else { return }
        initInFlight = true
        ATTrackingManager.requestTrackingAuthorization { [weak self] status in
            DispatchQueue.main.async {
                self?.bootstrapMax(attStatus: status)
            }
        }
    }
 
    private func bootstrapMax(attStatus: ATTrackingManager.AuthorizationStatus) {
        let config = ALSdkInitializationConfiguration(sdkKey: AppEnv.applovinSdkKey) { builder in
            builder.mediationProvider = ALMediationProviderMAX
            builder.testDeviceAdvertisingIdentifiers = AppEnv.testDeviceIDFAs
        }
        ALSdk.shared().initialize(with: config) { [weak self] _ in
            self?.bootstrapAdMob(attStatus: attStatus)
        }
    }
 
    private func bootstrapAdMob(attStatus: ATTrackingManager.AuthorizationStatus) {
        GADMobileAds.sharedInstance().start { [weak self] _ in
            self?.isReady = true
            self?.initInFlight = false
            NotificationCenter.default.post(name: .adsBootstrapReady, object: nil, userInfo: [
                "att": attStatus.rawValue,
            ])
        }
    }
}
 
extension Notification.Name {
    static let adsBootstrapReady = Notification.Name("AdsBootstrapReady")
}

React Native 側はこの AdsBootstrapReady 通知を Native Module で購読し、JavaScript 側のフックに useAdsReady() のような形で渡しています。広告呼び出し側のコードが「準備完了」の真偽値で待機するように一本化すると、起動直後のレースコンディションが消えて検証が一段楽になります。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Rork が出力した最小構成の iOS プロジェクトに AppLovin MAX を SwiftPM 経由で後付けする実装フロー
✦ATT ダイアログ・MAX 同意フラグ・AdMob 初期化の順序を崩さないための初期化ガード設計
✦AdMob 単独と AppLovin MAX 並走の eCPM/fill rate を 2 週間で比較するための最小 A/B テスト構成
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

⟐ ビジネス2026-05-21
Rork アプリで AdMob Bidding を本番投入した実装メモ — 5 AdNetwork 同時入札の eCPM 推移と運用設計
Rork で生成したアプリに AdMob Bidding を導入し、5 AdNetwork の同時入札を本番運用しています。ウォーターフォールから移行した eCPM 推移、fill rate の変化、Claude in Chrome での日次運用までを実装メモとして整理しました。
◇ アプリ開発2026-04-26
Rork でネイティブ iOS アプリを作る — SwiftUI 生成から TestFlight 配信までの実践ワークフロー
Rork の新規 iPhone プロジェクトは Swift/SwiftUI で生成され、Rork Pro で App Store まで届きます。古い Expo プロジェクトとの見分け方、クレジットで見る費用、骨格プロンプト、実機確認、Xcode に降りる基準、TestFlight 提出までを手順で追います。
⟐ ビジネス2026-09-06
eCPM が下がった月の広告収益を、国の構成と単価に切り分けます
ブレンド eCPM は単価ではなく加重平均です。下がった原因が配信国の構成なのか単価なのかを、合計差分と誤差なく一致する形で切り分ける手順とスクリプトをまとめました。低単価の国を止める前に確かめることも書き残します。