tech.sinayaka.com

アプリを更新せずに、旧アプリから新アプリへユーザーを送客した話

2026-06-01
2026-07-18
9分
1683語
iOS iOSAdMob広告ASO
目次

    数独パズルアプリを作り直した。旧アプリはキーチェーン周りの問題でアップデートできなくなり、ストアから削除。後継アプリを新規で出した。

    ところが、機能は後継のほうが上なのにまったくダウンロードされない。新規ユーザーはほぼゼロ。一方で削除したはずの旧アプリは、既存ユーザーが今も毎日遊んでいて広告も回っている。

    この「旧アプリの現役ユーザーを新アプリへ送りたい」を、アプリの更新なしで実現した話を書く。

    なぜ新アプリは埋もれるのか

    データを見て原因がはっきりした。新アプリの新規ユーザーは、アナリティクス上**全て (direct)**だった。

    (direct) はApp Store検索経由ではなく、URLを直接知っている人(=自分や既存ファン)からの流入を意味する。つまりApp Store検索結果に一切出てきていない

    理由は単純で、新アプリは別アプリ扱いだから:

    • レビュー・評価がゼロからの再スタート
    • ランキング・検索順位の蓄積がない
    • 「数独」「ナンプレ」のような激戦キーワードで新規アプリが上位に出るのはほぼ不可能

    旧アプリが積み上げた資産は、新アプリには1ミリも引き継がれない。

    旧アプリには「現役ユーザー」がいる

    ここで効くのが、削除済みの旧アプリだ。

    ストアから消えても、すでにインストール済みのユーザーのアプリは動き続ける。広告レポートを見ると、旧アプリは月に数万インプレッションを叩き出していた。数百人規模が今も遊んでいる。

    この人たちに「後継アプリがあるよ」と伝えられれば、検索流入ゼロの問題を一気に飛び越えられる。一番確実な見込み客が、すでに旧アプリの中にいる。

    問題は、旧アプリが更新できないこと。普通なら「アプリ内に新アプリへのバナーを追加してアップデート」だが、それができない。

    自社広告サーバーという逃げ道

    幸い、旧アプリ(Objective-C世代)には自前の広告配信の仕組みが入っていた。

    起動時に自社サーバーへ問い合わせ、JSONで「どの広告を出すか」を受け取る方式だ。

    https://example.com/ad.php?code=<アプリ識別コード>

    レスポンスはこんな形:

    {
      "ad_type": 10002,
      "text1": "ca-app-pub-xxxxx/yyyyy",
      "per": 100
    }

    ad_type で広告の種類を切り替える。値はDB(media / tag テーブル)で管理されていて、サーバー側のレコードを書き換えるだけで配信内容が変わる。アプリ側のコードには一切触らない。

    つまり、アプリを更新できなくても、広告枠の中身は今からでも差し替えられる

    HTML広告でバナーを差し込む

    ad_type にはAdMob以外にHTML広告のタイプがあった。

    10001 = HTML
    10002 = AdMob

    HTMLタイプを返すと、アプリ側は受け取った文字列を UIWebView に流し込む:

    NSString *html = [NSString stringWithFormat:
        @"<body style='margin:0;text-align:center;'>%@</body>", adText];
    [adWeb loadHTMLString:html baseURL:nil];

    ここに新アプリへのリンク付きHTMLを入れればいい。広告枠に自前のバナーを描画できる。

    タップでApp Storeが開くか

    懸念は「UIWebView 内のリンクをタップしたとき、ちゃんとApp Storeが開くか」だった。小さなWebView内でApp StoreのURLを開こうとすると詰む。

    旧アプリの実装を確認したら、ちゃんとデリゲートで処理していた:

    - (BOOL)webView:(UIWebView *)webView
      shouldStartLoadWithRequest:(NSURLRequest *)request
      navigationType:(UIWebViewNavigationType)navigationType
    {
        if (navigationType == UIWebViewNavigationTypeLinkClicked) {
            if ([[UIApplication sharedApplication] canOpenURL:[request URL]]) {
                [[UIApplication sharedApplication] openURL:[request URL]];
                return NO;  // WebView内では読み込まない
            }
        }
        return YES;  // 初期表示(loadHTMLString)はそのまま許可
    }

    リンククリック(UIWebViewNavigationTypeLinkClicked)を検知したら openURL: で外部に投げ、WebView内ロードは return NO で止める。初回の loadHTMLString はクリック扱いではないので return YES で正常に表示される。

    App StoreのURL(https://apps.apple.com/app/idXXXX)を渡せば、iOSがApp Storeアプリに引き渡してくれる。狙い通りだった。

    古いWebViewでもCSSアニメは動く

    UIWebView は古いAPIだが、中身はWebKitだ。CSSアニメーションもトランジションも動く。

    せっかくなので、ただの静止バナーではなく、目に留まる演出をつけた:

    • アプリアイコンが左右にゆらゆら揺れる(花のモチーフに合わせて)
    • バナー全体を斜めの光が定期的に横切る(shine)
    • CTAボタンがぷるぷる拡縮する
    @keyframes shine {
      0%   { left: -60%; }
      60%, 100% { left: 120%; }
    }
    .banner::after {
      content: '';
      position: absolute; top: 0; left: -60%;
      width: 40%; height: 100%;
      background: linear-gradient(120deg,
        transparent, rgba(255,255,255,.35), transparent);
      animation: shine 3s ease-in-out infinite;
    }

    広告枠は 320×50(iPhone)。アイコンを height:100% で枠にフィットさせ、右にテキストとCTAを並べる横長レイアウトにした。

    配信割合とA/Bテスト

    DBの per カラムは配信割合(重み付け抽選)だ。AdMobと新アプリ誘導を半々にしたいなら:

    -- AdMob枠
    UPDATE tag SET per=50 WHERE id=<AdMobのタグ>;
    -- 新アプリ誘導枠
    UPDATE tag SET ad_type=10001, per=50, text1='<バナーHTML>'
      WHERE id=<誘導タグ>;

    per の合計に対する割合で抽選されるので、50:50 なら半々で配信される。実際に何度もリクエストして比率を確認した。

    さらに面白いのは、誘導バナーを複数登録すればA/Bテストになること。表示・クリックはタグ単位でDBに記録されるので、どのコピーが一番刺さるかを後から数字で比較できる。

    タグA: 「神ヒントで解き方が学べる」    per=17
    タグB: 「もう詰まらない」              per=17
    タグC: 「新作・解法ヒントが神レベル」  per=16

    3案を均等に配信し、クリック率の高いコピーに寄せていく。広告枠ひとつで小さなマーケティング実験ができる。

    やってみた結果(途中経過)

    設定して半日で、誘導バナーは800回以上表示された。旧アプリの現役ユーザーがちゃんと見ている。

    ただ、クリックは数回どまり。新アプリのダウンロードにはまだ繋がっていない。表示はされるが、コピーがまだ弱いのだと思う。だからこそA/Bテストで「どう言えば刺さるか」を探っている最中だ。

    まとめ

    やったことポイント
    旧アプリの自社広告サーバーを使うアプリ更新なしでDB書き換えだけ
    HTML広告タイプで自前バナーを描画loadHTMLString
    タップでApp Storeを開くshouldStartLoadWithRequestopenURL:
    CSSアニメで目立たせる古いUIWebViewでもWebKitなので動く
    per で配信割合を制御AdMobと混在配信・A/Bテスト

    「アプリが更新できない」は詰みに見えて、配信の仕組みを自前で持っていれば抜け道がある。旧アプリの現役ユーザーは、新アプリにとって一番確実な見込み客だ。検索流入をゼロから積み上げるより、すでにいる人に届けるほうがずっと早い。




    Copyright 2026
    サイトマップ