Flutter製AI日記アプリをApp Storeに出すまでにハマったこと

作ったもの

FlutterでAI日記アプリ「Lumina」を作った。

日記を書くとAIが振り返りメッセージを返してくれるアプリで、1週間前・1ヶ月前・1年前の記録も参照して、過去の自分とのつながりを感じられるようにした。

APIキーをアプリに入れてはいけない問題

最初はFlutterアプリから直接OpenAI APIを呼べばいいと思っていた。

でも、iOSアプリにAPIキーを埋め込むのは危険。アプリを解析されるとキーが漏れる可能性がある。

そこで、Cloudflare Workersを中継APIとして使う構成にした。

plain text
Flutterアプリ
  ↓
Cloudflare Workers
  ↓
OpenAI API

アプリ側にはOpenAIのAPIキーを持たせず、Worker側だけで管理する。

本番URLをどう渡すか

本番APIのURLはFlutterの --dart-define で渡すようにした。

bash
flutter build ipa --dart-define=API_ENDPOINT=https://your-worker.workers.dev

これで、アプリ内に直接URLを書き込まずに、ビルド時に本番用のエンドポイントを切り替えられる。

App Store Connectで詰まったこと

App Store Connectでは、コード以外の部分でかなり時間を使った。

特に詰まったのはこのあたり。

  • アプリ名がすでに使われていて登録できない
  • Bundle IDとApp Store Connect側の設定を合わせる必要がある
  • User Accessをどうするか迷う
  • TestFlightにアップロードしたビルドがすぐには使えない
  • ビルド番号を毎回上げないと再アップロードできない

アプリ名が重複している場合は、名前を変えるか、商標権があるならAppleに申請する必要がある。

Archive / IPA / Transporter の違い

ここもかなり混乱した。

ざっくり言うと、XcodeのArchiveはApp Store提出向けの完成品を作る作業で、TransporterはIPAをAppleにアップロードするためのツール。

Flutterでは以下のコマンドでIPAを作れる。

bash
flutter build ipa

ただ、iOSの署名やdSYMまわりで問題が出たときは、XcodeのArchiveからアップロードした方が安定することがある。

dSYM不足エラー

一番ハマったのがこれ。

App Store Connectで次のようなエラーが出た。

plain text
The archive did not include a dSYM for the objective_c.framework

dSYMはクラッシュログを解析するために必要なデバッグシンボル。

今回は objective_c.framework のdSYMがarchiveに含まれていなかったため、dsymutil で生成してarchiveに追加した。

bash
xcrun dsymutil path/to/objective_c.framework/objective_c \
  -o path/to/archive.xcarchive/dSYMs/objective_c.framework.dSYM

その後、archiveをアップロードし直したら通った。

AIの返答が薄くなる問題

AI日記アプリでは、AIの返答品質がかなり大事。

最初は「お疲れ様です」「素敵ですね」みたいな、どの入力にも使えそうな返答になりがちだった。

そこでプロンプトを調整して、以下を意識させた。

  • 今日の日記の具体的な内容に触れる
  • 感情の変化を拾う
  • 努力や価値観を言語化する
  • 1週間前・1ヶ月前・1年前の記録があれば自然に絡める
  • 汎用的な励ましだけで終わらせない

AIアプリは、モデルを呼ぶだけでは完成しない。プロンプト設計で体験の質がかなり変わる。

日付リセット時間の問題

日記アプリでは「いつ日付が切り替わるか」も重要だった。

普通に0時で日付を切り替えると、深夜に書いた日記が翌日扱いになってしまう。

そこで、ユーザーが任意の時間を指定して、その時間を境に日付を切り替えられるようにした。

たとえば朝5時に設定すると、深夜2時に書いた日記も前日分として扱える。

これは地味だけど、日記アプリとしてはかなり大事な機能だった。

学び

FlutterでAIアプリを作ってApp Storeに出すまでには、実装以外にもかなり多くの落とし穴があった。

特に大事だと感じたのはこの3つ。

  • APIキーはアプリに入れず、Cloudflare Workersなどで中継する
  • App Store提出では署名・Archive・dSYMまわりで詰まりやすい
  • AIの返答品質はプロンプト設計で大きく変わる

アプリを作るだけならFlutterでかなり速く進められる。

ただ、実際にApp Storeへ出すところまでやると、Apple側の作法や本番運用の設計まで含めて考える必要がある。