RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/ビジネス
ビジネス/2026-04-26上級

Rork Max で『App Store Top 100 アプリ』を作って収益化する完全手順 — 設計から AdMob・サブスク導入まで

Rork Max で SwiftUI ネイティブアプリを開発し、App Store カテゴリ Top 100 に乗せて月20〜50万円の収益化を実現するための完全手順。設計指針・AdMob 実装・IAP・サブスク・ASO・リテンションまで、個人開発者の視点で体系的にまとめました。

Rork515Rork Max229App Store79AdMob70IAP6サブスクASO27個人開発187収益化66

「Rork Max で SwiftUI ネイティブアプリを作るのは分かった。でも、App Store の中で見つけてもらって、毎月の収益にするまでにはまだ霧がかかっている」——個人開発者として、私自身もここで何度か止まってきました。コードが動くことと、App Store のカテゴリで上位に食い込んで収益を作ることの間には、想像より大きな段差があります。

幸い、私はこの段差を設計・実装・運用の3つに分けて考えることで何度か越えてきました。今回は、Rork Max でネイティブアプリを作り、App Store カテゴリ Top 100 を通り、月20〜50万円の収益を作るまでの完全手順を、個人開発者の視点で丁寧に書いていきます。

ここから先はコードと判断軸が中心になります。動くコードと「なぜそう設計するか」をセットでお届けしますので、自分のアプリにそのまま転用できる内容を目指しました。

App Store Top 100 を通すための設計指針

Top 100 に乗るアプリには、運や偶然を超えた共通の構造があります。私が継続的に観察してきた範囲では、3つの軸が揃っています。

1. 1日5分以内で価値を感じる体験:起動して5分以内に「これは便利」と思える瞬間がある 2. 毎日または毎週開く理由がある:ニュース性・進捗性・記録性のいずれかが組み込まれている 3. ストアの第一印象(スクリーンショットと説明文)が解像度高く伝わる:1秒でアプリの価値が伝わる

Rork Max は SwiftUI ネイティブの生成性能が強いので、1と2は実装スピードで作れます。3はテキストと画像のデザインの問題なので、最初に時間を投資すると後の伸びが大きく変わります。

実装に入る前に、私が必ず書き出すのは次の3つです。

  • コア体験:起動から5分以内にユーザーが感じる「便利」を1文で書く
  • 再訪トリガー:毎日・毎週開く理由を1つ決める(通知・記録蓄積・新着情報など)
  • マネタイズフック:どこで広告が入り、どこで IAP/サブスクの提案が出るかを決める

この3つを書き終えてから初めて、Rork Max にコード生成を頼みます。これをやらずに「とりあえず作る」と、機能は揃うけど Top 100 には乗らないアプリができ上がります。

Rork Max でのプロジェクト構造とビルド設計

Rork Max は SwiftUI のネイティブコードを生成しますが、収益化を見越したプロジェクト構造に最初から整えておくと、後の機能追加が劇的にラクになります。私が今使っている構造はこうです。

MyApp/
├── App/
│   └── MyAppApp.swift
├── Features/
│   ├── Home/
│   ├── Detail/
│   └── Settings/
├── Monetization/
│   ├── AdManager.swift
│   ├── IAPManager.swift
│   └── SubscriptionManager.swift
├── Analytics/
│   └── AnalyticsTracker.swift
└── Resources/
    └── Localizable.strings

Monetization/ ディレクトリを最初から切り出しておくのが肝です。広告・IAP・サブスクのコードがバラバラに散らばると、後の修正で必ずバグが入ります。全ての収益化ロジックを1つのディレクトリに集約しておくと、A/B テストの実装も後から差し込みやすくなります。

AdMob の SwiftUI 実装 — バナー・インタースティシャル・リワード

AdMob を SwiftUI で扱うときの肝は、広告表示のタイミングをユーザー体験から逆算することです。私が今使っている実装の基礎を載せます。

