Help us understand the problem. What is going on with this article?

Flutter debugDefaultTargetPlatformOverrideとは何か?を理解するとデスクトップ対応の状況が見えてくる

はじめに

package:flutter/foundation.dartで提供されるdebugDefaultTargetPlatformOverrideについて解説します。

2020/03/10 追記

Add Linux and Windows target platformsのissueで正式対応されたため、本記事のdebugDefaultTargetPlatformOverrideの対応が不要になります!まだmasterチャンネルのみですが。

用途

用途は主に以下の2つです。

  • 今時点でFlutterのデスクトップ向けのコードを書く場合 (以下のサンプルコード参照)
  • 例えばAndroid端末でiOS仕様の挙動の確認をしたいなど (実機と異なるプラットフォームの動作確認) の場合
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/my_app.dart';

void _setOverrideForDesktop() {
  if (kIsWeb) return;

  if (Platform.isMacOS) {
    debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
  } else if (Platform.isLinux || Platform.isWindows) {
    debugDefaultTargetPlatformOverride = TargetPlatform.android; // ← Linux/Windowsデスクトップ向けはこれが必要!
  } else if (Platform.isFuchsia) {
    debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
  }
}

void main() {
  _setOverrideForDesktop();
  runApp(MyMaterialApp());
}

debugDefaultTargetPlatformOverrideとは何?

debugDefaultTargetPlatformOverrideは本来ターゲットとするプラットフォームから強制的に別のプラットフォーム向けの挙動に変えるためのデバッグ専用のプロパティです。

debugDefaultTargetPlatformOverrideはデフォルトnullで、この場合はアプリがターゲットのプラットフォーム向けの挙動になります。一方、上記のように何らかの値が設定されている場合には、強制的に指定されたプラットフォームの挙動をするようになります。

デスクトップ for Linux/Windows向けの現状

foundation/_platform_io.dartのソースコードを見てみると、WindowsやLinuxの正式対応がまだされておらず、debugDefaultTargetPlatformOverrideを使って何かのプラットフォームを指定しないとダメなことがわかります。

flutter/packages/flutter/lib/src/foundation/_platform_io.dart
import 'dart:io';
import 'assertions.dart';
import 'platform.dart' as platform;

/// The dart:io implementation of [platform.defaultTargetPlatform].
platform.TargetPlatform get defaultTargetPlatform {
  platform.TargetPlatform result;
  if (Platform.isIOS) {
    result = platform.TargetPlatform.iOS;
  } else if (Platform.isMacOS) {
    result = platform.TargetPlatform.macOS;
  } else if (Platform.isAndroid) {
    result = platform.TargetPlatform.android;
  } else if (Platform.isFuchsia) {
    result = platform.TargetPlatform.fuchsia;
  }
  assert(() {
    if (Platform.environment.containsKey('FLUTTER_TEST'))
      result = platform.TargetPlatform.android;
    return true;
  }());
  if (platform.debugDefaultTargetPlatformOverride != null)
    result = platform.debugDefaultTargetPlatformOverride;
  if (result == null) {
    throw FlutterError(
      'Unknown platform.\n'
      '${Platform.operatingSystem} was not recognized as a target platform. '
      'Consider updating the list of TargetPlatforms to include this platform.'
    );
  }
  return result;
}

プラットフォーム毎に何が違う?

では、プラットフォーム毎に何が違うのでしょうか?
それを解決するためには、defaultTargetPlatformをFlutter Frameworkのソースコードで grep してみると分かります。

一番分かりやすいのは、CupertinoSwitchです。
ソースコードのflutter/packages/flutter/lib/src/cupertino/switch.dartを見てみます。

iOSだけHapticFeedback.lightImpact()をコールしています。

flutter/packages/flutter/lib/src/cupertino/switch.dart
  void _emitVibration() {
    switch (defaultTargetPlatform) {
      case TargetPlatform.iOS:
        HapticFeedback.lightImpact();
        break;
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.macOS:
        break;
    }
  }

HapticFeedback.lightImpact()を追いかけてみると、SystemChannels APIを利用してプラットフォーム側のバイブレーション機能を呼び出しています。

結局この場合はハードウェアの実物がないと特に差分無しという感じになりますね。

なお、SystemCHannels APIんついては、Flutter プラットフォーム固有機能を利用するためのSystemChannels APIについてにまとめていますので参考にして下さい。

flutter/packages/flutter/lib/src/services/haptic_feedback.dar

flutter/packages/flutter/lib/src/services/haptic_feedback.dar
  /// Provides a haptic feedback corresponding a collision impact with a light mass.
  ///
  /// On iOS versions 10 and above, this uses a `UIImpactFeedbackGenerator` with
  /// `UIImpactFeedbackStyleLight`. This call has no effects on iOS versions
  /// below 10.
  ///
  /// On Android, this uses `HapticFeedbackConstants.VIRTUAL_KEY`.
  static Future<void> lightImpact() async {
    await SystemChannels.platform.invokeMethod<void>(
      'HapticFeedback.vibrate',
      'HapticFeedbackType.lightImpact',
    );
  }
kurun_pan
記事の内容以外についての、ご意見・連絡等はTwitterの方へお願いします!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした