はじめに
こんにちは。
今回も Kiro を使った開発に関する内容です。
みなさん、AWS Certified Generative AI Developer - Professional(AIP-C01)受験していますか〜??
私は本試験の勉強用に、自分専用の学習アプリを作りました。開発には今回もKiroを使い、Spec駆動開発で要件定義からコード実装まで一気通貫で進めました。
私自身はiOSアプリの開発は全くの未経験でしたが、Kiroを使うことでほぼ半日(しかも大半はKiroが実行するタスク内のコマンド実行のTrust(信頼)をするかどうかの判定で止まるくらい)で手元のiPhoneで勉強を開始できました。
本記事では、Kiroを使った開発体験と、SwiftUI + MVVMで構築したアプリのアーキテクチャについて紹介します。
完成したアプリの概要
| 項目 | 内容 |
|---|---|
| 対象試験 | AWS Certified Generative AI Developer - Professional(AIP-C01)(*) |
| モード | 練習(75問)/ 試験(75問・180分制限)/ 短時間(10問) |
| 主な機能 | 四者択一問題、複数選択問題、解説表示、履歴管理、セッション中断・復元 |
| 技術スタック | SwiftUI / Swift 6 / MVVM / UserDefaults / iOS 18+ |
| 動作環境 | 自分の iPhone15(iOS26) |
(*)ただし、この問題内容については、差し替えができるので、AIP-C01に限ったものではないです。また、問題自体は、後述の通り、ChatGPTなどの生成AIに生成してもらったものを使っています。
そもそも公開を前提にしていないので、XCodeと自分のiPhoneをリンクさせて使っています。この範囲であれば、無料でiPhoneアプリを動かせますし、問題を取り込んでビルドするので、オフラインでも勉強を続けられます。
Kiroによる開発フロー
Spec駆動開発とは
すでにみなさんもご存知かと思いますが、Kiroでは「Spec」という仕組みで、以下の流れで開発を進めます。
要件定義(requirements.md)
→ 技術設計(design.md)
→ 実装タスク(tasks.md)
→ 自動実装
各フェーズでKiroが工程ごとの文書を生成し、ユーザーがレビュー・承認してから次に進みます。
実際の流れ
- 要件定義: 「iOS試験勉強アプリを作りたい」と伝えると、Kiroが10個の要件(ユーザーストーリー + 受け入れ基準)を生成
- 技術設計: MVVM構成、データモデル、プロトコル定義、正確性プロパティ(15個)を含む設計書を生成
- タスク生成: Wave(依存関係に基づく並列実行グループ)に分割された46タスクを生成
- 自動実装: タスクを順次実行し、ビルド確認まで自動で実施
アーキテクチャ
今回も、Kiroと、Claude Opusを使って実装を行いました。
全体構成
Sources/
├── Models/ # データモデル(Question, QuizSession, etc.)
├── Services/ # ビジネスロジック(QuestionEngine, SessionManager, etc.)
├── ViewModels/ # 画面状態管理(QuizSessionViewModel, etc.)
├── Views/ # SwiftUI View層
└── Data/ # 問題データ(Swift構造体として組み込み)
主要コンポーネント
| コンポーネント | 責務 |
|---|---|
| QuestionEngine | 問題のバリデーション、ランダム選出、選択肢シャッフル、正誤判定 |
| SessionManager | セッションのライフサイクル管理(生成・中断保存・復元・完了) |
| ScoreCalculator | 正答率の計算 |
| HistoryStore | UserDefaultsによる履歴の永続化(モード別最新10件) |
| TimerManager | 試験モード用カウントダウンタイマー |
プロトコル設計
テスタビリティのため、全サービスをプロトコルで抽象化しています:
protocol QuestionEngineProtocol {
func selectQuestions(count: Int) -> [Question]
func judgeSingleChoice(question: Question, selectedIndex: Int) -> JudgmentResult
func judgeMultiChoice(question: Question, selectedIndices: Set<Int>) -> JudgmentResult
func loadValidQuestions() -> [Question]
}
技術的なポイント
1. 選択肢のシャッフル
何度も解くうちに「3番目が正解」と位置で覚えてしまう問題を防ぐため、出題時に選択肢の順番をシャッフルし、正解インデックスも追従させています。
private func shuffleChoices(_ question: Question) -> Question {
let shuffledIndices = Array(0..<question.choices.count).shuffled()
let newChoices = shuffledIndices.map { question.choices[$0] }
var newCorrectIndices = Set<Int>()
for oldIndex in question.correctIndices {
if let newIndex = shuffledIndices.firstIndex(of: oldIndex) {
newCorrectIndices.insert(newIndex)
}
}
return Question(
id: question.id,
text: question.text,
choices: newChoices,
correctIndices: newCorrectIndices,
type: question.type,
explanation: question.explanation
)
}
2. テキストデータからの問題変換
問題データはChatGPTなどの生成AIに作ってもらった問題を元にPythonスクリプトでパースし、Swift構造体に変換しています。
対応する入力形式:
問題1
企業はAmazon Bedrockを使用して...
A. 選択肢A
B. 選択肢B
C. 選択肢C
D. 選択肢D
正解: B
解説: Bedrcok Guardrailsは...
このあたりは Kiro がいい感じにパースをしてくれるので問題の範囲(問題文、選択肢、答え、解説)がわかるようになっていればOK。
3. @ Observable + @ MainActor
Swift 6のObservationフレームワークを使い、ViewModelを @Observable で定義。@MainActor でUI更新のスレッド安全性を保証しています:
@MainActor
@Observable
public final class QuizSessionViewModel {
public var selectedIndices: Set<Int> = []
public var isResultShowing: Bool = false
// ...
}
4. 結果表示中の操作ロック
回答確定後に選択肢を変更できないよう、isResultShowing フラグでガードしています:
public func selectChoice(at index: Int) {
guard !isResultShowing else { return }
// ...
}
5. セッション中断・復元
@Environment(\.scenePhase) でアプリのライフサイクルを監視し、バックグラウンド移行時に自動保存:
.onChange(of: scenePhase) { _, newPhase in
if newPhase == .background || newPhase == .inactive {
if quizViewModel.session.state == .inProgress {
quizViewModel.suspendSession()
}
}
}
成果物の画面の雰囲気
非常にシンプルですが、レスポンスよく動きます。アイデアが出れば機能追加して自分好みのアプリに育てることも可能。
結果画面は円グラフを表示したり、正解数を、分数で表示してもよいかなと考えているところです。
Kiroを使った所感
良かった点
いつも通りの感想にはなってしまいますが。
-
要件定義から実装まで一貫した流れで進められる。手戻りが少ない
- これに関しては、作りたいもののアイデアがあれば、サクッと形にできて、さらにVive Codingよりもしっかりしたものを作れるのがよいですね。あとから機能追加をしたいとか、修正したいといったときにも柔軟に対応が可能
- プロパティベーステストの設計まで含めた設計書を自動生成してくれる
- 並列タスク実行で、独立したコンポーネントを同時に実装できる
- テキストデータの変換など、雑務的な作業も対話的に依頼できる
注意点
- Xcode固有の設定(Bundle ID、署名、デバイス信頼)はKiroだけでは完結しない
- 生成されたコードは動くが、UIの細かい調整(スクロール位置のリセットなど)は実機やXCodeのiPhoneシミュレータでの動作確認後にフィードバックが必要
問題データの追加方法
テキストファイルを用意して、Kiroに「このファイルを読み込んで」と伝えるだけで変換・組み込みまでやってくれます。
前述のように、ChatGPTなどで問題を生成し、Markdown形式で出力してもらうのも有効です。ただ、うちのChatGPTでは、何度行ってもMarkdown形式で出力してくれませんでした。
まとめ
Kiroを使うことで、iOS開発の経験が浅くても、Spec駆動で設計から実装まで効率的に進められました。特に試験勉強のような「自分だけのツール」を素早く作りたい場面では、AIアシスタントとの対話的な開発が非常に有効だと感じました。
自分だけのアプリってよいですよね。アイデアをサクッと形にできる、Kiroはなくてはならない素晴らしいパートナーですね。
記載されている会社名、製品名、サービス名、ロゴ等は各社の商標または登録商標です。



