はじめに
前回の記事「AIが焙煎師の『未来』を創造する」から数日。完成したiOSアプリをより多くの人に体験してもらうため、PWA(Progressive Web App)対応に挑戦した。
しかし、その過程で得られたのは技術的な知見だけではなく、開発戦略における「選択と集中」の重要性という、より本質的な学びだった。
PWA対応への道のり
動機:友達・家族に気軽に体験してもらいたい
iOSアプリが完成したものの、友達(Windows PC利用)や家族(Android利用)に気軽に試してもらう方法を模索していた。
選択肢の検討:
- iOS TestFlight: 年間12,000円のApple Developer登録が必要
- Android版開発: 追加の開発・テスト工数
- PWA対応: 1つのコードベースでクロスプラットフォーム
コスト効率を考え、PWA対応を選択した。
技術的実装
Claude Codeとともに、以下の手順で進めた:
# Flutter Web環境の構築
$ flutter create --platforms web .
$ flutter build web --release
# Firebase Hosting環境の整備
$ firebase init hosting
$ firebase deploy --only hosting
一見順調に見えたが、ここから予想外の問題が連続で発生した。
直面した技術的課題
1. CanvasKitの互換性問題
Flutter Webでは、CanvasKitとHTMLレンダラーの2つの選択肢がある。デフォルトのCanvasKitで以下の問題が発生:
// Console Error
Intl.v8BreakIterator is deprecated. Please use Intl.Segmenter instead.
AFFECTED RESOURCES: main.dart.js:7042
対処法:
# HTMLレンダラーに変更
$ flutter build web --release --dart-define=FLUTTER_WEB_USE_SKIA=false
2. モバイルブラウザでの表示問題
PCブラウザでは正常に表示されるが、スマートフォンで以下の現象:
- 画面が真っ白
- ローディングスピナーのみ表示
- アプリ本体が全く起動しない
3. API制限の影響
Gemini API(無料枠:月間100万トークン、15RPM)の制限に達し、AI機能が停止:
// エラーハンドリングの追加
final challenges = await _challengeService
.generatePersonalizedChallenges()
.timeout(const Duration(seconds: 5))
.catchError((e) {
debugPrint('チャレンジ読み込みエラー: $e');
return _getDefaultChallenges(); // フォールバック処理
});
戦略的判断の瞬間
問題の本質を見極める
技術的な問題を次々に解決していく中で、重要な気づきがあった:
「技術的に可能」≠「戦略的に正しい」
PWAを動作させることは可能だが、以下の根本的な問題が存在した:
- 品質の妥協: ネイティブアプリの完璧な体験 vs Web版の制約
- 開発リソース: 限られた時間での優先順位
- ユーザー体験: 不完全なWeb版 vs 完璧なデモンストレーション
Claude Codeとの戦略セッション
この時、Claude Codeとの対話が決定的だった:
Claude: 「PWA対応の技術的課題は解決可能ですが、より大きな視点で考えてみませんか?友達・家族へのデモンストレーションが目的なら、画面共有という選択肢もあります。」
私: 「確かに...Web版にこだわる必要はないかもしれません。」
Claude: 「iOSネイティブの完璧な体験を維持し、開発リソースを既存機能の品質向上に集中する方が戦略的では?」
この対話により、明確な方針転換を決断した。
選択と集中の実践
決断:品質重視の戦略
採用した戦略:
- ✅ Web版開発を一旦停止
- ✅ iOSネイティブの完璧な体験を維持
- ✅ 友達・家族向けデモは画面共有で実施
- ✅ 開発リソースを既存機能の品質向上に集中
将来への投資:
- Firebase Web設定は完了(将来対応可能)
- エラーハンドリング機能は強化済み
- PWA対応の技術的知見は蓄積済み
コードベースの整理
戦略転換に伴い、不要な変更を整理:
# 不要なファイルを削除
$ rm -rf web/ lib/screens/*_simple.dart
# 有用な変更のみを保持
- Firebase Web設定(将来対応用)
- API制限時のフォールバック処理
- エラーハンドリング強化
Git履歴も3つのコミットに整理し、クリーンな状態を維持した。
学んだこと
1. 技術的制約との向き合い方
新しい技術への挑戦は価値があるが、制約を受け入れることも同様に重要。
- Flutter Webには固有の制約が存在
- すべての問題が技術的に解決可能とは限らない
- 制約の中で最適解を見つけることが重要
2. 戦略的判断力の重要性
「できること」と「すべきこと」は異なる
開発者は技術的な可能性に興奮しがちだが、以下を常に自問すべき:
- この技術選択は本当に価値を生むか?
- 限られたリソースの最適な使い道は何か?
- ユーザーにとって最も価値のある体験は何か?
3. AIパートナーとしてのClaude Code
Claude Codeの価値は、単なる実装支援を超えて戦略コンサルティングレベルに達している:
- 客観的な視点からの問題分析
- 複数の選択肢の提示と比較
- 感情的になりがちな技術選択の冷静な判断支援
今後の展望
短期計画(1-2週間)
- iOSアプリの品質向上に集中
- 友達・家族向け画面共有デモの実施
- フィードバック収集と分析
中期計画(1-3ヶ月)
- 焙煎音録音・分析機能の実装
- 豆の写真アップロード機能
- ユーザビリティの継続的改善
長期計画(6ヶ月以上)
- 技術環境改善後のPWA対応再検討
- 多言語対応
- IoTデバイス連携
おわりに
今回のPWA挑戦は、技術的には「失敗」に見えるかもしれない。しかし、得られた学びは計り知れない価値がある。
重要なのは「諦める」ことではなく、「適切なタイミングで方向転換する」こと。
開発において、すべての技術的可能性を追求することは不可能だ。限られたリソースの中で最大の価値を生み出すために、時には勇気を持って「選択と集中」を実践する必要がある。
Claude Codeとの協働により、感情的になりがちな技術選択を客観的に判断できたことが最大の収穫だった。AIパートナーは、技術的な実装支援だけでなく、戦略的な思考のサポートにおいても強力なツールとなり得る。
次回は、iOSアプリの品質向上と、実際のユーザーフィードバックについて詳しく報告する予定だ。
「選択と集中」により生まれる、より洗練された焙煎アプリの未来に、ぜひご期待いただきたい。
GitHub Repository: coffee-roasting-log-Google-AI-Studio
関連記事: