Claude Code Hooksで個人iOSアプリの開発サイクルを効率化する

こんにちは!クラスター株式会社でクライアントエンジニアをしている@nkjzmです。

最近クラスターの開発チーム内で行っているAI勉強会の中で「個人iOSアプリ開発で使っているClaude Code Hooksの紹介」という発表しました。

発表では、

  • Claude Code Hooksを使ってコード品質を保つ工夫
  • Hooksでエラーを検知してClaude Code自身に修正させる方法
  • 実装が完了したらすぐに手元のiPhoneで確認できる仕組み

などについて紹介しています。Hooksを活用する上での参考になれば幸いです。

発表スライドはこちら speakerdeck.com

スライドでは口頭で補足している内容もあるので、文章でも紹介したいと思います。

個人iOSアプリ開発で使っているClaude Code Hooksの紹介

作っているアプリ

個人でClaude Codeを使って『毎日ジム』というiOSアプリを作っています。

毎日ジムでのClaude Code 活用

毎日ジムではClaude Codeが全体の76%くらいのコードを書いています*1。Claude Codeに大量のコードを書いてもらう上で、コード品質を保つための工夫は不可欠です。そこでClaude Code Hooksを活用しています。

毎日ジムのContributions

Claude Code Hooksとは

Claude Codeのライフサイクルの様々な時点で実行されるユーザー定義のシェルコマンドのことです。CLAUDE.md内でもタスクに関する指示を記載することはできますが、LLMによる実行では無視されてしまうことが多々あります。Claude Code HooksはLLMに依存しないため、確実に実行される特徴があります。

参考: Claude Code フックを始める - Claude Docs

Claude Code Hooksはいつ実行できる?

Hooksを設定できるタイミングは、下記のようにいろいろあります。個人的によく使いそうなものを太字にしました。

  • PreToolUse: ツール呼び出しの前に実行(ブロック可能)
  • PostToolUse: ツール呼び出し完了後に実行
  • UserPromptSubmit: ユーザーがプロンプトを送信したときに、Claudeが処理する前に実行
  • Notification: Claude Codeが通知を送信するときに実行
  • Stop: Claude Codeが応答を終了するときに実行
  • SubagentStop: サブエージェントタスクが完了するときに実行
  • PreCompact: Claude Codeがコンパクト操作を実行しようとする前に実行
  • SessionStart: Claude Codeが新しいセッションを開始するか既存のセッションを再開するときに実行
  • SessionEnd: Claude Codeセッションが終了するときに実行

Claude Code フックを始める - Claude Docs より

PreToolUseとPostToolUseは、もう少し細かく指定できる(matcher)

PreToolUse(ツールの呼び出し前)とPostToolUse(ツールの呼び出し後)に関しては、matcherという仕組みを使ってもう少し細かな指定をすることができます。

  • Task - サブエージェントタスク(サブエージェントドキュメントを参照)
  • Bash - シェルコマンド
  • Glob - ファイルパターンマッチング
  • Grep - コンテンツ検索
  • Read - ファイル読み取り
  • Edit、MultiEdit - ファイル編集
  • Write - ファイル書き込み
  • WebFetch、WebSearch - Web操作

Claude Code フックを始める - Claude Docs より

実際に開発で使っているHooksの抜粋(ファイルの編集後)

PreToolUseとmatcherを組み合わせて、「ファイルの編集後」に実行するように設定しているHooksです。*2

実行しているのは下記の3つで、内2つはClaude Codeに指示して作成したスクリプトです。

  • コードのフォーマッタ
  • jsonファイルのフォーマッタ
  • jsonファイルのバリデータ

Hooks実行時のエラーをClaude Codeに通知する

Hooksには、実行したコマンドの終了コードが2の時にstderrをClaude Codeにフィードバックする仕組みがあります。一般的なエラー時の終了コード"1"ではない点に要注意です。

この仕組みを活用することで、エラーが発生した時にClaude Codeが勝手に対処をしてくれる状態を作ることができます。

開発で使っているHooksでは、

  • フォーマッターの場合
    • 基本的にはフォーマット実行のみ
    • フォーマットできないような構文エラーがあるとClaude Codeに通知
  • ローカライズキーのバリデーションの場合
    • キーの過不足があったらClaude Codeに通知

という形でエラー通知がされるようにしています。

Hooksでエラーが出たときの実際の様子

上半分が、Hooksによるスクリプトが吐いたエラーです。

エラーの原因の他に、エラーを対応するための情報も併せて出力するような工夫をしています。これはCLAUDE.mdに記載しておく方法もありますが、コンテキストを忘れてしまう場合もあるため、必要な時に示した方が適切に対応してくれやすい気がします。

下半分は、実際にClaude Codeがエラーに対処し、適切な状態にしてくれた様子です。

実際に開発で使っているHooksの抜粋(応答終了時)

Claude Codeの応答終了時にもHooksを実行しています。上3つは先ほど紹介したものと同じ内容です。別のツールやコマンド経由で編集された場合などに実行されないことがあるため、念の為このような記載をしています。

後半の長いワンライナーコマンドでは、iOSアプリのビルドとインストール、iPhone実機上での起動までを行っています。個人開発なので自分のiPhoneのdevice idなどをベタ打ちしています。実行には30秒~1分ほどかかるためStop時にのみの記載にとどめています。

このコマンドを追加しておくことで、「Claude Codeに機能実装を依頼→しばらく放置→完了すると手元のiPhoneで実装された機能が触れる状態」という開発体験を実現することができます。Claude Codeによる高速な開発フローでは人間の確認作業がボトルネックになることが多いため、このような工夫も有効かと思います。

iOSアプリを実機で起動させる方法についてはこちらのブログが参考になりました。 note.com

おまけ:よくミスする操作の工夫

おまけとして開発中に発生した問題と対処について紹介します。

Claude Codeにjsonの編集をしてもらうと、括弧やカンマなどを考慮した編集が上手くいかず、頻繁に構文エラー状態が発生していました。そこで、専用のシェルスクリプトを用意して、json編集時に使うように指示することで大幅な改善が得られました。CLAUDE.mdの他、先ほどのHooksエラー通知時のメッセージでも指示するようにしています。

プロジェクト内のCLAUDE.mdより抜粋

最後に

今回は社内AI勉強会で発表した「個人iOSアプリ開発で使っているClaude Code Hooksの紹介」の内容を紹介しました。ぜひHooksを使う際の参考にしていただけると幸いです。

(発表中で紹介したアプリもリリース済みなので、もしよければ使ってみてください🙏)

EverydayGym

EverydayGym

  • Kohki Nakaji
  • Health & Fitness
  • Free
apps.apple.com

*1:Claudeによるcommitのauthorにはユーザーも含まれているため、ユーザーのみのcommit差分からClaude Codeによるcommit比率を計算した

*2:EditやWriteの他に、serenaというmcp経由で編集された場合の記載もしている