RORK LABEN
BUILD — Rork Max はクラウド上の実機 Mac に Xcode と iOS SDK を載せ、SwiftUI を書き、ビルドし、エラーを読んで直す反復を回します。コードを吐いて終わりではない点が生成物の質に効いていますNATIVE — 生成されるのは React Native ではなく純粋な Swift / SwiftUI です。AR や Metal、ウィジェットなど React Native からは届かない機能に手が届くことが、他ビルダーとの実質的な差になりますPLATFORMS — 対応は iPhone・iPad・Apple Watch・Apple TV・Vision Pro に加えて iMessage まで含みます。ウォッチや拡張から入る設計を試すのに向いていますCOMPANION — Rork Companion により、有料の Apple Developer アカウントなしで生成したアプリを実機の iPhone で確認できます。最初の一本を試す段階の障壁が一段下がりましたPRICING — 無料で開始でき有料プランは月額25ドルから、Rork Max は月額200ドルの Max プランです。回収できる本数と規模を先に見積もっておく価値がありますDEADLINE — Google Play は2026年8月31日以降、新規アプリと更新の双方に対象 API レベル36 以上を要求します。残り10日で、生成物の targetSdkVersion は自分で確認が必要ですBUILD — Rork Max はクラウド上の実機 Mac に Xcode と iOS SDK を載せ、SwiftUI を書き、ビルドし、エラーを読んで直す反復を回します。コードを吐いて終わりではない点が生成物の質に効いていますNATIVE — 生成されるのは React Native ではなく純粋な Swift / SwiftUI です。AR や Metal、ウィジェットなど React Native からは届かない機能に手が届くことが、他ビルダーとの実質的な差になりますPLATFORMS — 対応は iPhone・iPad・Apple Watch・Apple TV・Vision Pro に加えて iMessage まで含みます。ウォッチや拡張から入る設計を試すのに向いていますCOMPANION — Rork Companion により、有料の Apple Developer アカウントなしで生成したアプリを実機の iPhone で確認できます。最初の一本を試す段階の障壁が一段下がりましたPRICING — 無料で開始でき有料プランは月額25ドルから、Rork Max は月額200ドルの Max プランです。回収できる本数と規模を先に見積もっておく価値がありますDEADLINE — Google Play は2026年8月31日以降、新規アプリと更新の双方に対象 API レベル36 以上を要求します。残り10日で、生成物の targetSdkVersion は自分で確認が必要です
記事一覧/開発ツール
開発ツール/2026-07-07中級

アプリ内レビュー依頼を出しているのに評価が増えないとき — 表示率とタイミングを計測して立て直す運用メモ

Rork アプリで expo-store-review を組み込んだのに星の数が伸びない。OS がダイアログを黙って抑制するため、呼び出しても表示されているとは限りません。表示機会を計測してタイミングを設計し直す運用メモです。

Rork540In-App ReviewSKStoreReviewControllerGoogle Play In-App Review計測2リテンション17App Store88

プレミアム記事

星の数が二週間動かなかったことがあります。

expo-store-review は入れてありました。ログには requestReview() を呼んだ形跡が毎日何十件も残っている。なのに App Store Connect の評価件数は前の週とほぼ同じ。呼んでいるのに増えない、という状態がいちばん厄介です。エラーも出ないので、どこを直せばいいのか手掛かりがないのです。

原因は単純でした。OS はレビューダイアログを呼び出しても表示するとは限らず、しかも「表示したかどうか」を教えてくれません。私はずっと、届いていない依頼を数えて満足していたわけです。

このメモは、Rork(React Native / Expo)で作ったアプリの「レビュー依頼が黙って握りつぶされている」状態を、表示機会という自前の指標で可視化して立て直すまでの記録です。個人開発で運用しているアプリで実際に星の増分が動いた手順に絞って書きます。

呼び出しは成功、でも表示はされていない

まず前提を正確に押さえます。iOS の SKStoreReviewController.requestReview()(Expo では StoreReview.requestReview())には、次の制約があります。

制約内容開発者から見えるか
年間表示上限同一ユーザーに対して概ね年3回まで見えない
表示の最終判断呼び出しても OS が出さないことがある見えない
コールバック表示されたか・投稿されたかの戻り値なし取得不可
開発ビルドシミュレータでは常に表示(本番挙動と異なる)誤解の元

Android の Google Play In-App Review API も同じ思想です。1日あたりのクォータがあり、短時間に繰り返すと以降は何も起きません。やはり「表示された」という確証は返りません。

つまり requestReview() の呼び出し回数は、レビュー体験の指標として役に立たないのです。呼べば呼ぶほど内部クォータを消費し、肝心なタイミングで出せなくなる。私が二週間はまっていたのは、まさにこの浪費でした。

呼び出しではなく「表示機会」を数える

