Claude Codeに全任せ:iOSアプリを5日でリリースした軌跡
はじめに
Claude Code自体はリリース当初に触っていた。でも、非エンジニア(一応元UXデザイナー)で事業開発やプロダクトマネジメントをやっている自分にとっては、完全に開発を任せきれるイメージがまだなかった。結局、中途半端に触って、手に馴染まずそのまましばらく放置していた。なんならGeminiやChatGPTをメイン環境としていた。
年末年始、少し長めの休みを取っていたタイミングで、Claude Codeの開発者であるBorisさんのツイートがバズり始めていた。「AIがコードを書く」というレベルではなく、「AIがほぼ自律的に開発する」という新しいスタイル。その実用性と革命性が、海外及び日本のAIコミュニティで話題になっていた。
I'm Boris and I created Claude Code. Lots of people have asked how I use Claude Code, so I wanted to show off my setup a bit.
My setup might be surprisingly vanilla! Claude Code works great out of the box, so I personally don't customize it much. There is no one correct way to
ここまでバズってるなら、改めて触らねばと思って手を取った。
そして、ただ単にVibe Codingを試すというより、ひょんなことから「iOSアプリ」という題材にたどり着いた。
ということでせっかくなら、モバイルアプリを超高速でリリースするスプリントとして記録を残そう。
コードだけじゃない。要件定義、設計ドキュメント、画面構成図、アプリアイコン用のプロンプト、カラーリング検証用のWebサイト、リリース自動化まで。「何もかもClaudeにやらせよう」を徹底したら、どこまで高速化できるだろう?
この記事は、その実験の記録。
先に書いておくと、
0:06
今どきこんなかっけえ動画勝手に作ってくれるらしい。サンキューAppleさん。
Claude Code Sprint:5日間でアプリをリリースする
Googleが提唱するデザインスプリントというフレームワークがある。5日間で課題発見からプロトタイプ検証までを行う手法だ。
デザインスプリントは「プロトタイプ」で終わる。アイデア検証が目的だからだ。
でも、AIと協業する時代には、もう一歩先に進める。5日間で「リリース可能なアプリ」まで作れないか?
勝手に名付けて Claude Code Sprint。とする。
デザインスプリントとの最大の違いは、プロトタイプではなく「本物」ができること。
Claudeがコードを書き、設計書を作り、CI/CDを整備してくれる。人間は「ディレクション」に集中する。
以下は、この Claude Code Sprint を実践した5日間の記録だ。
Day 1: 要件定義・コンセプト策定
今回の主目的は、Claude Codeを使った「Vibe Coding」の練習だった。とはいえ、無価値なものを作っても仕方ない。実際に自分が感じている課題を些細なものでもいいから解決しよう。そう考えた。
子どもの動画を家族で共有できる某アルバムアプリを使っている。便利なんだけど、無料ユーザーには動画は2分までという制限がある。(すいません、ケチで)
子供の動画は平気で5分、10分と長くなるので、毎回手動で分割するのが面倒だった。なんならこの制限があるゆえに、日々撮影している動画の長さが2分以上にならないように撮影しているさみしい自分に気づいてしまった。これはいかん!
ということで、「動画を2分ごとに自動分割してアップロードできるアプリが欲しい」これは初アプリ開発のVibe Codingの題材としてちょうどいい。
てな流れで、解決する課題・コンセプトは「どんな動画も2分ごとに分割して、超楽に共有できるアプリ」に決めた。
最初はWeb版で作ろうとした
実は、そもそもClaudeのチャット(Web版)で要件を整理しながら、最初に考えたのはWebアプリだった。(なのでiOSアプリのスプリントになったのは後付である)
Claude技術要件: - フロントエンドのみ(サーバーレス) - ffmpeg.wasm を使用してブラウザ内で動画処理 - PWA対応(ホーム画面に追加できるように)
ffmpeg.wasmを使えば、サーバーなしでブラウザ内で動画処理ができる。サーバー代もかからないらしいし、良さそう!と思った。ということで、開発するためのプロンプトも書かせてみた
# 動画2分分割Webアプリ 開発プロンプト
## 概要
家族共有アルバムアプリが2分までの動画しかアップロードできないため、任意の長さの動画を2分ごとに自動分割するWebアプリを作成してください。
## ターゲット
- デバイス: iPhone(Safari)
- 想定動画長: 5〜10分程度
- ユーザー: 個人利用(自分用)
## 必須機能
1. **動画選択**: カメラロールから動画を選択できる
2. **自動分割**: 選択した動画を2分(120秒)ごとに自動分割
3. **ダウンロード**: 分割された動画を1本ずつカメラロールに保存できる
## 技術要件
- **フロントエンドのみ**(サーバーレス)
- **ffmpeg.wasm** を使用してブラウザ内で動画処理
- **PWA対応**(ホーム画面に追加できるように)
- レスポンシブデザイン(iPhone最適化)
## UI仕様
### 画面構成(シンプルに1画面)
┌─────────────────────────┐
│ 📹 動画を2分で分割 │ ← タイトル
├─────────────────────────┤
│ │
│ [ 動画を選択 ] │ ← ファイル選択ボタン
│ │
│ 選択中: video.mov │ ← 選択後に表示
│ 長さ: 7分30秒 │
│ → 4本に分割されます │
│ │
│ [ 分割開始 ] │ ← メインアクションボタン
│ │
│ ━━━━━━━━━░░░░ 60% │ ← 処理中プログレスバー
│ │
│ ✅ part1.mp4 [保存] │ ← 分割完了後、各ファイルの
│ ✅ part2.mp4 [保存] │ ダウンロードボタン
│ ✅ part3.mp4 [保存] │
│ ✅ part4.mp4 [保存] │
│ │
│ [ 全部まとめて保存 ] │ ← 一括ダウンロード(任意)
│ │
└─────────────────────────┘
### デザイン指針
- 背景: 白または薄いグレー
- メインカラー: 青系(#007AFF など iOS風)
- フォント: システムフォント
- 角丸ボタン、十分なタップ領域(44px以上)
- シンプル&クリーン
## 処理フロー
1. ユーザーが動画を選択
2. 動画のメタデータ(長さ)を取得して表示
3. 「分割開始」ボタンで処理開始
4. ffmpeg.wasmで2分ごとに分割
- 再エンコードなし(-c copy)で高速処理を優先
- 無理なら再エンコードでもOK
5. 分割完了後、各ファイルのダウンロードリンクを表示
6. ユーザーが1本ずつ保存
## ファイル命名規則
- 元ファイル名_part1.mp4
- 元ファイル名_part2.mp4
- ...
## エラーハンドリング
- 動画以外のファイルが選択された場合 → エラーメッセージ
- 2分以下の動画 → 「この動画は分割不要です」と表示
- 処理中にエラー → リトライを促すメッセージ
- メモリ不足(大きすぎる動画) → 警告メッセージ
## PWA設定
- manifest.json を作成
- アイコン(シンプルなもので可)
- 「ホーム画面に追加」対応
- オフライン対応は不要
## ディレクトリ構成(例)
video-splitter/
├── index.html
├── style.css
├── app.js
├── manifest.json
├── icon-192.png
├── icon-512.png
└── sw.js (Service Worker、最小限でOK)
## 注意事項
- iPhoneのSafariはメモリ制限があるため、10分を超える動画では警告を出す
- ffmpeg.wasmの初回ロードは時間がかかるので、ローディング表示を入れる
- 動画のコーデックによっては処理に時間がかかる可能性あり
## 優先度
1. **必須**: 動画選択 → 2分分割 → ダウンロード(基本機能)
2. **推奨**: PWA対応、プログレス表示
3. **任意**: 一括ダウンロード、分割秒数のカスタマイズ
---
まずは基本機能を動かして、動作確認してから細かい調整をお願いします。実際に作ってみた。すぐ動いた。AIすごい。と一瞬思ったが、問題が山積みだった。
- iPhoneのSafariはメモリ制限があり、長い動画だとすぐクラッシュする
- 処理時間が長く、途中でタイムアウトする
- 300MB以上の動画に対応するにはサーバーサイドでの処理がマストで使えな
- UIが微妙(そもそも元のプロンプトも読まないでぶん投げてるから仕方ないんだけど)
「これは使い物にならないな」と思って一瞬諦めた。
iOSネイティブへの転換
調べていくと(Claudeを詰めていくと)、iOSのAVFoundationというフレームワークを使えば、端末内で高速に動画処理ができることがわかった。
- 再エンコードなしで超高速
- メモリ制限を気にしなくていい
- カメラロールとの連携もスムーズ
大問題は、アプリのデザインフェーズまでは仕事で自分が手を動かしていたことはあるが、アプリ開発なんてしたことがないということ。生成AI自体になって以降Vibe CodingでWebで動くシステムは作ったことが幾度かあったが、意外とネイティブアプリはなかった。(なんとなくAIにはネイティブは苦手なイメージがあったから)
とはいえ、ちょうどその年末年始のタイミングで海外ではAIでアプリを個人開発する事例がバンバン出てきてたし、アプリのコーディングを支援するツールも色々出てた。知ってはいたけど、なんとなく手を出してなかっただけ。
「意外といけるんじゃね?」
ということで思い切って、iOSネイティブアプリに転換することにした。
要件定義フェーズと言いつつ、まずWeb版を作ってアプリにPivotするまで意思決定出来ているのは、AI時代ならではの速度感である。
--ここまで1時間くらいかな---
Day 2: 初期構築
とりあえず雑に投げてみた
動画を2分ごとに分割するiOSアプリを作りたい。要件定義書を元に作って。
これだけ。「まあ、とりあえず投げてみるか」くらいの気持ち。
するとClaude Codeは淡々とファイル構成を作り、SwiftUIでViewを書き、AVFoundationで動画処理のロジックを実装していく。
数分後、一応Xcodeで動くものができた。
でも当然ボロボロ動いたとはいえ、完成度はお察し。
- iPhone 17 Pro Maxのサイズに未対応でレイアウトが崩れる
- (上下に永遠に消えない黒い余白が生まれるw)
- UIが猛烈に使いづらい、圧倒的なタスク志向(後述)
- 細かいバグ、ありすぎ
でも冷静に考えると、めちゃくちゃ適当なWeb用のプロンプトで投げたのに、そもそもネイティブアプリとしてワークするものになってる。コンポーネントの雰囲気を見ても、しかもなんとなくiOSの標準に則った開発をしてくれそうな匂いはする。
※当時のスクショを掘り返すのが大変だったので割愛
ただ、プロンプト適当だったしな。UXの課題や方向性を真面目に言語しつつ、本格的に指示を与えれば、クオリティ高い実装まで割とすぐ持っていけそうだな。という感覚を、このDay 2で得た。
--ここまで3時間くらいかな---
Day 3: ブラッシュアップ(HIG・OOUI観点追加)
よし、そろそろ本気出すか!
Day 2は「とりあえず動かす」がゴールだった。雑なプロンプトでも動いた。じゃあ次は、専門家の目線を入れていこう。
まず、Human Interface Guidelines(HIG)。AppleがiOSアプリの設計指針として公開しているドキュメントだ。タップターゲットは44pt以上、Dynamic Type対応、アクセシビリティ考慮...こういった「iOSアプリとしての品質基準」が定められている。
そして、OOUI(Object-Oriented User Interface)という設計パターン。Day 2の成果物は圧倒的なタスク指向になってた。「分割する」ボタンがドーンとあって、動画を選ぶ流れ。これをオブジェクト指向に変える。
タスク指向: [分割する] → [動画を選ぶ]
OOUI: [動画を選ぶ] → [分割する / 共有する / 削除する]
HIGの基礎を叩き込んで、OOUIで設計し、コンポーネントを指定すれば良い感じになるだろう。そんな目論見でDay 3をスタートした。
「iOSアプリとしての品質を上げるには何が必要か」HIGとOOUIという観点はUIデザイナーがデザインする上では当たり前の当たり前にケアさえれる論点であるため、それをClaudeに伝えた。
HIGの観点を入れて、OOUIで設計し直したい。今回は簡易的で構わないのでWeb Searchで文献を検索し、要点をまとめて.mdファイルにまとめてコンテキストとして保存して。
この指示を出したら、Claudeがコンテキストとなるドキュメントを3つ作成してくれた。
📄 HIG_GUIDELINES.md
📄 OOUI_DESIGN.md
📄 SWIFTUI_PATTERNS.md
HIGの要点、OOUIの設計パターン、SwiftUIのベストプラクティス。これらをプロジェクト内に保存しておけば、Claudeが実装時に参照してくれる。
この3つのドキュメントを読み込んだ上で、要件定義ドキュメントを元に実装し直して
すると、Claudeがだいぶ良い感じの実装プランドキュメントを作成してきた。
- オブジェクトモデル(Video, SplitResult, VideoPart)
- 4画面の詳細設計
- ナビゲーションフロー図
- デザイントークン(スペーシング、カラー、タイポグラフィ)
- アクセシビリティ要件
- 実装優先順位さらに画面構成図をASCIIアートで提示してきた。
┌─────────────────────────────────┐
│ ナビゲーションバー │
│ 「動画ライブラリ」 │
├─────────────────────────────────┤
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │ 🎬 │ │ 🎬 │ │ 🎬 │ │
│ │サムネ │ │サムネ │ │サムネ │ │
│ │5:30 │ │12:45 │ │3:20 │ │
│ │旅行 │ │誕生日 │ │公園 │ │
│ └───────┘ └───────┘ └───────┘ │
└─────────────────────────────────┘おお、これでアプリの全体像がイメージできるようになった。
「めちゃくちゃ良い!けどまだ磨ける」
設計ドキュメントを見て実際に実装されたものを、実機で触ってみた。驚くべきことに、だいぶ良い感じになった。
すると早速、また気になる点が。「動画詳細画面」と「分割結果画面」が別々にあるんだけど、この2画面、統合した方が自然じゃない?
動画を選ぶ → 詳細を見る → 分割する → 結果を見る → 戻る → また詳細を見る...
この遷移、冗長じゃん。詳細画面に分割結果も表示すれば、ユーザーは1つの画面で完結できる。そもそもコアオブジェクトの「動画」が、分割結果を保持するべきじゃない?という。
Claudeは設計ドキュメント通りに4画面構成で作ってきた。でも、よくある話で、ドキュメントを読んだときには気づいていなかったけど実機触った瞬間違和感に気づくやつ。
動画詳細画面と分割結果画面、統合した方がいいと思う。そのうえで、最も重要なアクションは「一括共有」だからそこのボタンを最大限押しやすくしてくれ。最下部に固定してフローティングするボタンを置いておこう。
Claudeに伝えたら、すぐ統合を実装してくれた。ナビゲーション階層が1つ減って、UXがシンプルに。
余談:
ちなみに「2分に分割するみたいなシンプルなアプリって、すでに世の中にあるんじゃね?」という疑問は当然あった。調べてみたら、もちろんあった。何個か。
ただ、それらはあくまでローカルに都度保存することを前提としている。分割した動画をカメラロールに保存して終わり、アップロードはそれから、みたいな。つまり意外とステップが多い。
iOSの共有シートを使えば、分割した動画を一括で共有できるんじゃないか?家族アルバムアプリにそのままアップロードできるんじゃないか?という仮説が生まれた。ためしにやってみたら、いけちゃった。
競合アプリを2つほどダウンロードして試してみた結果、「カットから共有までが圧倒的にシームレス」という差別化ポイントが見えた。せっかくなら、ここを強みにして作ろう。と決めた。
余談おわり
--ここまで6時間くらいかな---
Day 4: クリエイティブ(ロゴ・カラーリング)
正直、もうこれで完成でよくない?
Day 3までで、機能面は揃った。動画を選ぶ、分割する、保存する、共有する。全部できる。
標準コンポーネントを参照しているから、使い心地もかなり良い。正直、もうこれで完成でいいじゃんという感じだった。
でもせっかくなら家族に配りたいしな。でもTestFlightで配布するにはApple Developer Programへの登録が必要。年間12000円。まあ、せっかくだし良いか?とえいやで登録した。 (家族アルバムアプリのサブスクをケチるために始めたのに、Developer Programに入会する姿勢、自分でも意味がわからない)
せっかくなら、アプリアイコンも欲しくなった。
TestFlightに登録しようとすると、アプリアイコンが必要になる。白い四角のままじゃ寂しい。
アイコンを付けようとすると、今度はアプリ全体のビジュアルも標準コンポーネントまんまじゃちょっと物足りなくなってきた。
正直、遊びのレベル。でもせっかくだから、ちょっとブランド感出してみるか。
まずアイコン。今回は「Claudeに任せる」がコンセプトなので、それに従って。
アプリの実装内容と要件定義のドキュメントを元に、ターゲットとなるユーザーに受け入れられるアプリアイコン用の画像生成プロンプトを書いて。3パターンほど。
Design a cute and simple iOS app icon for "2分ちょっきん" (a video splitting app that cuts videos into 2-minute segments).
Style:
- Flat design with soft, rounded shapes
- Kawaii/cute Japanese aesthetic
- Minimalist and clean
Elements:
- A pair of cute scissors (main motif) with rounded, friendly appearance
- Film strip or video frame being cut
- The number "2" subtly incorporated
- Soft pastel color palette (light pink, mint green, or soft purple as main color)
Requirements:
- iOS app icon format (rounded square)
- Simple enough to be recognizable at small sizes
- Friendly and approachable feeling
- No text in the iconプロンプト例
そしてそのClaudeが書いてくれたプロンプトを、画像生成AI(Nano Banana Pro)に投げた。何パターンか生成して、一番良さそうなのを選んだ。パステルカラーでかわいい。
カラーリング検証用Webサイトで色検証
アイコンができた。このカラーリング(ミントグリーンとピンク)、意外と良いな。ちょっくらアプリ全体に反映させるか。
でも、いきなりアプリに実装して「なんか違う」ってなったら手戻りがデカいし、せっかくの標準感満載の良い感じにアプリが台無しになったらダルいしな。事前にイメージ確認したいな...ということで
アイコンのカラーリングをアプリに適用する場合のカラースキームを提案して
カラースキームをアプリに適用したときのイメージを確認できるWebサイトを作って
:root {
/* ブランドカラー */
--color-primary-mint:
#A8E6CF; /* 背景など */
--color-accent-pink:
#FF8B94; /* ボタン、強調 */
/* テキスト・ボーダー */
--color-text-main:
#6D5D5D; /* メインテキスト */
--color-border:
#8C7A7A; /* 薄めの境界線用 */
/* 背景・ベース */
--color-surface:
#F7FBF9; /* カード背景 */
--color-white-pure:
#FFFFFF; /* 必要時の白 */
}Claudeは簡単なHTMLページを作ってくれた。ボタン、カード、背景などにカラーパレットを適用したモックアップ。これを見て「これまた、悪くないな。この色でいこう」と判断してから、アプリ本体に適用。
捨てやすいHTML・CSSを書いてカラーリングのプロトタイピングしてからアプリに落とし込むのも悪くないな、となった。
ということで色も悪くなかったので、今度はこのWebサイトのカラーリング含めたビジュアルデザインをアプリ側に適用するプロンプトをClaudeに作らせて、アプリに反映
# iOS App Visual Redesign Prompt for Claude Code
## 🎯 目的
動画分割アプリ「ちょきっと」のiOSアプリを、OS標準のUIコンポーネント(UIKit/SwiftUI)を最大限活用しながら、指定のブランドカラーパレットでビジュアルリデザインする。
---
## 🎨 Design Tokens(必須適用)
以下のカラーパレットをアプリ全体に一貫して適用してください。
swift
// MARK: - Brand Colors (Assets.xcassets または Extension で定義)
extension Color {
// ブランドカラー
static let brandMint = Color(hex: "A8E6CF") // Primary - 背景、ナビゲーション
static let brandPink = Color(hex: "FF8B94") // Accent - CTA、強調
// テキスト・ボーダー
static let textMain = Color(hex: "6D5D5D") // メインテキスト
static let textSecondary = Color(hex: "8C7A7A") // サブテキスト、ボーダー
// サーフェス
static let surfaceCard = Color(hex: "F7FBF9") // カード背景
static let surfacePure = Color.white // 必要時の白
// 派生色(自動生成または手動調整)
static let mintLight = Color(hex: "C8F0DF") // ミント薄め
static let pinkLight = Color(hex: "FFB5BB") // ピンク薄め
}
// UIKit用
extension UIColor {
static let brandMint = UIColor(hex: "A8E6CF")
static let brandPink = UIColor(hex: "FF8B94")
static let textMain = UIColor(hex: "6D5D5D")
static let textSecondary = UIColor(hex: "8C7A7A")
static let surfaceCard = UIColor(hex: "F7FBF9")
}
---
## 📐 デザインルール
### 1. 角丸(Corner Radius)
すべてのUIコンポーネントで統一した角丸を適用:
| コンポーネント | Corner Radius |
|---------------|---------------|
| 大きなカード、モーダル | 24px |
| ボタン(大) | 16px または capsule |
| ボタン(小)、入力フィールド | 12px |
| サムネイル、アイコン背景 | 12px |
| 小さなバッジ | 8px |
### 2. シャドウ
柔らかいシャドウで奥行きを表現(iOS標準の.shadowより控えめに):
swift
.shadow(color: Color.textMain.opacity(0.08), radius: 12, x: 0, y: 4)
### 3. ボーダー
アクセントとして太めのボーダーを使用する場面あり(2-3px、textSecondary色)
### 4. タイポグラフィ
**フォント: SF Rounded(システム標準)を使用**
swift
// 見出し(大)
.font(.system(.largeTitle, design: .rounded, weight: .bold))
// 見出し(中)
.font(.system(.title2, design: .rounded, weight: .bold))
// 見出し(小)
.font(.system(.headline, design: .rounded, weight: .semibold))
// 本文
.font(.system(.body, design: .rounded))
// サブテキスト
.font(.system(.subheadline, design: .rounded))
// キャプション
.font(.system(.caption, design: .rounded))
**フォントルール:**
- Dynamic Type完全対応を維持(`UIFontMetrics`自動適用)
- カスタムフォントの埋め込み禁止(アプリサイズ肥大化防止)
- ロゴ「ちょきっと」のみ画像またはSVGで対応可
- `#000000`は使用禁止 → `textMain`に置換
- `#666666`等のグレーは → `textSecondary`に置換
**UIKit使用時:**
swift
// UIKitでSF Roundedを使用する場合
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
.withDesign(.rounded)!
let font = UIFont(descriptor: descriptor, size: 0) // size: 0 でDynamic Type追従
---
## 🧩 コンポーネント別 適用ガイド
### NavigationBar / ToolBar
swift
// SwiftUI
.toolbarBackground(Color.brandMint, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.tint(Color.textMain)
// UIKit (AppDelegate or SceneDelegate)
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .brandMint
appearance.titleTextAttributes = [.foregroundColor: UIColor.textMain]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.textMain]
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
UINavigationBar.appearance().tintColor = .textMain
### TabBar
swift
// SwiftUI
.tint(Color.brandPink)
// UIKit
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.configureWithOpaqueBackground()
tabBarAppearance.backgroundColor = .surfaceCard
UITabBar.appearance().standardAppearance = tabBarAppearance
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
UITabBar.appearance().tintColor = .brandPink
UITabBar.appearance().unselectedItemTintColor = .textSecondary
### Buttons
swift
// Primary CTA Button(最も目立たせたいボタン)
Button("動画を分割") { }
.buttonStyle(.borderedProminent)
.tint(Color.brandPink)
.foregroundColor(.white)
.clipShape(Capsule())
// または カスタムスタイル
struct PrimaryCTAButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.headline)
.foregroundColor(.white)
.padding(.horizontal, 32)
.padding(.vertical, 14)
.background(Color.brandPink)
.clipShape(Capsule())
.shadow(color: Color.brandPink.opacity(0.4), radius: 8, y: 4)
.scaleEffect(configuration.isPressed ? 0.96 : 1.0)
.animation(.easeInOut(duration: 0.15), value: configuration.isPressed)
}
}
// Secondary Button(枠線のみ)
struct SecondaryButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.subheadline.weight(.medium))
.foregroundColor(Color.textMain)
.padding(.horizontal, 24)
.padding(.vertical, 12)
.background(Color.surfaceCard)
.overlay(
Capsule()
.stroke(Color.textSecondary, lineWidth: 1.5)
)
.clipShape(Capsule())
}
}
### List / Form
swift
// 背景色の適用
List {
// ...
}
.scrollContentBackground(.hidden)
.background(Color.brandMint)
.listRowBackground(Color.surfaceCard)
// セクションヘッダー
.headerProminence(.increased)
.foregroundColor(Color.textMain)
### Cards(カスタムコンポーネント)
swift
struct CardView<Content: View>: View {
let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
content
.padding(16)
.background(Color.surfaceCard)
.cornerRadius(16)
.shadow(color: Color.textMain.opacity(0.08), radius: 12, x: 0, y: 4)
}
}
### Progress / Slider
swift
ProgressView(value: progress)
.tint(Color.brandPink)
Slider(value: $value)
.tint(Color.brandPink)
### TextField / Input
swift
TextField("動画のタイトル", text: $title)
.textFieldStyle(.plain)
.padding(14)
.background(Color.surfaceCard)
.cornerRadius(12)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(Color.textSecondary.opacity(0.3), lineWidth: 1)
)
### Alert / Sheet
swift
// Sheetの背景
.presentationBackground(Color.surfaceCard)
.presentationCornerRadius(24)
// Alert - システム標準を使用(tintColorのみ変更)
.tint(Color.brandPink)
---
## 🖼️ Assets.xcassets 設定
### AccentColor
- Any Appearance: `#FF8B94`
- Dark Appearance: `#FF8B94`(または少し明るめに調整)
### Color Set を追加
以下の名前でColor Setを作成:
- `BrandMint` → `#A8E6CF`
- `BrandPink` → `#FF8B94`
- `TextMain` → `#6D5D5D`
- `TextSecondary` → `#8C7A7A`
- `SurfaceCard` → `#F7FBF9`
---
## ⚙️ Global Appearance Setup
swift
// App.swift または AppDelegate で実行
func setupGlobalAppearance() {
// NavigationBar
let navAppearance = UINavigationBarAppearance()
navAppearance.configureWithOpaqueBackground()
navAppearance.backgroundColor = .brandMint
navAppearance.titleTextAttributes = [.foregroundColor: UIColor.textMain]
navAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.textMain]
UINavigationBar.appearance().standardAppearance = navAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navAppearance
UINavigationBar.appearance().tintColor = .textMain
// TabBar
let tabAppearance = UITabBarAppearance()
tabAppearance.configureWithOpaqueBackground()
tabAppearance.backgroundColor = .surfaceCard
UITabBar.appearance().standardAppearance = tabAppearance
UITabBar.appearance().scrollEdgeAppearance = tabAppearance
UITabBar.appearance().tintColor = .brandPink
UITabBar.appearance().unselectedItemTintColor = .textSecondary
// Global Tint
UIView.appearance().tintColor = .brandPink
// Switch
UISwitch.appearance().onTintColor = .brandPink
// Slider
UISlider.appearance().minimumTrackTintColor = .brandPink
UISlider.appearance().maximumTrackTintColor = .textSecondary.withAlphaComponent(0.3)
}
---
## 🚫 禁止事項
1. **`#000000`(純黒)の使用禁止** → `textMain`を使用
2. **`#FFFFFF`(純白)の多用禁止** → 背景は`surfaceCard`、必要時のみ白
3. **iOS標準以外のカスタムナビゲーション実装禁止** → 標準UINavigationController/NavigationStackを使用
4. **過度なアニメーション禁止** → iOS標準のspringアニメーションを基本とする
5. **Dynamic Type無効化禁止** → アクセシビリティを維持
---
## ✅ 実装チェックリスト
- [ ] Color Extension を作成し、全カラーを定義
- [ ] Assets.xcassets に Color Set を追加
- [ ] AccentColor を `#FF8B94` に設定
- [ ] Global Appearance を AppDelegate/App.swift で設定
- [ ] NavigationBar のスタイル適用確認
- [ ] TabBar のスタイル適用確認
- [ ] 全ボタンのスタイル統一
- [ ] List/Form の背景色適用
- [ ] TextField のスタイル適用
- [ ] ダークモード対応(必要に応じて)
---
## 📝 追加指示
実装時に以下を意識してください:
1. **OS標準コンポーネント優先**: カスタム実装より標準UIKit/SwiftUIコンポーネントの見た目を変更する形で対応
2. **一貫性**: 同じ役割のUI要素は同じスタイルを適用
3. **アクセシビリティ**: コントラスト比、Dynamic Type、VoiceOverを考慮
4. **パフォーマンス**: 不要な再描画を避ける(Color定義はstaticに)
何か不明点があれば、このドキュメントを参照しながら質問してください。せっかくなのでiOS 26のLiquid Glassにも対応
カラーリングを調整するついでに、せっかくなのでiOS 26の新しいデザインシステム「Liquid Glass」にも対応してみることにした。
iOS 26のLiquid Glassデザインシステムに対応して。iOS 17-25では既存のデザインにフォールバックするように。
Claudeは6ファイル、+933行の変更を一気にやってくれた。主な変更はこんな感じ:
さらに触覚フィードバック(ハプティクス)も追加。ボタンを押したときに軽い振動が返ってくるようになった。
正直、見た目の違いは微妙かもしれないけど、「最新OSのデザイン言語に対応してる」という事実が嬉しい。しかもClaudeが一発でやってくれた。
最終的にこんな感じに。
ダークモードは...まあ、微妙
ライトモードはいい感じになった。ミントグリーンとピンクのアクセントが効いて、パパママが好きそうなかわいい雰囲気。
問題はダークモード。なんか、ブランド感が薄い。なぜか黒板みたいな緑背景に薄いピンクを指定してきた。
納得いかん!が、ダークモードは「後で改善する」リストに入れて、先に進むことにした。リリース優先!スピード命のプロジェクト出し!
--ここまで8時間くらいかな?---
Day 5: リリース
毎回手動でリリースは面倒くさい
App Storeにアプリを出すには、いくつかの手順が必要。
- Xcodeでアーカイブ
- App Store Connectにアップロード
- メタデータ(説明文、スクリーンショット)を設定
- 審査に提出
これを毎回手動でやるの、面倒くさすぎる。特にバグ修正で頻繁にアップデートする可能性がある初期段階では。
FastlaneのセットアップもClaudeに丸投げ
ちょうどいいタイミングで、海外の方のツイートでFastlaneというツールを知った。これを使えば、これらを自動化できるらしい。と。コマンド一発でApp Storeにアップロードできるようになるとか。
Fastlaneでリリース自動化をセットアップして
詳細はClaudは、Fastlane用の設定ファイルを作成し、必要なコマンドを整備してくれた。
fastlane beta # TestFlight配布
fastlane release # App Store提出これで、ターミナルでコマンド叩くだけでリリースできるように。楽すぎる。スクリーンショットも自動、プライバシーポリシー等の資料もAI生成、何もかもAIと壁打ちしながら解決して、無事リリース!!!!
ありがたいことに、審査も一発で通った
振り返ってみると...全部Claudeがやってた
Day 1からDay 5までを振り返ってみると、「全部Claudeに任せてアプリ開発とリリースまで」が本当に実現できてた。
じゃあ人間は何やったの?
- 方向性を決めた(解くべき課題の設定、Web版→iOS転換、HIG・OOUI採用など)
- 「これ使いたい」「これ微妙」を実機を触って伝えた
- 最終判断を下した
- コードは1行も書いていない
--ここまでで10時間くらいかな!お疲れ様でした!---
Day5といいつつ、休みの間時間を開けつつ実働10時間くらいなので、本気で時間を使えば1日でこのくらいのアプリなら出せちゃうということ。DBもないし、認証もないし、本当に簡易的なアプリだからというのが大きいけど。
まとめ:「全部AIに任せる」と本当に速い。速さにおいてはもう勝てない。圧倒的。
5日間を通じて気づいたこと。「全部任せる」の範囲、思ってたより広い。
最初は「コードを書かせる」くらいのイメージだった。でも実際には
- 要件整理の壁打ち相手とドキュメント化
- 実装前の設計ドキュメントの作成
- 画面構成図(ASCIIアート)の提案
- カラーリング検証用の簡易サイト作成
- アイコン用プロンプトの作成
- リリース自動化のセットアップ
ネイティブアプリだとしてもリリースまで全部任せられるのはすごい。
じゃあ人間は何をするのか
「全部Claudeに任せる」と言っても、人間の役割がなくなるわけじゃない。むしろ、やるべきことが明確になる。
1. 「解くべき課題」を決める
「動画分割アプリが欲しい」という最初の動機は人間から出てきた。Claudeは「何でも作れる」けど、「何を作るべきか」は判断しない。リアルな課題設定は人間の仕事。
2. 「どういう方向性か」を示す
Web版→iOSネイティブに転換、HIGとOOUIの観点を入れる、このカラーリングで行く。方向性は人間が決めた。AIはアプリはハードルが高いからWeb版でいいんじゃないか?って言ってたけど、それは違うと判断した。(舐められてるな)
3. 「これでいい / これは違う」を判断する
動画詳細と分割動画一覧の画面統合の判断、コア体験となる一括共有のボタンの配置の判断、ダークモード後回しの判断、アイコン選定。手触り感のある主観的な評価は人間にしかできない。
4. 専門知識を活かして舵を取る
UXデザイナーとしての視点で「この遷移は冗長・OOUIの観点入れないから使いづらい・」と判断できた。言うまでもないが、ドメイン知識や専門性、AIとの協業でこそ活きる。
結論
1億総アプリ開発者時代が来る...のか?
誰でも良いものが作れ、使われるかというと、それは全くない。
- そもそも「解くべき課題」を見つけるのが難しい
- 本当に使いやすいものにするためのラストワンマイルのUI/UX作り込み
- 今回は簡単なアプリだったから出会わなかったけど、拡張性の高いアーキテクチャ設計
- セキュリティの担保
- 集約集客…
などなど無限に専門的な論点は存在しているわけで、「作れる」のハードルの低下は間違いないが、1億人がこれでビジネスする世界にはならないだろうことも実感。
なんにせよ、僕が一番驚いたのはスピードだ。
思いついてから10時間ほどでアプリをリリースするところまでたどり着けた。
今回作ったものは極めてシンプルなアプリケーションだったとはいえ、何もない(そもそも作るものも決めてない)ところから、日々使いうる(少なくとも僕が使う)アプリのリリース10時間でそこまでいくのは、これまでの世界だとほぼありえなかったんじゃないかと思う。
僕個人としては、AIの価値は何よりもこのスピードだと思っている。
そしてなんとなくこの実装プロセスを経たことで実務でもエンジニアとの会話もよりスムーズになった気がしており(これまではドキュメントとUIデザインまでしかやれていなかったので)、実装モデルから思考する頭を手に入れるのも、企画側の人間として大事なことだなと実感した。
なにより、プロトタイピングの精度・速度を自分で猛烈に上げられるのが最高にいいですね。
ということで、皆さんアプリ開発しましょう!!!
せっかく作ったのでダウンロードしてくださいね 。無料です。
なお、この年末年始のおかげで私はClaudeどっぷりになり、完全に移行しました。
Want to publish your own Article?
Upgrade to Premium