「勉強のやる気が出ない」を技術で殴るために、iOS 17のInteractive Widgetとカメラ機能をフル活用した話
はじめに
「勉強、始めるまでが一番つらくないですか?」
机に向かってもついスマホを触ってしまう。
いざ始めても「自分はいったい何時間頑張ったのか」が目に見えないから、達成感がなくて続かない。
そんな自分の悩みを解決するために、「スマホを触る暇があったら、ホーム画面から0秒で勉強を開始できるアプリ」 を作りました。
名前は 『StudyReel (スタディリール)』 です。
技術的な縛りは 「徹底的にiOSネイティブであること」。
FlutterやReact Nativeも便利ですが、最新の Interactive Widget (iOS 17+) や SwiftData のパフォーマンスを極限まで引き出すために、あえて SwiftUI 100% で挑みました。
作ったもの:StudyReel
「学習の瞬間を記録し、モチベーションを可視化する」

主な機能
- Interactive Widget: アプリを開かずに、ホーム画面からワンタップでポモドーロタイマーを開始。
-
Visual Stats: 勉強時間を
Swift Chartsで美しくグラフ化。 - App Group Sync: ウィジェットとアプリ本体でデータをリアルタイム同期(iOSのサンドボックス制限を越えてデータを共有する仕組み)。
技術スタック:Appleの最新技術をしゃぶり尽くす
今回は「学習コスト」を度外視して、Appleが提供する最新フレームワークを積極的に採用しました。
| コンポーネント | 技術 | 役割 |
|---|---|---|
| Language | Swift 5.9 | 安全でモダンな記述。 |
| UI | SwiftUI | 宣言的UI。アニメーションの実装が楽。 |
| Database | SwiftData | Core Dataの後継。@Model マクロで定義が爆速。 |
| Widget | WidgetKit | 今回の主役。 インタラクティブなホーム画面体験。 |
こだわり①:アプリを開かせない「Interactive Widget」
かつてのiOSウィジェットは「情報の表示」しかできませんでした。
しかしiOS 17からは、ウィジェット上のボタンを押して直接コードを実行できる App Intents が導入されました。
これを使わない手はありません。StudyReelでは、「勉強しよう」と思った0.5秒後にはタイマーが回っている 体験を実現しました。
// 実際のコード:App Intentによるタイマー開始
@available(iOS 17.0, *)
struct StartTimerIntent: AppIntent {
static var title: LocalizedStringResource = "Start Pomodoro"
@Parameter(title: "Duration")
var duration: Int
// このメソッドがウィジェットのボタンから直接呼ばれる
func perform() async throws -> some IntentResult {
// AppGroup経由でデータを保存
PomodoroData.startTimer(minutes: duration)
return .result() // UIを即座にリロード
}
}
この perform() メソッドの中で UserDefaults (App Group) を更新することで、アプリ本体を起動することなく、裏側でタイマー状態を同期しています。
「アプリを起動する」という些細なハードルすら取り除くことが、継続の鍵だと考えたからです。
実験中の機能:タイムラプス自撮り
(※現在実装中のα機能です)
ただ時間を計るだけでなく、「勉強している自分の姿」 をタイムラプスで記録する機能も実験しています。
「誰かに見られている(または後で見返す)」という感覚は、最強の集中スイッチになるからです。
// AVFoundationを使ったプレビュー実装
struct CameraPreview: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = PreviewView()
// 録画セッションをレイヤーに接続
recorder.startSession(previewLayer: view.previewLayer)
return view
}
}
こちらは AVFoundation をゴリゴリに使って実装しています。
SwiftUIとのブリッジ (UIViewRepresentable) が必要になりますが、ネイティブならではの滑らかなプレビュー動作は必見です。
こだわり③:ユーザーの声で進化するUX
「タイマー中に画面が消えてしまうと困る」「今日は顔を撮りたくない」
そんな実際のユーザー(身近な人)からのフィードバックを即座に反映しました。
-
画面自動ロックの無効化: タイマー稼働中は
UIApplication.shared.isIdleTimerDisabledを制御し、画面常時点灯を実現。 - 録画トグル機能: 「集中はしたいけど撮影はしたくない」という気分のために、タイムラプス機能のON/OFFを実装。
個人開発だからこそ、こうした「かゆいところに手が届く」改善を爆速で回せるのが強みです。
おわりに
Web技術(React/Next.js) も便利ですが、OSの機能を限界まで引き出すなら、やはり ネイティブアプリ開発 に軍配が上がります。
特にWidgetKitのような「OSの特権」を使える機能は、ユーザー体験を劇的に変えるポテンシャルを持っています。
もし「最近勉強続いてないな…」という方がいたら、ぜひStudyReelで 「まずはホーム画面をタップ」 してみてください。
そこから、あなたの新しい習慣が始まるかもしれません。
GitHubリポジトリ
Discussion