戻り値がない以上、表示回数そのものは取れません。取れないものを追うのはやめて、代わりに自分が制御できる一歩手前の指標を置きます。「依頼を出してよい条件を満たしてダイアログ表示をリクエストした瞬間(=表示機会)」を、自前のカウンタで記録するのです。

考え方はこうです。OS のクォータは触れない。ならばアプリ側のゲート(いつ・誰に・何回まで依頼するか)を厳密に管理し、そこを通過した回数だけを信頼できる指標として扱います。表示機会を絞り込めば、限られた OS クォータを価値の高い瞬間に集中投下できます。

// src/lib/reviewGate.ts
import * as StoreReview from 'expo-store-review';
import AsyncStorage from '@react-native-async-storage/async-storage';
 
const KEYS = {
  opportunities: 'review_opportunities',   // 表示機会に到達した回数
  lastPromptAt: 'review_last_prompt_at',    // 最後に依頼した日時(ISO)
  positiveSignals: 'review_positive_signals', // 良い体験の蓄積
  version: 'review_prompted_version',        // 依頼済みのアプリバージョン
};
 
// この2つは「無駄打ちを防ぐ」ための自前ルール。OSの上限とは別に効かせる
const MIN_DAYS_BETWEEN = 60;      // 前回依頼からの最低間隔(日)
const REQUIRED_SIGNALS = 3;        // 依頼前に必要な良い体験の数
 
async function getNumber(key: string): Promise<number> {
  const raw = await AsyncStorage.getItem(key);
  return raw ? Number(raw) : 0;
}
 
// 良い体験(タスク完了・保存成功など)のたびに加点する
export async function recordPositiveSignal(): Promise<void> {
  const current = await getNumber(KEYS.positiveSignals);
  await AsyncStorage.setItem(KEYS.positiveSignals, String(current + 1));
}
 
// 依頼してよいか判定し、満たせば「表示機会」を記録してリクエストする
export async function maybeRequestReview(appVersion: string): Promise<boolean> {
  const isAvailable = await StoreReview.isAvailableAsync();
  if (!isAvailable) return false;
 
  const signals = await getNumber(KEYS.positiveSignals);
  if (signals < REQUIRED_SIGNALS) return false;
 
  const promptedVersion = await AsyncStorage.getItem(KEYS.version);
  if (promptedVersion === appVersion) return false; // 同一版で二度と出さない
 
  const lastAtRaw = await AsyncStorage.getItem(KEYS.lastPromptAt);
  if (lastAtRaw) {
    const days = (Date.now() - new Date(lastAtRaw).getTime()) / 86400000;
    if (days < MIN_DAYS_BETWEEN) return false;
  }
 
  // ここを通過した瞬間だけを「表示機会」として数える
  const opp = await getNumber(KEYS.opportunities);
  await AsyncStorage.setItem(KEYS.opportunities, String(opp + 1));
  await AsyncStorage.setItem(KEYS.lastPromptAt, new Date().toISOString());
  await AsyncStorage.setItem(KEYS.version, appVersion);
 
  await StoreReview.requestReview(); // 表示されるかはOSが決める
  return true;
}

肝心なのは、maybeRequestReview()true を返した回数を分析基盤に送っておくことです。この「表示機会」の総数と、App Store Connect / Play Console の評価件数の増分を並べれば、見えないはずの表示・投稿の実態を推定できます。

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

この記事の続きを読む

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

この記事で得られること
呼び出し回数ではなく「表示機会に到達した回数」を自前で計測する具体的なフック実装
iOS 3回/年・Android クォータという不可視の上限を、評価件数の増分と突き合わせて推定する手順
起動直後に出して無駄打ちしていた依頼を、達成イベント基点に移して評価件数を動かした運用ログの読み方
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-08-20
ベータ SDK でビルドしたアプリは、TestFlight には配れても審査には出せません
ベータ版の Xcode でビルドしたアプリは TestFlight には配布できますが、App Store の審査には提出できません。手元のビルドがどの SDK で作られたかを確認する方法と、eas.json で提出用ビルドを守る設定をまとめました。
開発ツール2026-08-14
ライセンス表示に載せる依存は、lockfile の dev/prod では決まりません
AI ビルダーが書き出したプロジェクトの依存を実際に分類し、ライセンス表示に載せる範囲をどう決めたかの記録です。copyleft の検出結果と配布物の境界の食い違いを、本番プロジェクトの実データで確かめました。
開発ツール2026-07-17
許可を聞かずに通知を届ける — Rork アプリの provisional 認可と、Expo の定番コードが握りつぶすもの
iOS には許可ダイアログを出さずに通知を配り始める provisional 認可があります。ところが Expo 公式が載せている定番の登録コードをそのまま使うと、provisional で通った端末が「拒否」として扱われ、避けたかったはずのダイアログが出ます。granted が false になる仕組みから、5値で許可状態を扱うフック、静かな配信を前提にした通知設計、昇格を求める判断、計測の分離までを実装込みで整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →