
FlutterFlowで作ったアプリの画面を、FlutterFlowのエディタを開かずにClaude Codeから直す——アプリの構造を記述したDSL(Dartのコード)を編集し、テストを通し、CLIでFlutterFlowに反映し、iOSシミュレーターで撮影して確かめる、という流れで、自社アプリ「あとだしジャンケン」の4画面に散らばっていた2個のボタンの位置を1つの共通部品にそろえました。この記事ではその手順と、「反映が1画面にしか届いていなかった」罠を含むハマりどころを紹介します。
背景: 画面ごとにボタンの位置がずれていた
このアプリには、タイトル・あそびかた・結果・中断中の4つの画面に、それぞれ「主ボタン(黄色)+副ボタン(枠線)」の2個組があります。画面ごとに別々に置いていたため、ボタンの高さが上下にずれ、中断中の画面だけ横幅240で中央に寄った狭い見た目になっていました。細かい話ですが、遊ぶたびに目に入る部分なので、バージョン1.0.1で直すことにしました。
FlutterFlowは本来、ブラウザのエディタで部品を並べて作るノーコードのツールです。ただ、FlutterFlow AIのDSLワークスペースを使うと、ページの構成をdsl/edit.dartというDartのコードで記述し、CLIからプロジェクトに反映できます。コードになっていれば、Claude Codeが読んで直せます。私が画面で部品を1つずつ動かす代わりに、AIに「4画面のボタンを同じ位置に固定して」と頼める、ということです。
実装: 共通部品を1つ作り、4画面に差す
やったことは単純で、2個のボタンを縦に並べる部品を1つ作り、4画面すべてからそれを使うようにしました。寸法は、黄色の主ボタンが高さ56、枠線の副ボタンが48、間隔12、左右の余白24、下の余白24です。
DslWidget _bottomButtons(String name,
{required String primary,
required String primaryName,
required Object primaryTap,
required String secondary,
required String secondaryName,
required Object secondaryTap,
Object? visible}) =>
Column(
name: name,
visible: visible,
crossAxis: CrossAxis.stretch,
spacing: 12,
padding: EdgeInsets.only(left: 24, right: 24, top: 12, bottom: 24),
children: [
_pixelButton(primary, primaryName,
filled: true, height: 56, onTap: primaryTap),
_pixelButton(secondary, secondaryName,
filled: false, height: 48, onTap: secondaryTap),
],
);
結果画面とあそびかた画面は中身だけがスクロールし、ボタンは常に一番下に固定されるようにしました。ゲーム中の「中断中」は、回答用のボタン列を隠して、同じ場所にこの共通部品を表示します。
同時に、あそびかたのルール3行の先頭を「・」から①②③に変え、文字を14にして2行目が1行に収まるようにしました。ここで小さな工夫が要りました。DSLのTextには文字サイズを直接指定する引数がなく、テーマのスタイルから選ぶ形です。ところがテーマに14のスタイルがなかったので、使っていなかったbodySmallを14に設定して使いました。
// bodySmall を 14 にする (あそびかたのルール 3 行専用。ドット文字のまま)
app.typography('bodySmall', fontFamily: _bundledDotFont, fontSize: 14);
テーマの設定として持たせておけば、後述する「毎回の置き換え」でも消えません。
流れ: 編集→テスト→反映→シミュレーターで確認
修正のたびに回した手順は次のとおりです。
flutterflow ai test # DSLのテスト(このプロジェクトでは36件)
flutterflow ai run dsl/edit.dart --project-id <プロジェクトID> --commit-message "v1.0.1 #34 #31"
scripts/sim-build.sh --launch # 生成コードをビルドしてiOSシミュレーターで起動
テストが36件すべて通ることを確認してからrunでFlutterFlowに反映し、シミュレーターで4画面に加えて「通常のゲーム中」「カード付きの結果画面」を撮影して、ボタンの位置が同じ高さにそろっていることを目で確かめました。確認が済んだらリポジトリにコミットします。FlutterFlowのエディタ側で私がバージョン番号を1.0.1(ビルド3)に上げたときは、refresh-contextで手元に取り込んでから次の修正に入りました。
ハマりポイント
- 反映で置き換わるのが結果画面だけだった: 一番の罠です。DSLの編集フローが、結果画面を置き換える段しか呼んでいませんでした。そのためタイトル・あそびかた・ゲーム画面のDSLを直しても、FlutterFlowには届いていなかったのです。4画面をまとめて置き換える既存の段を、フローの最後の段から呼ぶように直して解決しました。以後は反映のたびに、生成コードに変更が入ったかを
grepで確かめることにしています。「runが成功した」と「変更が届いた」は別物でした。 - 部分修正の近道はCLIから使えない: 1つの部品だけを直す「ファストレーン」はMCP専用で、CLIからは使えません。文字サイズのように引数で指定できない値は、未使用のテーマスタイルを目的の値にして使うのが、置き換えでも消えず確実でした。
- 設定値の形式が厳密: 最低iOSバージョンを
app.rawで設定したとき、15.0は「3つの数字でない」と拒否され、15.0.0で通りました。生成コードのPodfileとXcodeの設定が15.0.0になったことまで確認しています。 - 書き出しのたびにフォントが消える: コードを書き出す(refresh / run)たびに、同梱したフォントファイルが生成コードから消え、シミュレーターのビルドが落ちます。フォントのコピーからビルド・起動までを1コマンドにするスクリプトを置いて回避しました(ストア版はFlutterFlow側でビルドするので影響しません)。
- debugビルドは起動直後が黒い: 数秒は黒い画面のままなので、待ってから操作します。撮影を自動化するなら待ち時間が要ります。
まとめ
ノーコードのツールで作ったアプリでも、構造がコードとして取り出せれば、AIエージェントに「直して、テストして、反映して、確認して」まで任せられます。ただし、反映が本当に届いたかをAI自身に確かめさせる(生成コードのgrep、シミュレーターでの撮影)工程を入れておかないと、「成功した」という報告だけが残ります。4画面のボタンをそろえる小さな修正が、その確認工程を作るきっかけになりました。
なお、このアプリをストアに出すときに踏んだ罠は、FlutterFlowのワンクリック配信で両ストアに出すときの落とし穴にまとめています。
FlutterFlowを使ったアプリ開発や、AIエージェントを組み込んだ開発体制のご相談は、お問い合わせフォームからどうぞ。
← TECH-BLOG一覧へ