LoginSignup
5
0

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-02-19

はじめに

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',
    );
  }
5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0