eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

ついにGSuiteの無料版がシャットダウンされるので移行した

GSuite無料版

  • @gmail.com ではなく、独自ドメインのGSuiteが条件付きで無料で使えていた
    • 10年ほど前まで(いまほどGSuiteが普及してない時期)は、無料で10アカウントまで独自ドメインのGSuiteを利用することができた
  • 5年前時点ではもう無料では作れず、有料プランのみに切り替わってた
    • 普及したんだね!

2022/5月にシャットダウン

  • 無料登録したGSuiteアカウントは2022年2月現在まだ無料で使える
  • ただし、無料提供が5月で終了すると発表された(5月までに切り替えが必要で、その後7月までは無料で使える)

さよなら開発アカウント

  • 開発専用を含めて、4つのアカウントを運用していた
    • これだと毎月2500円以上
    • ネトフリの4Kプランよりも高い
  • Admin用と副業用の2アカウントを残し、アカウントを削除
    • これで毎月1300円

無料はいつか終わる

  • あいつも有料化する
  • こいつも有料化する
  • けど、今日じゃない

と思い続けて10年、ついに有料化のビッグウェーブにのまれたという話

Kotlin 1.6に変更してproguardをかけたら通信周りが死んだので直した

事象

  • アプリにログインできない

調査

  • APIcurlすると、正常に動作する(サーバーは正常動作してる)
  • Debugビルドで実行すると、正常に動作する(プログラム自体は正常である)
  • サーバーのログを確認すると、送信値のValidationに失敗している

Releaseビルドでの動作

  • APIRetrofit2 を経由でコールしている
  • JSON変換は moshi を利用している
  • このどちらかに問題が発生した可能性が高い

APIサーバーにどんな値が送られているのか

  • 送信値の直接的なログはない
    • 値のValidationに失敗した、という情報しか出してない
  • まずは手元のアプリでどんな値が実際に送信されているかLogcat

github.com

  • 結果として、snake_caseとして送信しなければならない値がcamelCaseとしてJSON化されていることがわかった
    • moshiには @Json("user_name") のようにAnnotationを付与しているので、Annotationが殺されているのがわかった
data class ExampleLogin(
   @Json("user_name")
   val userName,
)
  • 器用にsnake_caseがcamelCase化処理されるとは考えにくいので、おそらくdata classのプロパティ名がそのまま使われているのだろうと予想する

proguardルールを変更した

  • どうやってもダメ
  • 全部のclassやinterfaceをkeepしてもAnnotationが剥がれてしまう

Annotationを付け替えた

  • filedに付与すると、proguardを通してもAnnotationが生きている
  • なんとなくだが、Proguardの最適化によってField/Methodの扱いが変わってしまったように思う
  • ただし、このままだとProguard前のデバッグで不正になる
data class ExampleLogin(
   @JvmField
   @field:Json("user_name")
   val userName,
)

Annotationをさらにつけた

  • モリモリ全部盛りで、FieldとMethodに付与した。
  • これでDebugもReleaseもOK
  • 変換用Classは全部Generatorが吐き出しているので、テンプレートだけ対応してあげてヨシ.
data class ExampleLogin(
   @JvmField
   @field:Json("user_name")
   @Json("user_name")
   val userName,
)

Kotlin 1.6はなかなか色々大変だったが、これでひと段落のはず

Flutter iOSでファイルの書き込みが静かに失敗する不具合の対応

flutter doctor

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.3, on macOS 12.0.1 21A559 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] Android Studio (version 2020.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.2.3)
[✓] VS Code (version 1.62.3)
[✓] Connected device (2 available)

発生した事象

iOSのアプリCacheディレクトリにファイルを書き込むと、低確率でファイル書き込みが静かに失敗する。

file.writeAsBytes( binary, flush: true);

Consoleログ出力にはエラーはなく、例外が発生しない。 書き込みは失敗するため、書き込んでもファイルが存在しない(File.existsがfalseとなる)し、appendモードの場合はファイル長(File.length())が想定よりも短くなる。

