癒し系・ウェルネス系のアプリを作っていると、必ずリクエストされるジャンルがあります。それが「占いアプリ」です。
2014年からiOSアプリを作り続けてきた私は、壁紙アプリや瞑想タイマーを経て、日替わりタロット占いアプリを個人開発しました。そのときの経験から言えるのは、「占いアプリは見た目よりずっと複雑」だということです。Rorkを使えば多くの部分は解決できますが、占いというジャンル固有の設計上の注意点があります。ここでは実際につまずいた7つのポイントを中心に解説します。
なぜ占いアプリは難しいのか
一見シンプルに見えます。カードを引いて、意味を表示します。それだけでは?
実際に作り始めると、こういった問題が次々と出てきます。
- タロット78枚のデータをどう管理するか(カード名・正位置・逆位置・キーワード・解説文)
- 「今日の1枚」の毎日リセットロジック(デバイス時間を信用していいのか)
- 逆位置の扱い(ランダムに出るべきか、設定でオフにできるべきか)
- AI解釈文をAPIで動的生成するか、事前テキストを使うか
- 有料化するとしてサブスクか買い切りか、どちらがユーザーに受け入れられやすいか
- AppStoreの審査でエンターテインメント表記が必要なケース
これらを順番に解説します。
① カードデータの設計
タロットには大アルカナ22枚・小アルカナ56枚の計78枚があります。各カードに最低限必要なフィールドは次の通りです。
{
"id": "major_00",
"name_ja": "愚者",
"name_en": "The Fool",
"upright_keywords": ["新しい始まり", "自由", "冒険"],
"reversed_keywords": ["無謀", "先を急ぎすぎ", "計画不足"],
"upright_description": "新しい旅の始まりを意味します...",
"reversed_description": "焦りや無謀さへの警告です...",
"image_key": "major_00"
}Rorkへのプロンプトでは「78枚のタロットカードデータを格納するJSONスキーマを設計して、Supabaseのcardsテーブルを作成してほしい」と指示し、Supabaseとの連携コードも同時に生成させます。全78枚のデータを手入力するのは大変なので、「大アルカナ22枚分のサンプルデータをSQLのINSERT文で生成して」と追加指示すると、一気にシードデータが完成します。
カード画像については注意が必要です。有名なウェイト版のイラストは著作権が切れているものと残っているものが混在しているため、Unsplashや購入済みアセットを使うか、AIで独自生成した画像を使うのが安全です。
② 毎日リセットロジックの罠
「今日の1枚」を実装するとき、デバイスのローカル時刻だけに頼ると問題が起きます。時計を操作すれば何度でも引き直せてしまうからです。
Rorkに「日替わりカード抽選のロジックを実装して。ユーザーが当日に引いたカードはAsyncStorageに保存して、翌0時まで再抽選できないようにする」と指示すると、次のような実装を提案してくれます。
const getTodayKey = () => {
const now = new Date();
return `drawn_card_${now.getFullYear()}_${now.getMonth()}_${now.getDate()}`;
};
const getOrDrawCard = async (): Promise<Card> => {
const key = getTodayKey();
const stored = await AsyncStorage.getItem(key);
if (stored) return JSON.parse(stored);
const randomCard = await fetchRandomCard();
await AsyncStorage.setItem(key, JSON.stringify(randomCard));
return randomCard;
};ただし厳密な不正防止が必要なプレミアム機能では、サーバーサイドでユーザーIDと日付を紐づけて管理する必要があります。Supabaseのdaily_drawsテーブルにuser_idとdraw_dateのユニーク制約を設定し、重複挿入をエラーとして扱う方法をRorkに実装させると確実です。
③ AI解釈文の生成方法
占いアプリの差別化ポイントになりやすいのがAI解釈です。引いたカードと、ユーザーが入力した「今日の質問」を組み合わせて、パーソナライズされた解釈文を生成します。
Rorkには「Claude APIを使ってタロット解釈を生成するAPI Routeを実装して。カード名・正逆位置・ユーザーの質問を受け取り、200字程度の解釈文をJSONで返す」と指示します。
// app/api/interpret/route.ts
export async function POST(request: Request) {
const { cardName, isReversed, userQuestion } = await request.json();
const prompt = `タロットカード「${cardName}」の${isReversed ? '逆位置' : '正位置'}について、
ユーザーの質問「${userQuestion}」に対する解釈を、温かみのある敬体で200字以内で答えてください。`;
const response = await anthropic.messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 400,
messages: [{ role: 'user', content: prompt }],
});
return Response.json({ interpretation: response.content[0].text });
}コスト面では、claude-haiku-4-5を使えば1回の解釈生成が約0.01円以下です。月に1000人のユーザーが毎日1回使っても月10円程度なので、無料プランでも提供できます。
④ 逆位置をどう扱うか
逆位置(カードが逆向きに引かれた状態)の扱いは、ユーザーによって好みが分かれます。「逆位置は怖い」と感じるユーザーもいるため、設定でオフにできるようにするのが親切です。
Rorkへの指示例:「設定画面に「逆位置を使用する」トグルを追加して。AsyncStorageに設定を保存し、カード抽選時にこの設定を参照してランダムな逆位置判定を行うロジックを実装してほしい」
const shouldReverse = async (): Promise<boolean> => {
const useReversed = await AsyncStorage.getItem('use_reversed_cards');
if (useReversed !== 'true') return false;
return Math.random() < 0.3; // 30%の確率で逆位置
};⑤ カードジャーナル機能
占いアプリのリテンションを高めるのに最も効果的だったのが、ジャーナル機能でした。引いたカードに対して「今日の気づき」を書き留められるシンプルなメモ機能です。
Rorkに「daily_journalsテーブルをSupabaseに作成して、カードIDと日付とメモテキストを保存できるようにして。ジャーナル一覧画面も実装してほしい」と指示します。ユーザーが過去の記録を見返せる仕組みになると、継続率が大幅に上がりました。
⑥ 収益化設計
占いアプリの収益化では、以下の構成が機能しやすいと感じています。
無料機能は大アルカナ22枚のみ(小アルカナは使えない)、AI解釈は月5回まで、ジャーナルは3件まで保存可能とします。
プレミアムプランはRevenueCatで実装し、月額380円($3.99)か年額2,800円($29.99)の2プランを用意します。全78枚が使えて、AI解釈無制限、ジャーナル無制限、過去の履歴閲覧機能が使えるようになります。
RevenueCatのPaywallBuilderをRorkに「RevenueCatのRemoteConfigPaywallを使って、タロットテーマのカスタムペイウォール画面を作って」と指示すると、ブランドに合わせたデザインのペイウォールが生成できます。
⑦ AppStore審査での注意点
占い系アプリには「Entertainment purposes only」の免責事項が必要です。これを怠ると審査が通らないケースがあります。
具体的には、アプリのAbout画面または設定画面に「このアプリは娯楽目的で作成されており、実際の予測や助言を行うものではありません」という文言を追加し、App Store ConnectのAge Rating設定でも「エンターテインメント」として設定します。
また、占いアプリをサブスクで提供する場合、AppleのGuidelines 3.1.3(サブスクのコンテンツ規定)を確認してください。「継続的に更新されるコンテンツ」としてサブスクが認められるため、毎日の新しいカードコンテンツと定期的なアップデートが必要です。
作ってみて分かったこと
占いアプリは、技術的にはそれほど複雑ではありません。しかし、コンテンツの質(カードの解説文、AI解釈の温度感)とUX(毎日習慣として使いたくなる設計)が、ダウンロード数以上にリテンションに直結します。
Rorkを使うと骨格は半日で作れます。その後の「使い続けたいと思える細部の磨き込み」に時間をかけることが、このジャンルで成功するための本質だと感じています。
癒し系アプリを開発している方には、ぜひ挑戦してほしいジャンルです。