取り組みの背景 — この記事で学べること
フィットネストラッカーアプリは、App Store の中でも常に上位を占める人気カテゴリです。歩数計、心拍数モニター、ワークアウト記録、睡眠分析――これらの機能をネイティブに実装するには、通常 HealthKit・WatchKit・WidgetKit という3つの Apple フレームワークを横断する高度な知識が必要です。
Rork Max を使えば、これら3つのフレームワークを自然言語プロンプトで統合したアプリを構築できます。iPhone アプリ・Apple Watch コンパニオンアプリ・ホーム画面ウィジェットを1つのプロジェクトとして設計・実装し、App Store に公開するまでの全工程を順を追って整理していきます。
対象読者: Rork Max の基本操作に慣れている方、HealthKit や Apple Watch アプリの開発経験がなくても OK ですが、Rork Max で1つ以上のアプリを作った経験があることを前提とします。
完成イメージ:
- iPhone: ダッシュボード画面(歩数・消費カロリー・心拍数・睡眠スコア)
- Apple Watch: リアルタイムワークアウト記録 + コンプリケーション
- ウィジェット: 今日のアクティビティリングをホーム画面に表示
前提知識・環境構築
必要なもの
- Rork Max アカウント(Max プラン $200/月 推奨)
- Apple Developer Program(年額 $99 — App Store 公開に必須)
- iPhone + Apple Watch の実機(HealthKit はシミュレータでは制限あり)
Rork Max の準備
Rork Max はクラウド Mac フリートでビルドするため、ローカルに Xcode は不要です。ブラウザから rork.com/max にアクセスし、新しいプロジェクトを作成します。
HealthKit のエンタイトルメント
HealthKit を使うアプリは Apple Developer Portal で明示的にエンタイトルメントを有効化する必要があります。Rork Max はプロンプトでヘルスケア機能を指示すると、Info.plist と Entitlements を自動で設定します。
概念と設計思想
アーキテクチャ全体像
今回構築するフィットネストラッカーは、以下の3層で構成します。
┌──────────────────────────────────────────────┐
│ WidgetKit │
│ ホーム画面ウィジェット(アクティビティリング) │
├──────────────────────────────────────────────┤
│ iPhone App (SwiftUI) │
│ ダッシュボード / 履歴 / 設定 / HealthKit連携 │
├──────────────────────────────────────────────┤
│ Apple Watch App (WatchKit) │
│ ワークアウト記録 / コンプリケーション │
└──────────────────────────────────────────────┘
↕ App Group (共有データ) ↕
HealthKit Store(Apple管理)
データフロー
Apple Watch でワークアウトを記録すると、HealthKit Store にデータが保存されます。iPhone アプリは HealthKit から最新データを読み取り、ダッシュボードに表示します。ウィジェットは App Group 経由で共有された集計データを表示します。
プロンプト設計の方針
Rork Max で複雑なマルチターゲットアプリを作る際は、段階的に機能を追加するのがベストプラクティスです。
- まず iPhone アプリの基本 UI を生成
- HealthKit の読み取り機能を追加
- Apple Watch ターゲットを追加
- ウィジェットターゲットを追加
一度にすべてを指示すると、AI が混乱してビルドエラーが増えます。
ステップバイステップ実装
Step 1: iPhone アプリのベース UI を構築
最初のプロンプトで、ダッシュボード画面の基本構造を作ります。
フィットネストラッカーアプリを作成してください。
【iPhone アプリの画面構成】
1. ダッシュボード(タブ1)
- 今日の歩数(大きな数字 + 円形プログレス)
- 消費カロリー(リング表示)
- 心拍数(最新値 + 小さなラインチャート)
- 睡眠スコア(棒グラフ + 評価テキスト)
2. 履歴(タブ2)
- 週間/月間の歩数推移グラフ
- 日別の詳細データリスト
3. 設定(タブ3)
- 歩数目標の変更
- 通知の ON/OFF
- HealthKit 連携状態の確認
【デザイン要件】
- ダークモードベースのフィットネス UI
- Apple の Activity Rings に似た円形プログレス
- SF Symbols を使ったアイコン
- SwiftUI の Charts フレームワークでグラフを描画このプロンプトで、Rork Max は SwiftUI ベースの3タブアプリを生成します。ストリーミングシミュレータでプレビューを確認しましょう。
Step 2: HealthKit 連携を実装
次のプロンプトで、HealthKit からデータを読み取る機能を追加します。
HealthKit を統合してください。
【読み取るデータ】
- 歩数(HKQuantityType.stepCount)— 今日の合計
- 消費カロリー(HKQuantityType.activeEnergyBurned)— 今日の合計
- 心拍数(HKQuantityType.heartRate)— 最新値 + 過去24時間のサンプル
- 睡眠分析(HKCategoryType.sleepAnalysis)— 昨晩の睡眠時間
【実装要件】
- HealthKitManager クラスを作成し、データ取得ロジックを集約
- 初回起動時に HealthKit の認可リクエストを表示
- バックグラウンドデリバリーで歩数の更新を受け取る
- データが取得できない場合はプレースホルダーを表示
- NSHealthShareUsageDescription に適切な説明文を設定Rork Max が生成するコードの中で、特に重要なのが HealthKitManager です。以下は期待される構造です。
// HealthKitManager.swift — Rork Max が生成するコードの概要
import HealthKit
class HealthKitManager: ObservableObject {
let healthStore = HKHealthStore()
@Published var todaySteps: Int = 0
@Published var todayCalories: Double = 0
@Published var latestHeartRate: Double = 0
@Published var sleepHours: Double = 0
// HealthKit 認可リクエスト
func requestAuthorization() async throws {
let readTypes: Set<HKObjectType> = [
HKQuantityType(.stepCount),
HKQuantityType(.activeEnergyBurned),
HKQuantityType(.heartRate),
HKCategoryType(.sleepAnalysis)
]
try await healthStore.requestAuthorization(
toShare: [], read: readTypes
)
}
// 今日の歩数を取得
func fetchTodaySteps() async {
let stepsType = HKQuantityType(.stepCount)
let today = Calendar.current.startOfDay(for: Date())
let predicate = HKQuery.predicateForSamples(
withStart: today, end: Date()
)
let query = HKStatisticsQuery(
quantityType: stepsType,
quantitySamplePredicate: predicate,
options: .cumulativeSum
) { _, result, _ in
DispatchQueue.main.async {
self.todaySteps = Int(
result?.sumQuantity()?
.doubleValue(for: .count()) ?? 0
)
}
}
healthStore.execute(query)
}
}
// 期待出力:
// todaySteps = 8432(HealthKit から取得した実際の歩数)
// todayCalories = 342.5(アクティブエネルギー消費量)Step 3: Apple Watch コンパニオンアプリを追加
Apple Watch ターゲットを追加するプロンプトです。
Apple Watch コンパニオンアプリを追加してください。
【Watch アプリの機能】
1. ワークアウト記録画面
- ワークアウトの種類選択(ランニング/ウォーキング/サイクリング)
- 開始/一時停止/停止ボタン
- リアルタイムの心拍数・消費カロリー・経過時間を表示
- HKWorkoutSession を使用して正確なワークアウトデータを記録
2. 今日のアクティビティ画面
- 歩数 + カロリーの円形プログレス
- iPhone アプリと同じ目標値を参照
3. コンプリケーション
- 現在の歩数を表示する CircularGauge スタイル
【技術要件】
- WatchConnectivity で iPhone と双方向データ同期
- Extended Runtime Session でバックグラウンドワークアウトを維持
- Digital Crown でワークアウト種類をスクロール選択Rork Max は watchOS ターゲットを自動で追加し、WatchKit のコードを生成します。生成されたコードでは、HKWorkoutSession を使ったリアルタイムワークアウト記録が中核になります。
// WorkoutManager.swift — Apple Watch 側のワークアウト管理
import HealthKit
import WatchKit
class WorkoutManager: NSObject, ObservableObject {
let healthStore = HKHealthStore()
var workoutSession: HKWorkoutSession?
var workoutBuilder: HKLiveWorkoutBuilder?
@Published var heartRate: Double = 0
@Published var calories: Double = 0
@Published var elapsedTime: TimeInterval = 0
@Published var isActive = false
func startWorkout(type: HKWorkoutActivityType) async throws {
let config = HKWorkoutConfiguration()
config.activityType = type
config.locationType = .outdoor
workoutSession = try HKWorkoutSession(
healthStore: healthStore,
configuration: config
)
workoutBuilder = workoutSession?.associatedWorkoutBuilder()
workoutBuilder?.dataSource = HKLiveWorkoutDataSource(
healthStore: healthStore,
workoutConfiguration: config
)
workoutSession?.delegate = self
workoutBuilder?.delegate = self
let start = Date()
workoutSession?.startActivity(with: start)
try await workoutBuilder?.beginCollection(at: start)
isActive = true
}
func endWorkout() async throws {
workoutSession?.end()
try await workoutBuilder?.endCollection(at: Date())
try await workoutBuilder?.finishWorkout()
isActive = false
}
}
// 期待出力:
// ワークアウト開始後、心拍数・カロリーがリアルタイムで更新
// heartRate = 142.0(bpm)
// calories = 87.3(kcal)
// elapsedTime = 1200.0(秒 = 20分)Step 4: ホーム画面ウィジェットを追加
最後にウィジェットを追加します。
ホーム画面ウィジェットを追加してください。
【ウィジェットの仕様】
- サイズ: Small(2x2)と Medium(4x2)の2種類
- Small: 今日の歩数 + 円形プログレスリング
- Medium: 歩数 + カロリー + 心拍数を横並びで表示
【技術要件】
- App Group を使って iPhone アプリとデータを共有
- TimelineProvider で15分ごとにデータを更新
- WidgetKit のアクセントカラーをフィットネステーマ(グリーン系)に
- ウィジェットタップで iPhone アプリのダッシュボードを開く(DeepLink)ウィジェットの核心は TimelineProvider です。App Group 経由でデータを読み取り、15分間隔で更新します。
// FitnessWidget.swift — ウィジェットのタイムラインプロバイダー
import WidgetKit
import SwiftUI
struct FitnessEntry: TimelineEntry {
let date: Date
let steps: Int
let stepGoal: Int
let calories: Double
let heartRate: Double
}
struct FitnessTimelineProvider: TimelineProvider {
// App Group 経由でデータ読み取り
let defaults = UserDefaults(
suiteName: "group.com.yourapp.fitness"
)
func getTimeline(
in context: Context,
completion: @escaping (Timeline<FitnessEntry>) -> Void
) {
let steps = defaults?.integer(forKey: "todaySteps") ?? 0
let goal = defaults?.integer(forKey: "stepGoal") ?? 10000
let cal = defaults?.double(forKey: "todayCalories") ?? 0
let hr = defaults?.double(forKey: "latestHeartRate") ?? 0
let entry = FitnessEntry(
date: Date(), steps: steps,
stepGoal: goal, calories: cal, heartRate: hr
)
// 15分後に次の更新をスケジュール
let next = Calendar.current.date(
byAdding: .minute, value: 15, to: Date()
)!
let timeline = Timeline(
entries: [entry], policy: .after(next)
)
completion(timeline)
}
// ... placeholder, snapshot 省略
}
// 期待出力:
// ホーム画面に歩数リングが表示される
// 15分ごとに最新データに更新
// タップで iPhone アプリが起動応用パターン
パターン 1: ワークアウトの自動検出
Apple Watch には CMMotionActivityManager を使ったモーション検出機能があります。Rork Max に以下のようなプロンプトを追加すると、ユーザーがランニングを始めたことを自動検出してワークアウト記録を提案できます。
CMMotionActivityManager を使って、ユーザーがランニングを始めたことを
自動検出し、「ワークアウトを開始しますか?」という通知を送る機能を
追加してください。パターン 2: 週間レポートの通知
毎週月曜日に先週の運動データをまとめた通知を送る機能も効果的です。
毎週月曜日の朝9時に、先週の運動サマリー(合計歩数、平均心拍数、
ワークアウト回数)をローカル通知で送る機能を追加してください。パターン 3: HealthKit データのエクスポート
ユーザーが自分のデータを CSV でエクスポートしたい場合のプロンプトです。
設定画面に「データをエクスポート」ボタンを追加し、過去30日間の
歩数・カロリー・睡眠データを CSV ファイルとして共有シートで
書き出す機能を実装してください。トラブルシューティング
HealthKit の認可がリジェクトされる
HealthKit の認可ダイアログでユーザーが拒否した場合、HKAuthorizationStatus が .sharingDenied になります。設定アプリへの誘導 UI を表示しましょう。Rork Max に「HealthKit の権限が拒否された場合に、設定アプリを開くボタンを表示してください」と指示すれば対応できます。
Apple Watch とのデータ同期が遅い
WatchConnectivity の transferUserInfo は即座に届かない場合があります。リアルタイム性が必要なデータには sendMessage を使い、バックグラウンド同期には transferUserInfo を使い分けてください。
ウィジェットが更新されない
WidgetKit のタイムライン更新はシステムが管理するため、正確に15分間隔にならないことがあります。iPhone アプリ側で HealthKit データを更新した際に WidgetCenter.shared.reloadAllTimelines() を明示的に呼び出すことで、ウィジェットの即座更新をリクエストできます。
ビルドエラー: App Group の設定ミス
iPhone アプリ・Watch アプリ・ウィジェットの3つのターゲットすべてで同じ App Group ID を設定する必要があります。Rork Max に「App Group の ID を group.com.yourapp.fitness に統一してください」と明示的に指示することで解決します。
ワークアウトセッションがバックグラウンドで停止する
watchOS ではバックグラウンドでのワークアウト記録に Extended Runtime Session が必要です。Rork Max が自動で設定しますが、うまくいかない場合は「HKWorkoutSession の Extended Runtime Session を有効にしてください」と追加プロンプトを送ってください。
公開・収益化のポイント
App Store 審査の注意点
HealthKit を使うアプリは Apple の審査が厳格です。以下のポイントを押さえましょう。
- NSHealthShareUsageDescription に明確な利用目的を記載する(例:「歩数と心拍数を表示するために HealthKit データを使用します」)
- 必要最小限のデータのみをリクエストする(不要なデータ型を要求すると審査でリジェクトされる)
- プライバシーポリシーに HealthKit データの取り扱いを明記する
- HealthKit データを外部サーバーに送信しない設計にする(送信する場合は明確な開示が必要)
収益化モデル
フィットネスアプリの一般的な収益化パターンは以下の通りです。
- フリーミアム: 基本機能(歩数・カロリー)は無料、詳細分析・Apple Watch 連携・CSV エクスポートをプレミアム機能に
- サブスクリプション: 月額 $4.99 / 年額 $29.99 のプランをRork Max の StoreKit 2 連携で実装
- ワンタイム購入: プレミアム機能を $9.99 の買い切りで提供
ASO(App Store 最適化)
フィットネスカテゴリは競争が激しいため、ニッチなキーワードを狙いましょう。「歩数計」「心拍数」だけでなく、「HealthKit ウィジェット」「Apple Watch ワークアウト記録」といった具体的なキーワードをメタデータに含めると効果的です。
まとめ
ここではRork Max を使って HealthKit × Apple Watch × ウィジェットを統合したフィットネストラッカーアプリを構築する全手順を解説しました。
ポイントを振り返ります。
- 段階的なプロンプト設計: iPhone → HealthKit → Watch → Widget の順に機能を追加
- HealthKitManager でデータ取得を集約: 歩数・カロリー・心拍数・睡眠データを一元管理
- WatchConnectivity で双方向同期: iPhone と Apple Watch のリアルタイムデータ連携
- App Group でウィジェットとデータ共有: 15分更新のタイムラインでホーム画面に表示
- 収益化: フリーミアム + StoreKit 2 サブスクリプションの組み合わせ
Rork Max の強みは、これまで数週間かかっていたマルチプラットフォーム開発を、プロンプトの組み合わせだけで実現できることです。Apple Watch アプリの基本やウィジェットの基礎、HealthKit の入門ガイドもあわせて参考にしてください。