2026年の春、久しぶりに壁紙系アプリの新バリアントをRorkで試作してみました。目的は一つ、AdMobの広告フローが既存の開発スタックとどう違うかを自分の手で確かめることでした。
2014年から個人アプリ開発を続けてきた私にとって、AdMobは長い付き合いのある収益源です。壁紙アプリ・癒し系アプリ・引き寄せ系アプリなど複数のタイトルを運営し、累計5,000万DL超、ピーク時には月150万円を超える広告収益を得たこともあります。そのぶん、実装の細部に強いこだわりがあります。
Rorkのコード生成に対する期待と懸念、両方を抱えながら試した結果を、できるだけ正直に書き残しておきます。
試したこと — まずは最小限の構成で
最初に作ったのは、画像を縦スクロールして壁紙を眺めるだけのシンプルな構成です。スクロールのたびにインタースティシャル広告が入り、壁紙を長押しで保存するとリワード広告が表示される、ごく標準的な広告フローです。
Rorkへのプロンプトはこうしました。
壁紙スクロールアプリを作ってください。
- 縦スクロールで画像を閲覧
- 5枚ごとにインタースティシャル広告(AdMob)
- 長押し保存時にリワード広告
- AdMob テストIDを使用
生成されたコードは、expo-ads-admob ではなく react-native-google-mobile-ads を採用していました。最新のSDKを使うという判断は正しい。ここは素直に評価できます。
違和感その1 — 広告タイミングのロジックが甘い
インタースティシャルの発火タイミングがカウントベースで実装されていました。具体的には scrollCount をstateで管理し、5になったら広告を表示するというシンプルな実装です。
// Rorkが生成したコード(簡略版)
const [scrollCount, setScrollCount] = useState(0);
const handleScroll = () => {
const newCount = scrollCount + 1;
setScrollCount(newCount);
if (newCount % 5 === 0) {
showInterstitial();
}
};動作はします。ただ、12年の実運用経験から言うと、これはユーザー体験と収益率の両方で課題があります。
実際に私が使っている設計では「セッション開始から最低N秒後」「前回の広告表示からM秒以上経過」という条件を組み合わせています。スクロール速度によって広告頻度が変わるカウントベースは、高速スクロールユーザーに広告過多になりやすく、Google Play Storeのポリシー審査で引っかかったことも過去に一度ありました。
このロジックをどう伝えるかというと、プロンプトで「最後の広告から30秒以上経過した場合のみ表示」と具体的に指示すれば生成し直してくれます。ただ、AdMobポリシーの暗黙知まではRorkは持っていない、という感覚が残りました。
違和感その2 — ATT許可フローが後回しになっている
AppTrackingTransparency(ATT)のパーミッションリクエストが、広告SDKの初期化後に配置されていました。順序が逆です。
正しくはATT許可を取得してから広告SDKを初期化する必要があります。順序が逆だと、許可を取る前に非パーソナライズド広告で初期化されてしまい、許可後もパーソナライズド広告に切り替わらないケースがあります。これはeCPM(千回表示あたり収益)に直接影響します。
// 正しい順序
const requestATT = async () => {
const { status } = await requestTrackingPermissionsAsync();
return status === 'granted';
};
// ATT許可取得後にMobileAds初期化
const isGranted = await requestATT();
await MobileAds().initialize();自動生成されたコードはこの順序が担保されていませんでした。修正は難しくないですが、知らずにそのままリリースすると広告収益が期待値を下回ることになります。
違和感その3 — テストIDと本番IDの切り替え設計がない
生成されたコードにはAdMobのテストIDがハードコードされていました。.env を使った環境変数管理や、ビルドタイプによる切り替え設計がありませんでした。
// Rorkが生成したコード
const BANNER_ID = 'ca-app-pub-3940256099942544/6300978111'; // テストID固定本番IDをどこで管理するかはRorkの問題というよりアーキテクチャの問題ですが、12年間で「テストIDを本番に出してしまった」という話を周囲から何度か聞いています。最初から環境変数前提の構成にしてくれると、もう少し安心です。
app.config.js に環境変数を追加して管理する設計に自分でリファクタリングしました。
驚き — リワード広告のUX実装は思ったより良かった
3つの違和感を書きましたが、一つ正直に驚いたことがあります。リワード広告を受け取った後の「保存完了」アニメーションと状態管理が、想定より自然に実装されていました。
リワード広告の完了コールバックで状態フラグを更新し、保存処理を走らせ、完了トーストを表示する一連のフローが、コールバック地獄にならない形でまとまっていました。
// 生成されたリワード広告フロー(簡略版)
const handleSaveWithReward = async () => {
try {
await rewardedAd.show();
// onEarnedReward コールバックが発火すると下記が実行
} catch (e) {
// 広告なしで保存を許可するフォールバック
await saveToGallery(imageUri);
}
};
rewardedAd.addAdEventListener(RewardedAdEventType.EARNED_REWARD, () => {
saveToGallery(imageUri).then(() => {
showSaveSuccessToast();
});
});非同期処理のエラーハンドリングと、広告がロードできなかった場合のフォールバックも含まれていた点は、素直に「よく考えられている」と思いました。
Rorkによる広告収益化、どんな開発者に向いているか
12年分の経験を持って評価すると、Rorkで広告収益化を始めることに対して「やめておけ」とは言いません。ただ条件付きです。
向いている開発者は、AdMobの仕組みをある程度理解した上でRorkをプロトタイピングツールとして使う人だと思います。生成されたコードをそのまま本番投入するのではなく、ATTフローとIDの環境変数管理、広告タイミングのポリシー準拠を自分でレビューできる人であれば、開発スピードは確実に上がります。
逆に、AdMobを初めて触る人がRorkで完結させようとすると、eCPMが低い状態でリリースしてしまうリスクがあります。広告収益は設計の細部が数字に直結するので、最低限の知識は事前に持っておくことをおすすめします。
私自身はRorkを「初速を出すためのツール」として使い始めています。叩き台を3〜4時間で作り、そこから自分の経験値でポリシー準拠と収益設計を重ねるというワークフローが、今のところ一番しっくりきています。
Rork アプリに AdMob 広告を実装する完全ガイドに実装手順は詳しくまとめてあります。今回書いた「違和感3点」を補完する形で読んでいただくと、実装のイメージが掴みやすいかもしれません。
同じ経験をお持ちの方に、少しでも参考になれば幸いです。