Issue

おそらくこれ

github.com

対応

たまに静かにランダムに失敗するので、成功が確定するまで書き込み続ける。

ログファイルのように次々appendするようなパターンでは二重書き込みが怖いけど、今回の自分のユースケースでは書き込みをリトライすることでワークアラウンドした。

その他

正しい対応の仕方があれば教えてほしい(マジで困る)

AndroidアプリのKotlin 1.4/1.5から1.6へのマイグレーション

AndroidX Roomのコンパイラが不正なJavaクラスを吐き出す

  • Entity(だいたいdata class)に複数のコンストラクタがある場合(Entityをnewする際のサポートのために作ったコンストラクタ)、Kotlin 1.6からRoom Compilerが不正なコードを吐き出すようになった
  • RoomのR/Wに使われないコンストラクタに @Ignore アノテーションをつければ良い
    • メッセージからして、多分1.4までが不正な状態で、1.6で想定通りに機能するようになったと思われる

String.toLowerCase(Locale)が非推奨になった

  • ガイドに従って String.lowercase(Locale) に書き換えれば良い

when分岐でに足りない候補がある場合に(seled classとか)警告が出るようになった

  • elseブロックを追加する
  • 丁寧にやるなら、全部の候補を列挙した方が将来自分が困らなくていいかもしれない(意図しないwhen分岐漏れを防ぐための警告なので)

Channel.offerがtrySendに変更された

  • 戻り値がObjectになり、詳細な結果が取れるようになった

Koinが内部で参照しているClassが消された

  • Time/Duration系の参照が一部変更されたらしい
  • KoinのLoggerレベルを下げてワークアラウンド
  • 追記: Square Wireライブラリ(Proto3のSquare実装)も同じくtime.Instantに関わる問題でクラッシュする
    • 3.7.1では対応済なのでバージョン更新

stackoverflow.com

改善策

  • Android Desugaringライブラリが古いとProguardかけた場合だけ問題が発生する場合がある
  • 1.1.5に更新したら治った

developer.android.com

M1 Max Macbook Pro(14inch)の所感

購入したスペック

  • M1 Max
  • 10 CPU
  • 32 GPU
  • 64GB RAM
  • 512GB SSD

環境構築で躓いたところ

Android SDKAndroid Studioからインストールも認識もできない

  • なにかに引っかかってエラーらしい
  • IntellijAndroid Pluginに付属しているGUIでインストールするとAndroid Studioからも認識される
    • Apple Silicon環境ではemulatorコマンドが消されているので、Android Studioインストーラーがコケる
    • emulatorだけcanaryチャンネル(--channel=3)で手動でインストールすると以後正常動作する

javacがクラッシュする

  • JDK9から付属しなくなったいつものjavax
  • ごちゃごちゃやってるうちに治った

Android Emulatorが起動しない

  • Android StudioのAVD Managerで作成すると常に失敗する
  • コマンドラインで作成すると成功する
  • stableチャンネルに"emulator"がない(Apple Siliconだけ?)ようなので、canaryから取り寄せる
sdkmanager --channel=3 emulator
avdmanager create avd -n instrumentation -k "system-images;android-31;google_apis_playstore;arm64-v8a" -d "Nexus 9"

Flutterアプリビルド速度

  • VSCodeからdebugビルドが30秒〜15秒 -> 9秒〜10秒に短縮

Androidアプリビルド

  • Gradleコマンドでフルビルド75秒 -> 65秒に短縮

費用対効果

  • ビルド速度だけを見たら、40万円出すのは微妙と思うかも
  • 何やってもほぼファンはまわらず、静かに作業できる
    • 全部のUnit Testを並列実行させたらファンが回ったので、ファンは壊れてなさそう
  • 作業中も概ねキビキビ動いてくれる
    • 総合的な快適性はかなり上がった
    • iOSアプリ開発しないのであれば、40万円でデスクトップ構築したほうが安い
  • 逆に言えば、40万円払って出先でもデスクトップ(より多少劣るが)並のスペックを手に入れたと思えばまあ良いかも
  • アップグレード先としてはアリ、高性能なMacを必要とせず既にデスクトップで強力な母艦があるなら微妙
    • けど超静か
    • 静かで強力な開発環境がほしいなら(ARMでよければ)アリ