// AdManager.swift — AdMob ラッパー
import GoogleMobileAds
import SwiftUI
 
final class AdManager: NSObject, ObservableObject {
    static let shared = AdManager()
    @Published var isInterstitialReady: Bool = false
    private var interstitialAd: GADInterstitialAd?
 
    func setup() {
        GADMobileAds.sharedInstance().start { _ in }
        loadInterstitial()
    }
 
    private func loadInterstitial() {
        let request = GADRequest()
        GADInterstitialAd.load(
            withAdUnitID: "ca-app-pub-XXXXXX/YYYYYY",
            request: request
        ) { [weak self] ad, error in
            if let error = error {
                print("interstitial load failed: \(error.localizedDescription)")
                self?.isInterstitialReady = false
                return
            }
            self?.interstitialAd = ad
            self?.isInterstitialReady = true
        }
    }
 
    @MainActor
    func showInterstitialIfReady(from rootViewController: UIViewController) {
        guard let ad = interstitialAd else { return }
        ad.present(fromRootViewController: rootViewController)
        // 表示後は次の広告を先読み
        loadInterstitial()
    }
}
 
// バナー広告のSwiftUIラッパー
struct BannerAdView: UIViewRepresentable {
    let adUnitID: String
 
    func makeUIView(context: Context) -> GADBannerView {
        let banner = GADBannerView(adSize: GADAdSizeBanner)
        banner.adUnitID = adUnitID
        banner.rootViewController = UIApplication.shared.connectedScenes
            .compactMap { ($0 as? UIWindowScene)?.windows.first?.rootViewController }
            .first
        banner.load(GADRequest())
        return banner
    }
 
    func updateUIView(_ uiView: GADBannerView, context: Context) {}
}

ここで重要なのが、isInterstitialReady で表示可能性を見える化していることです。インタースティシャル広告は読み込みに時間がかかるので、未ロード状態で present を呼ぶと表示されません。状態を @Published で公開して、UI 側からも待ち合わせできるようにします。

インタースティシャルを出す位置」も体験を左右します。私が観察してきた範囲では、起動直後・操作の途中ではなく、1つの作業を完了した直後(例: 記事を読み終わった、保存ボタンを押した)が、最も体験を壊しません。広告を出すたびに「ここで出す価値があるか?」を自問する習慣をつけると、ユーザーレビューが守れます。

IAP の実装 — StoreKit 2 で「広告を消す」買い切り

買い切り IAP は、AdMob と組み合わせるときに最も摩擦の少ない収益化です。「広告を消す」¥250〜¥480 の買い切りを提供すると、広告に疲れたユーザーが自然に課金する流れが作れます。

// IAPManager.swift — StoreKit 2
import StoreKit
 
final class IAPManager: ObservableObject {
    static let shared = IAPManager()
    @Published var products: [Product] = []
    @Published var purchasedProductIDs: Set<String> = []
 
    private let productIDs: [String] = ["com.example.myapp.removeads", "com.example.myapp.proupgrade"]
 
    func loadProducts() async {
        do {
            self.products = try await Product.products(for: productIDs)
        } catch {
            print("loadProducts failed: \(error)")
        }
    }
 
    func purchase(_ product: Product) async -> Bool {
        do {
            let result = try await product.purchase()
            switch result {
            case .success(let verification):
                let transaction = try checkVerified(verification)
                purchasedProductIDs.insert(transaction.productID)
                await transaction.finish()
                return true
            case .userCancelled, .pending:
                return false
            @unknown default:
                return false
            }
        } catch {
            print("purchase failed: \(error)")
            return false
        }
    }
 
    private func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
        switch result {
        case .verified(let safe):
            return safe
        case .unverified(_, let error):
            throw error
        }
    }
 
    func restorePurchases() async {
        for await result in Transaction.currentEntitlements {
            if case .verified(let transaction) = result {
                purchasedProductIDs.insert(transaction.productID)
            }
        }
    }
}

