FlutterでOS判定をする際、多くの記事で Platform.isIOS
Platform.isAndroid
を用いて解説されていますが、これは誤りを含んでいるように思います。
ThemeData#platform のドキュメントにはこう書かれています。
Widgets from the material library should use this getter (via Theme.of) to determine the current platform for the purpose of emulating the platform behavior (e.g. scrolling or haptic effects). (中略) The dart.io.Platform object should only be used directly when it's critical to actually know the current platform, without any overrides possible (for example, when a system API is about to be called).
(訳) マテリアルライブラリのウィジェットは、プラットフォームの挙動(スクロールや触覚効果など)をエミュレートする目的で現在のプラットフォームを決定するのにTheme.ofを介してこのゲッター(訳注:
platform
のこと)を使用すべきです。(中略) dart:io.Platformオブジェクトは現在のプラットフォームを実際に知ることが重要で、上書きができない場合(例えばシステムAPIを呼び出そうとしている場合)にのみ直接使用すべきです。
つまり、Widgetの見た目を出し分ける目的では Platform.is*
は使用するのは好ましくないということです。
このように書かれているのは、Flutterには見た目を上書きできる機能がありますが、OSの挙動にまつわる処理まで変更されてしまうことがないように dart:io.Platform
の値は変わることがないからです。
代わりにWidgetでは、 Theme.of(context).platform
で比較をすべきです。
Theme.of(context).platform == TargetPlatform.android
Theme.of(context).platform == TargetPlatform.iOS
こうすることにより、例えばAndroidの実機やエミュレータでデバッグしている状況でiOSのウィジェットの挙動も見たいときに、themeに1行追加するだけで確認できます。
MaterialApp(
theme: ThemeData(
platform: TargetPlatform.iOS,
...
),
...
)
(ちなみにDart DevToolsにPlatformをオーバーライドする機能もありますが、私の環境では動きませんでした)
もちろんシステムAPIを呼び出す部分はAndroidのままのため、実際に動くかiOS端末で確認する必要はありますが、iOSのビルドは比較的遅いため、ウィジェットの見た目のチェックでは役に立つかと思います。