kumamotone’s blog

iOS/Android アプリエンジニアです https://twitter.com/kumamo_tone

デジタルデトックスチャレンジ 2025/03 版 経過報告

kumamotone.hatenadiary.jp

これ書いてから1週間経った。経過報告

Xの閲覧に関してはかなり改善した。家のWiFiではXを一切開けなくするというルールを追加しただけだが、個人的には効果てきめんだった。1日平均2時間以上削減できている。macで見る時間はカウントされていないが、体感増えている感じはない。(PCでは縦スワイプで動画を見る機能がなく、おすすめタブの非表示も比較的簡単にできるので、タイムラインを表示するだけだとそこまで無限に時間を使えない)

スマホゲームに関してもアンインストールしたままなので、こちらも使用時間ゼロ。まだ全然ではあるが、比較的クリエイティブな活動や個人の開発に多く充てられたと思う。また、運動に時間を割けたため、比較的気分的な不調は抑えられたんじゃないかと思う。

Digital Wellbeing アプリに比べると時間が不正確で小さめに出やすい気がするのだが、StayFreeで統計を取って見るのはモチベーションになる。Apple MacアプリとChrome拡張機能もある。アクセシビリティの権限を渡さないといけないのはやや心配な感じがするが、アメリカの大きめの企業だし基本的に匿名化して扱ってくれている感じはする。

本当にTrusted by Appleなのか

営業日はかなり生産的に過ごせたなという気持ちがある一方、休日の過ごし方は結構気をつけないといけないなと思う。大きめのストレスが掛かると何もかもやる気が無くなって自暴自棄になったりする(今週のTwitter視聴はほぼこのタイミングだった)ので、ここだけミスった感じがする。

これへの対策はなかなか難しく、なんか抽象的なアイデアしか思いつかないが、以下のようなところを今週は心がけてみたい。

  • ランチは極力控え、粗食で済ませる
  • 昼間に運動、長めの掃除などをしない(疲れて夕方に横になってしまうのを防ぐため)
  • (ストレスを避け自分のペースを保つことを心がける)

うーむ抽象的なプランしかないとやはり心配だ…。ともかく家でスマホでXを開かないは継続で!

OpenAPIのファイルをきれいに見たりモックサーバーを立てたりする

アプリから叩くサーバーのAPIがOpenAPIの形式で定義してくれていることがある。これはめちゃくちゃありがたい。openapi-generatorでクライアントコードを出力することもできるし、なにか問題があればSwagger UIやRedoclyで便利に閲覧したり、Prismでモックサーバーを立てて簡易的に試すこともできる。

できるのだが、毎回調べていて、なんかみんなもっと便利な方法でやってておれだけ不効率なことやってたらどうしようと思う。なんかそういうわけでもなさそうな実感が得られてきたので、雑にまとめる。ここらへん不満なく日常的ににこなしている方はとくに得られるものはないと思うのでブラウザバックいただいたほうがいいかもしれない。

Redocly で閲覧する

npm i -g @redocly/cli@latest
redocly preview-docs openapi.yaml

yamlファイルを与えてやるとローカルにサーバーが立ち上がってブラウザで見れるようになる。このとき、bundle.yamlのほうを渡してやると良い。個人的にここ数年?でよく聞くようになったツール。ローカルで見る場合も npm で簡単に入って、セットアップの手間も考えると一番ヘルシーかも。

ただあんまり慣れていなくて読みづらい。表示が急に右側とかに出たりするので、目が滑って情報を取りこぼすことが多く、あと余白もスカスカなのでSwaggerに比べてあんまり良いUIだとも正直思えない。なので個人的には後述のSwaggerを使いたい。

Swagger で閲覧する

VS Code拡張機能を入れる方法とdistというのを使ってブラウザで見る方法がある。

VSCode拡張機能を入れる

一緒に働いている方に教えてもらったのだが VSCode の拡張があるようで、これはとにかく拡張をインストールしてbundle.yamlを開くだけでOKなので、セットアップが簡単でよかった。

が、yamlを開いているリポジトリが分かれているため開きに行くのがやや億劫、cmd+Fで検索をかけたいときがあるが効かなかった(もしかすると拡張機能上でも使えるのかもしれないが、なぜか反応しなかった)ため、後述する手元でブラウザで見る方法も調べた。

ブラウザで閲覧する

個人的にはこの方法で見たいのだが、調べたところなぜか割と手間というか、回りくどい。

zenn.dev

上記の記事を参考に、swagger-ui-distというhtmlとjsなどがセットになったファイル群を、GitHubから入手するか、swagger-ui-distnpm install でできた node_modules 内のフォルダをまるっとコピーしてきて、bundle.yamlを同じフォルダに格納して、scriptのとこに以下を足す。この内容はindex.htmlか、そこでロードされているjsにある。

+   <script>
+     window.onload = () => {
+       window.ui = SwaggerUIBundle({
+         url: '../bundle.yml',
+         dom_id: '#swagger-ui',
+         presets: [
+           SwaggerUIBundle.presets.apis,
+           SwaggerUIStandalonePreset
+         ],
+         layout: "StandaloneLayout",
+       });
+     };
+   </script>

Prism でモックサーバーを立てて実装をたしかめる

APIのクライアントコードの妥当性を検証する必要がある場合はもはや少ないかもしれない。最近はDartのopenapi-generatorを使ってるケースも多い。一方で、古くからやってるプロジェクトには入っていないこともあるし、新しいプロジェクトでもopenapi-generatorがカバーしきれていない仕様のバグとかにあたって採用を見送ったりする場合があり、クライアントコードを手書きする機会もまだある。

最後まで手元で動作確認できればいいのだが、先んじてAPIクライアントの部分だけ準備したいという場合もある。その場合、実装がうまくいっているかどうかチェックする方法があい。生成AIのアシストがある程度あるとはいえ、自分の注意力でバグり散らかしたコードをコードレビューに出すのをできるだけ避けたく、実装をたしかめる方法が必要と感じた。

調べるとprismというツールがあるらしいので使ってみる。

npm install -g @stoplight/prism-cli
prism mock openapi.yaml --port 4010

上記でモックサーバーが立ち上がる。わかりやすい。 -v --trace をつけると細かくログを出してくれる。あと --dynamic オプションを付けると、OpenAPIの型定義に沿って毎回ランダムなダミーデータが生成されたり、--errorsでエラー返すようにしてくれたりもするらしいが、これは試せていない。

dart 側から叩くテストに関してはここは生成AIに書いてもらう。このAPIクライアントを使って192.168.1.100:4010にサーバーが立っているとして、あとなんでもいいのでBearerトークンをつけてください…みたいにお願いする。ためしにCopilot Editで出力したRetrofitやfreezedのクライアントやモデルコードをPrismを使ってチェックしてみたところ…全然間違っててワロタw いや生成AIが悪いみたいに言ってますけどわいの指示と目grepが悪いんすよね…

パスは間違えやすいところなのでこれでチェックできるのはありがたい。レスポンスのキー名や型に関しても、違う場合はモデルのパースに失敗するから気付ける。リクエストに関しては、デフォルトでoptionalなのは無視されるのと内容は(おそらく)見てくれないので、あんまり期待できない。グローバルで設定する方法はないが、スキーマに additionalProperties: false を足せばPrism が存在しないキーを含むリクエストを自動的に 400 等のバリデーションエラーとして返すようになるので、キー名についてはこれで気づけそうだが、これはめんどくさい…。

生成AIさんには、あとでbaseUrlに一括で/v1ってつけるのでクライアントに/v1つけるのはやめてください、みたいな話だとか、snake_caseからcamelCaseへの変換はグローバルに設定が定義されているから不要ですみたいな話だとか、伝えているはずなんだけど、意外と難しいようですな…まああっしの仕事がわずかながら残ってたようで良かったですわ…

総括

生成AIでのコード生成でRetrofitやfreezedのクライアントやモデルコードを一発で出すのは意外とまだ難しい。open-api-generatorなどを使うのがやはり一番良いと思うが、ポリモーフィズムの機能(oneOf, anyOf, allOf)のサポートがまだ完全に行われておらず、まだissueがOpenになっている。たとえばひとつのフィードで色々な型のオブジェクトが流れてくるみたいなのをスキーマ定義したいときに、この機能はぴったりなわけなのだが、少なくともDartだと問題のあるコードが生成される。 freezedを使えばUnionで実装することができる。

techblog.zozo.com

個人的に精査できているわけではないが、ワークアラウンドとしては上記の記事にあるようなところを守ればopen-api-generatorに合わせることができそう。「open」がプログラミング言語予約語と被っていてうまくいかない、みたいなところもハマりどころだと思う。

AI Blindspots を(o1 proで)翻訳して読んだ

LLMのコーディング時の盲点を集めたサイト「AI Blindspots」 がSlackで流れてきて良さそうな雰囲気だったので読んでみた。

ezyang.github.io

Hugo という静的サイトジェネレーター で書かれていてシンプルな見た目で好感が持てる。 Hugo ʕ•ᴥ•ʔ Bear Blog というテーマらしい。かわいい。

日本では少し前にXでちょいバズし、はてブもついているようだった。

調べてみると、存じ上げなかったのだが著者は Edward Z. Yang (https://x.com/ezyang)さんという Meta社の研究者の方のようだった。

翻訳

Hugo のソースは GitHub にあったので、 fork させていただいて翻訳させていただいた。といっても、翻訳そのものo1 Proにまるっとおまかせしている。

github.com

原文のニュアンスがどのくらい拾えているかわからないが、かなり読みやすい。

やり方

文章はMarkdown形式で記事ごとにわかれているので、一旦ひとつの大きなファイルに結合する。

for f in content/blog/*.md
do
  echo -e "\n[[[$f]]]\n"
  cat "$f"
done > combined.md

fishだと

for f in content/blog/*.md
    echo
    echo "[[[$f]]]"
    echo
    cat "$f"
end > combined.md

このとき、頭に[ファイル名]\nを挿入しておいて識別子にする。

指示は「以下のmarkdownファイルを日本語にしてください。」だけでOK

何故全文を一気に投げるのかというと、個別にやるのがめんどくさいというのもあるが、何よりある程度長めの文章のほうが何についての文章なのかがAIに伝わりやすくなり、それで精度が上がりそうな予感がするから。コピペして combined_ja.md とか名前をつけ、もとに戻す。

#!/usr/bin/env zsh

# 出力先のファイルを保持する変数
outfile=""

# combined.md を行単位で読み込む
#   - IFS= で空行もそのまま取り込む
#   - read -r でバックスラッシュ等をエスケープ解釈しない
while IFS= read -r line; do

  # 区切り行かどうかを判定:
  #   1. 最低6文字以上あるか (例: [[[ ]]] → 6文字)
  #   2. 先頭3文字が '[[['
  #   3. 末尾3文字が ']]]'
  if [[ ${#line} -ge 6 && ${line:0:3} == '[[[' && ${line: -3} == ']]]' ]]; then
    # 先頭の [[[ と 末尾の ]]] を取り除いてファイル名を抽出

    # 方法1: 文字列切り取り(サブスクリプト)
    #   newfile="${line:3:${#line}-6}"
    #
    # 方法2: パターンマッチによる除去(こちらのほうがわかりやすいかも)
    newfile="${line#\[\[\[}"    # 先頭 '[[[' を削除
    newfile="${newfile%\]\]\]}" # 末尾 ']]]' を削除

    # ディレクトリが存在しなければ作成
    mkdir -p "${newfile:h}"

    # 以降の本文をこのファイルへ書き込む
    outfile="$newfile"

    # この行自体は本文としては出力しない
    continue
  fi

  # 区切り行でなければ、outfile が設定されている場合に追記
  if [[ -n "$outfile" ]]; then
    # 先頭がハイフンでもオプション解釈されないよう、print -- を使う
    print -- "$line" >> "$outfile"
  fi

done < combined_ja.md

雑に GitHub に push して Netlifyから開いてビルドしてなんかエラー出てるからそのままChatGPTに貼り付けて…

[build]
   command = "hugo"
   publish = "public"
 
 [build.environment]
   HUGO_VERSION = "0.110.0"      # 必要なバージョンを指定
   HUGO_EXTENDED = "true"        # SCSS/SASSなどを使う場合

出てきた netlify.toml ってファイルをルートディレクトリに入れたらデプロイできた。おそろし〜

AI Blindspotsの感想

さて肝心?の AI Blindspots の内容の感想だが、ほとんどまあそうですよねという感じで感じであんまり驚きはなかった。

ただ短くて読みやすく、例がマイページ書いてあって読み物としてやさしかった。

意外とAIは自分の限界がわからんくてハルシネーションを起こす(限界を知ろう)、コンテキストが大事(メメント)、一度に色々言わんほうがいい(掘り進めるのをやめよう)

「ファイルを小さく保つ」に関しては、個人的な体験からするとあんまり同意できない。同じディレクトリに入ってるから当然読みに行ってくれるだろみたいな思い込みは意外と通用せず、結局最初から全部読んでもらったほうがはやいということが多い。わざわざ無関係な記述をすべて同じファイルにする必要はないと思うが、何千行みたいな規模でない限り、画面と関連するモデルみたいなものは1ファイルに出してもらったほうが今のところは安定する気がしている。コンテキストが多い分には適宜無視してもらえるが、ないと本当にわけのわからん動きをしはじめる。ただ与えすぎるとコンテキストを圧迫するので、これはトレードオフをうまく見極めるしか無いと思う。

一方で、コードが横に長いと出力に時間がかかるので、関数分けやコンポーネント分けをして部品を小さく保つことは非常に重要と感じる。

また、E2Eですべてのパーツを含む、最小限の動く仕組みをまず作り上げる、というプラクティス(ウォーキングスケルトン)や、時に「人間離れした」成果を出すには、ただ座ってブルドーザーのように総当たり作業をし、そこから学んだことを活用して速度を上げる、というアプローチが有効という話(ブルドーザー方式)は、たしかに、今からの時代ますます重要になるだろうなと思った。

おわり

あんまり驚きはなかったみたいなことを書いたが、これだけ端的に考えがまとまっているというのがシンプルにすごい。こういう文章を自分も書きたい。一方でこのブログは何だ 支離滅裂すぎる 練習しましょうね

デジタルデトックスチャレンジ 2025/03 版

最近3週間の自分のスマホでのXアプリの使用時間です。週平均20時間、4時間を超えてる日が6回あります。別に今月が特別多いというわけでもなく、年中こんな感じです。

X見ること自体はそこまで悪いことだと思っていないのですが、おすすめタブ、とくにおすすめタブの動画を縦スワイプで閲覧できるのがよくないと思っています。

やらなきゃいけないことがあるけど、逃避→時間が経つ→焦燥感と疲労感→以下無限ループ…になります。

あと広告のゲーム(パズルを解いて極寒の地で震える母娘を助けるゲーム、兵士を左右に動かして数を増やしてゾンビを倒すゲーム、ホテルを経営をして広告を見ながら金を稼ぐ謎のゲームなど)も複数入っています。広告のゲームは、だいたいログインボーナスみたいなのを取り切ったり、ライフや時間を経過させてから再ログインすることによってインセンティブがあることが多いので、意外と1日に何時間もできるような感じになっておらず、意外と有害度は高くないと感じました。のでなんか病院で寝たきりとかになったらこういうのやるのが一番気が紛れていいんじゃないかと思いました。それでもかなり無為なことには違いないので、しばらくやめたいと思いました。

第N次デジタルデトックスチャレンジ開始です。

前回までの失敗

  • デジタルウェルビーイングアプリでアプリタイマーを設定する
    • アプリ自体は起動できるし、簡単に解除できるのでまったく意味がない。

→起点をできるだけ封じる。解除がモーダルで行えるような方法は取らない

  • アプリを削除して、Kiwi BrowserにControl Panel for Twitterを入れておすすめタブを見れなくする
    • YouTube はこの方法(アプリを消してControl Panel拡張を入れる)で縦動画を見る時間をほぼ無くすことができた
    • しかし、写真を投稿するときなど、必要に感じるタイミングもある(このタイミングでアプリがインストールされてしまい、習慣化が終わる)
    • しかもTwitterDMは普通に必要な連絡も来たりすることがあるので、気がついたらめちゃくちゃ時間が経っていて気まずい思いをすることがある

→アプリを消すのは今回は諦める ただし家では開かないように工夫する

  • そもそも、縦スワイプや広告ゲームに走ってしまうのは生活のストレス値が高すぎるからという可能性も高いので、ストレスケアの方法も

→ストレス値を軽減する工夫をする

やること

  • AppBlock の「家のWi-FiではスマホXを開けなくするルール」を設定し、厳格に守る
    • 見たいときは、PCで見る
      • PCでも時間の浪費にはなってしまうがおすすめタブを殺せるので遥かにマシ
    • 家では写真が投稿できなくなるが、諦める(どうしてもGoogleフォト経由でアップロードされた画像をPCから投稿する)
  • 広告のゲームについては、アンインストールする
    • これはなんというかただの自傷行為なので別に一回消してしまえば自力で我慢できる気がするし、しばらくやらなかったらやる気がなくなると思う
  • リングフィットアドベンチャーとFit Boxingをやる
    • 筋トレと有酸素運動を両方を行うことでドーパミンをマイルドに出して中毒症状を和らげる
    • ヨガ、ストレッチパートでマインドフルネス的な動きが入ることも期待する

一応以下のアプリも導入してみます

  • minimalist phone
    • 待受を真っ黒にして時計と文字のランチャーだけにするアプリ
    • ウィジェットが置けなくなるのはキツい カレンダーとFitbitだけは見たい
    • 買い切りがあるが高い
  • StayFree
    • 課金しなくても使用時間の統計を見ることができる
    • MacアプリやChrome拡張もあるので普段遣いするほぼすべてのデバイスでアプリの使用時間をトラックできる

一応こうなったら成功という基準

  • 3月24日〜3月30日において
    • (自分でやむを得ないと思った場合を除いて)家でスマホでXを開いた回数が3回未満
    • Xの使用時間が1日平均1時間以上減少
    • Xの使用時間が4時間を超えてる日が2回未満

うまくいけば1日1時間以上は浮くはずなので、代わりに何かが生活に入ってくることを期待します。もしまた気が向いたら書きます。

CA.flutter #3 に参加しました

cyberagent.connpass.com

本日はサイバーエージェントさんのFlutterエンジニアによる勉強会、 CA.flutter #3 に参加しました!会場はサイバーエージェントさんのアベマタワーズでした。

オンラインでの配信もされていて、YouTube Live で配信内容が見れるようになっているのも毎回とてもありがたいです…!(巻き戻しもできたのでブログまとめたい勢としては聞き逃した部分を確認できるのでめちゃくちゃありがたい……!)

www.youtube.com

現地の音響とかも聞きやすかったり、さすがの運営(何の観点?)の手腕も感じました。質問は sli.do でリアルタイムに匿名で受け付けられていたのもとても親切な設計だと感じました!

以下発表内容になります!

custom_lintで始めるチームルール管理

WINTICKET で運用されている custom_lint

WINTICKET で運用されている custom_lint は、12個の独自ルールをもつ社内パッケージに加えて、外部lintパッケージが2個ある。

lint がほしくなるとき、それは3パターンぐらいある。

1. よくレビューで指摘がある

  • StatelessWidget で十分な HookWidget について、StatelessWidgetで十分ですよみたいなレビューが飛ぶことがある
  • flutter_hooks_lint というパッケージに hooks_unuse_widget というルールがあり、これを使うと lint することができる

pub.dev

前一緒に開発していた先輩が作っていたやつなので勝手に小躍り

2. チームルール

  • force_unwrap して意図せずエラーが頻発しているWidgetがあり、コード全体でforce_unwrapを基本的に禁止しようという流れになった
    • avoid_force_unwrap というcustom_lint を作って解決した

3. レビューでも気づきにくいミス

  • テストのファイルは_testの接尾辞をつけてほしい 接尾辞がついていない場合、実行されない場合がある
    • avoid_non_suffix_test_file_name というlintを作って、_testがついていることを保障するようにした

custom_lint のつらいところ

lint を入れると生産性が良くなるというところに異論がある人は少ないと思うが、デメリット的なところもある。

1. 最初にいれるときは大変

  • ignore をちょっとずつ外していって対応
  • fix コマンドを使って一括適用して負担を軽減

2. lint 自体に計算機的な実行コストがかかる(3GBとか使っていることがある)

  • ご利用は計画的に

新しい "analyzer" がもっとLintをよくしてくれるかも

custom_lint が公式にリプレイスされるという噂。IssueにNew analyzer system というのがある。

これはcustom_lint 相当の機能が盛り込まれている予定で、lintが重いなどの問題も軽減されていく可能性もある。

GitHub Codespacesで実現するブラウザ上でのFlutter開発

GitHub Codespacesは GitHubが提供しているVSCodeベースのクラウドベースの開発環境。最低スペックの2コアだと60時間まで無料。

github.dev との違い

. キー を押してブラウザで開けるgithub.devだが、こちらはコンソールがないのでコマンドが実行できなかったり、lintやformat、ビルドができない

Dev Container の設定方法

Extensions とかも指定できる。ここでClineとかも指定できる

デモ

lint や formatも効くし、Copilot が効く。かなりローカルに近い感覚で使える。 Clineも使える。

Flutter 開発という観点から

今のところ制約があり、実機と繋いでみたいな開発は難しそう

flutter run -d web-server すれば画面上で動作確認はできる。 Hot Reload は使えないが、ターミナル上でリロードなどは可能。

コラム: そのうちWidget Preview 機能というのがFlutter Webで動くようになるようなので、それに期待

タブレット端末やスマホで試してみた

できないことはないが、画面が小さいので普通に厳しい 色々工夫するとminimapとか消したりとかエディタの要素を消したりはできるので、そうすれば最低限編集できるようにはなりそう

AIコードエディタの基盤となるLLMのFlutter性能評価

  • LLMのFlutter性能を評価したい!
    • 何故?→Dart/Flutterでもっと便利にLLMを使いたいから(意訳)。モデルの評価プロセスを理解すると、より効果的な改善が可能になるから
    • アカデミアでデータセット作成を進めてくれる気配はないので我々でやるしかない 自分で作りたいが、色々な経験者から意見を募りたい
    • 評価をちゃんとやると本当に使えるのか、現状できないことは何なのか明らかにできる

LLM の概要については緑本を読むのがおすすめ

https://www.amazon.co.jp/%E5%A4%A7%E8%A6%8F%E6%A8%A1%E8%A8%80%E8%AA%9E%E3%83%A2%E3%83%87%E3%83%AB%E5%85%A5%E9%96%80-%E5%B1%B1%E7%94%B0-%E8%82%B2%E7%9F%A2/dp/4297136333

評価プロセスは以下のように定義できる。

  • タスクを定義する
  • 評価指標を定める
    • 人手での評価と自動評価がある
    • 自動評価には BLEU, LLM-as-a-judge などがある
  • データセットの作成
    • これも手動と自動に分けられる
    • データセットには分量や多様性などが求められる
  • モデルの出力を分析する

Flutter においてはどうなるか?

以下のようなタスクを定義できそう。

  • UI実装・修正
  • Riverpod を用いたロジックの実装・修正
  • Widgetテスト・E2Eテストの実装・修正
  • アーキテクチャ
  • ネイティブコードからDartへの変換

単純にはビルドが通るか、テストが通るかみたいな観点で評価ができる。

データセットの候補に関してはGitHubのpublic repoやpackageのonboardingなどを参考にするのがいいのではないかと思っている。クリティカルなものが思いつかなかったので広く意見を募りたい。

おわりに

これまでCA.flutterは3回とも参加させていただきましたが、いつもどの登壇者も「ちょっと使ってみた」というレベルではなくしっかりとした深堀りをされていて、勉強会参加の意義を感じられる良質な会だと感じています。また開催があれば参加したいと思っています!

Summer Pockets(サマポケ)のAndroid版のデータ引き継ぎ方法

いい歳した人間が黙々と美少女ゲームのセーブデータのバックアップをしているというのがキツいのでやや恥ずかしいのですが、おそらくGoogleバックアップに対応しておらず、調べても全然情報がなかったのでここに書き残しておきます。

AndroidAndroidに引き継ぐ場合の想定です。(私はPixel 6からPixel 9 Proに引き継ぎしました)

古い端末からの抽出

古い端末を繋ぎます。

/sdcard/Android/data/ を grep するとそれっぽいフォルダがありました。

adb shell ls /sdcard/Android/data/jp.co.product.kn.summerpockets/files/

ローカルに抽出します。このフォルダごと軽い気持ちでpullしたら6.9GB もあったので、セーブデータっぽいフォルダだけ持ってきます。

mkdir old
adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets ./old/___SAVEDATA_SummerPockets
adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_EX/ ./old/___SAVEDATA_SummerPockets_EX
adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_rb/ ./old/___SAVEDATA_SummerPockets_rb

rbはわかるがEXってなんだ?

新しい端末へ転送

新しい端末をつなぎます。購入状態の復元とデータのダウンロードはおわっている状態。念のためアプリは閉じておいたほうがいいかもしれません。それっぽいフォルダがこちらにもあることを確認。

adb shell ls /sdcard/Android/data/jp.co.product.kn.summerpockets/files/

なんかさっきと微妙に表示が違うな

そのままpushしてもいいのですがこちらも念のためバックアップを取っておきます。

adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets ./new/___SAVEDATA_SummerPockets
adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_EX/ ./new/___SAVEDATA_SummerPockets_EX
adb pull /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_rb/ ./new/___SAVEDATA_SummerPockets_rb
adb shell rm -r /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets
adb shell rm -r /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_EX
adb shell rm -r /sdcard/Android/data/jp.co.product.kn.summerpockets/files/___SAVEDATA_SummerPockets_rb

ls して消えていることを確認

adb shell ls /sdcard/Android/data/jp.co.product.kn.summerpockets/files/

転送!

adb push ./old/___SAVEDATA_SummerPockets /sdcard/Android/data/jp.co.product.kn.summerpockets/files/
adb push ./old/___SAVEDATA_SummerPockets_EX /sdcard/Android/data/jp.co.product.kn.summerpockets/files/
adb push ./old/___SAVEDATA_SummerPockets_rb /sdcard/Android/data/jp.co.product.kn.summerpockets/files/

確認

アプリが起動しっぱなしになっていたのでちょっと焦ったのですが、再起動したらデータがセーブデータが読める状態になっていました。

サマポケ最高

サマポケAndroid版は硬派すぎるUIで最初面食らったもののアプリの質は全体的に読みやすくよかったので、データの引き継ぎがこのような方法を取らないとできなさそうというのは残念…まあiPhoneならそのまま引き継げそうなので残念なのはAndroid OSのほうか…まあでもなんとかなるところにデータを保存しておいてくれていて助かりました。

エラー文読むのがずっと苦手だった

エラー文読むのがずっと苦手だった。

たとえばユニットテスト書いてて、

type 'Null' is not a subtype of type 'Future<T>' :test/hoge_test.dart 30:7

ってエラー文に遭遇したとき、まず「英語でそんなワーワー言わないで!😖」と思考が放棄され、でもググったりガチャガチャしても一向にどうにもなる気配がないので観念して冷静に直訳すると、 Dartくん「Null は Future型のサブタイプではありません🤓」なんだけど、 マジでなんで急にサブタイプの話してるの?ってか仮にそうだとしても、その言い方はなくない?😠みたいな感じになる

実際にこのとき読み取るべきメッセージは

  • Future<T> が返されるべきとこ実際実行したら Null だったよ」
  • 「だから Future<T> を返すように修正してね」
  • 「あっでも Future<T> じゃなくても Future<T> っぽいやつだったらOKだから!」
  • 「大丈夫だから一緒に頑張ろうねっ🤗」

みたいな感じである

自分はこういう理系的な行間を読むのがめちゃくちゃ苦手で(だから大学とかで買わされる、背表紙が謎に固くてページ数は全然ないのにめちゃくちゃ高くて「◯◯は自明」「解答略」とか書いてある数学の本とかが読めない)、マジで素質がね〜〜って長年なってたんだけど、最近はChatGPTに投げればこのあたり何が言いたいのか補間してくれて、人間のフリをできる時間が増えた(今までもググればこのあたりを補間してくれる記事はあるにはあった)

これによってエラーで長時間悩んで、勇気を出して人に見せたら「エラー文ちゃんと読みました?w(ちくちく言葉)」とか言われ、おれは己の才能の無さに傷つき、向こうは向こうで「普通にちょっと考えたら分かることを質問しにくるってわしナメられとんのかな?」みたいになる全員が悲しいだけの時間がかなり発生しにくくなって、全体的に良い感じです サンキューAIくん