StoreKit 2 を使うことで、サーバーサイドのレシート検証なしでも比較的安全な実装が可能です。Transaction.currentEntitlements で復元できる作りにしておくと、機種変更後の復元クレームを防げます。

サブスクの設計 — 「無料で十分使える」ことを前提にした上位プラン

サブスクは、無料体験を壊さないことが最重要です。「サブスクに入らないと使えない」設計は、ストアの低評価レビューの直接的な原因になります。私の今のおすすめは、無料機能で 80%、サブスクで 20% の割合です。

サブスクで提供する20%の例:

  • 広告完全非表示
  • データ無制限保存(無料は直近30日まで)
  • カスタムテーマ・上級フィルター
  • 早期アクセス機能
// SubscriptionManager.swift — サブスク状態管理
import StoreKit
 
final class SubscriptionManager: ObservableObject {
    static let shared = SubscriptionManager()
    @Published var isSubscribed: Bool = false
    @Published var subscriptionProducts: [Product] = []
 
    private let groupID = "com.example.myapp.subscriptions"
 
    func loadSubscriptions() async {
        do {
            let products = try await Product.products(for: [
                "com.example.myapp.monthly",
                "com.example.myapp.yearly"
            ])
            self.subscriptionProducts = products
            await refreshStatus()
        } catch {
            print("loadSubscriptions failed: \(error)")
        }
    }
 
    func refreshStatus() async {
        for await result in Transaction.currentEntitlements {
            if case .verified(let transaction) = result {
                if transaction.productType == .autoRenewable {
                    isSubscribed = true
                    return
                }
            }
        }
        isSubscribed = false
    }
 
    func subscribe(_ product: Product) async -> Bool {
        do {
            let result = try await product.purchase()
            if case .success(let verification) = result {
                if case .verified(let transaction) = verification {
                    await transaction.finish()
                    await refreshStatus()
                    return true
                }
            }
            return false
        } catch {
            print("subscribe failed: \(error)")
            return false
        }
    }
}

refreshStatus を起動時に必ず呼ぶことで、機種変更後やサブスク失効時にも UI が正しく追従します。サブスク中に広告を出してしまうのは、最も低評価につながる失敗パターンです。SubscriptionManager.shared.isSubscribed を AdMob 表示前に必ずチェックする習慣にしてください。

ASO(App Store 最適化)と最初の100ダウンロードまでの動き方

App Store 検索でアプリが見つけられるかどうかは、**タイトル・サブタイトル・キーワード(メタデータ)**の3つで8割が決まります。私が今使っている書き方の基準はこうです。

  • タイトル:アプリ名 + 主要な動詞(例: 「PDF要約 — 議事録を3行に」)
  • サブタイトル:誰の・どの仕事を・どう変えるかを30文字で(例: 「会議の議事録を1分で読める3行要約に」)
  • キーワード:競合の少ない複合キーワードを最大100文字

最初の100ダウンロードを集めるための動きは、SNS 告知だけでは足りません。私が実際にやっているのは次の組み合わせです。

  • note・X での開発記録投稿:機能ではなく「開発の判断と試行錯誤」を書く
  • Reddit/Hacker News などコミュニティでの限定公開:完成度70%段階で意見を集める
  • 個別 DM での友人・知人への直接案内:レビュー数の最初の10件を確保する

最初の10レビューが集まると、ストア検索の表示順位が大きく動きます。これが Top 100 への階段の最初の段差です。

リテンション設計 — Day 1 / Day 7 / Day 30 リテンションの目標値

App Store Top 100 の中で長期上位を維持するアプリには、リテンションの数字が共通しています。私が個人アプリで目標にしている水準はこうです。

  • Day 1 リテンション: 40% 以上(インストール翌日も開いてくれる人の割合)
  • Day 7 リテンション: 20% 以上
  • Day 30 リテンション: 10% 以上