Android StudioとVSCodeの開発効率のメモ

コード生成

  • equals系のオーバーライドで差が出る
    • Android Studioは割と素直にできるし、data classは自動的に行われる
    • VSCode + Dartは標準機能に無いのでExtensionを追加
      • ただし、Classの記述状況によってはExtensionが生成してくれないので自分でどうにかすることがまれによくある
      • VSCode+Dartは基本機能が(ASに比べて)プアなので、Extensionで機能を拡張していく必要がある
        • Projectで必要なExtensionは標準設定としてシェアできるので、誰かがちゃんと整備すれば実用上あまり問題にならない
  • VSCode + Dart Extensionは型の単純なtypedefを認識してくれないので、一部コード補完が効かなくなる

リファクタリング

プロジェクト環境整備

  • VSCode圧勝。JSONで記述できるので、必要なExtensionやTaskを登録しておきやすい
    • Intellijのプロジェクトシェアは結構面倒

IDEの快適さ

  • 基本的にメモリを積んでCPUで叩けば何ら問題ない
  • VSCodeは参照の検索が遅い
  • VSCodeIDEのレイアウトが限られているのが難点
    • Terminalを上に持っていきたいが、できない
    • Intellijは自由にレイアウトできる
  • VSCodeはRemote Developmentが強い
    • なれたWindows母艦からリモートに接続して開発できる
    • WindowsiOSアプリを開発できる気になれる

Flutterアプリ開発環境の長所短所

M1X出ないのかよ!!

Apple発表会で出なかったので、手持ちの環境の再整備を行うことにした

各環境のレビュー

Intel Mac mini 2018 + Windows

  • i7 6C12T / RAM 64GB
  • 従来の開発環境

iOSアプリビルドにはmacが必須なので用意した環境。 WindowsからVSCode Remoteで接続して開発。

  • 利点
    • AndroidiOSもWebも開発できる
    • VMを立ち上げればWindows AppもLinux Appもビルドできるパーフェクト環境
  • 欠点
    • 根本的にi7が遅いのでビルドも遅い。
    • 騒音がひどい。

Intel Mac Book Pro 2020

  • i7 4C8T / RAM 32GB
  • 持ち運び用

リモートワークで自宅内ノマドする機会が増えたので用意した環境。

  • 利点
    • AndroidiOSもWebも開発できる
    • VMを立ち上げればWindows AppもLinux Appもビルドできるパーフェクト環境
  • 欠点
    • 根本的にi7が遅いのでビルドも遅い。
      • Mac miniと比べてもパワー不足。Ryzenとは比べられるレベルじゃない。
    • 騒音がひどい。

Windows

  • Ryzen 3950X 16C32T / RAM 64GB

  • 利点

    • ビルドが早い
    • Macと比べて動作が静か
  • 欠点
    • iOSビルドができない
    • Flutter以外の周辺ツールと日本語環境のかみ合わせが悪い
      • よく文字化けする
    • flutter pub getでmklinkできずにコケる
      • 管理者権限でpub getすれば通るけど気持ち悪い

Ryzen 3950X + Windows / WSL2

  • 利点
    • ビルドが早い
    • Macと比べて動作が静か
  • 欠点
    • iOSビルドができない
    • adb接続にトリッキーなことをしなければならない
    • Android Studioとか開けないのでAndroid Kotlin側のコードをいじるときに不便

Ryzen 3950X + Ubuntu

  • 利点
    • ビルドが早い
    • Macと比べて動作が静か
  • 欠点
    • iOSビルドができない
    • Windows系のツール(Photoshopとか)が使えない
    • ZoomやDiscordが安定して接続できない

最終的に