これを下回るアプリは、たとえダウンロード数が伸びても Top 100 内で滞留できません。リテンションを上げるための実装で最も効くのは、通知進捗の見える化です。

通知は「個人開発のアプリだから難しい」と思われがちですが、UNUserNotificationCenter を使えば SwiftUI からシンプルに実装できます。重要なのは、通知の文面をユーザーごとにパーソナライズすることです。「明日も開きませんか?」という汎用文ではなく、「昨日記録した『朝5km走』の続きはどうですか?」のような、その人のデータに紐づいた一文が、開封率を3〜5倍に変えます。

よくある間違い・落とし穴

最後に、Top 100 を狙う上で気をつけたい落とし穴を3つ。

1. リリース直後に広告フォーマットを増やしすぎる バナー+インタースティシャル+リワードを最初から全部入れると、ユーザーレビューが荒れがちです。最初の2週間はバナーのみで運用し、評価が安定してからインタースティシャルを足すのが安全です。

2. ASO のキーワードを欲張りすぎる 高ボリュームキーワードばかり狙うと、競合に埋もれて全く検索表示されなくなります。月100〜500検索の中ボリューム複合キーワードを3〜5個拾う方が、Top 100 入りには現実的です。

3. サブスク中ユーザーへの広告表示 これは全ての低評価レビューの中で最も致命的なパターンです。isSubscribed のチェックを必ず最初に入れる、という鉄則を守るだけで、レビュー4.0台が4.5台に変わります。

全体を振り返って — Top 100 は『5分体験 × 再訪トリガー × 解像度の高いストア』の積み上げ

Rork Max で SwiftUI ネイティブアプリを作って App Store Top 100 に乗せ、月20〜50万円の収益にするのは、1つの飛躍ではなく、3つの掛け算で達成できます。

  • 5分以内に価値を感じる体験
  • 毎日・毎週開く理由
  • ストア第一印象の解像度

実装の順序としては、まずコア体験を Rork Max で生成して半完成で出し、AdMob だけを入れて運用しながら ASO を育てるところから始めるのが現実的です。IAP とサブスクは、Day 1 リテンションが30%を超えてから足すと、課金率が大きく変わります。

料金面の判断軸を整理したい場合は、Rork Max の料金で SwiftUI ネイティブアプリを収益化する3つの判断 を先にお読みください。マイクロ単位のサブスク設計に踏み込みたい場合は、Rork で月10万円のアプリを作る — 価格とリテンション実装 も合わせてどうぞ。

最初の30分でやれるのは、自分のアプリの「5分体験を1文で」「再訪トリガーを1つ」「ストア第一印象のスクリーンショットを1枚」、この3つだけ書き出すことです。その3つが揃えば、Rork Max でのコード生成は驚くほどスムーズに進みます。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

ビジネス2026-05-02
個人開発で月10万円を超えるアプリ収益化の実践戦略 — Rork で作って試した収益チューニングの全工程
個人開発のアプリで月10万円の壁を超えるための実践戦略。Rork で作ったアプリで実際に試した広告収益最大化、IAP 価格チューニング、サブスク継続率向上、ASO 強化までの全工程を、12 年間の収益化試行錯誤に基づく数値とコードで解説します。
ビジネス2026-04-26
Rork Max で作る SwiftUI アプリを黒字化する3つの判断 — プラン・収益モデル・公開タイミング
Rork Max で SwiftUI ネイティブアプリを作るとき、黒字化を左右するのは価格表ではなく『どのプランか』『どの収益モデルか』『いつ公開するか』の3つです。個人開発の実体験から、最初の月から回収するための判断軸を整理しました。
ビジネス2026-05-15
5,000万DLの個人開発者がRork Maxでアプリを作り直した記録:開発時間・品質・収益の実測比較
累計5,000万DLの個人開発者がRork Maxで壁紙アプリを再実装。開発時間・コード品質・AdMob・RevenueCat統合・収益指標を実測比較。AIツールの限界と活用法を正直に報告します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →