0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】dart-define-from-fileの環境変数をAppDelegate.swiftで使う

Posted at

環境

Flutter 3.19.6
Dart 3.3.4
M2 mac Sonoma 14.5
xcode Version 15.3

課題

どうしてもアプリ起動時にAppdelegate.swiftにdart-define-from-fileで定義している環境変数を渡したかった。ただし.envとか使った方が圧倒的に楽そうではある。

↓この記事が非常に参考になった。chatGPTが相決してくれなかったことを解決してくれた。AIばっかりに頼っていてはいけないかもしれない。

解決方法

/libディレクトリ内の任意の場所に環境変数の橋渡しをするためのファイルを作る(別にmain.dartに直接書いても構わない)。
MethodChannel()には任意の文字列を渡す。これはAppDelegateでも同じ文字列を使うのでわかりやすい名前をつけるのがいい。
platform.invokeMethod(methodName, arguments)でAppDelegateから関数を呼ぶ。channelと同様methodNameはわかりやすい名前をつける。argumentsに値を渡すことでAppDelegate内でその値を利用することができる。

ただし、MapかListを渡す時はそれぞれinvokeMapMethod()invokeListMethod()と別の関数を使う。

lib/env_bridge.dart
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';

class EnvBridge {
  // AppDelegate.swiftから処理を実行するためのchannelを宣言
  static const platform = MethodChannel('envBridgeChannel');

  // main.dartから呼ぶ
  static Future<void> sendEnvironmentVariableToAppDelegate() async {
    const key =
        String.fromEnvironment('key', defaultValue: 'noSuchKey');

    try {
    // AppDelegateで登録した処理を行う
      await platform.invokeMethod('setEnvironmentVariable', key);
    } catch (e) {
      debugPrint('failed to set googlemaps api: $e');
    }
  }
}

flutterコードか実行するための処理をAppDelegateに登録する。
FlutterMethodChannel()のnameにはEnvBrigdeに書いたものと同じものを書く。
channel.setMethodCallHandler()で任意の処理を登録する。methodCall.argumentsでFlutterで渡された引数を受け取ることができる。ビルド時に怒られるのでas! Stringでキャストする。数値などを渡す時は適宜対応する。

ios/Runner/AppDelegate.swift
import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

+    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
+    let channel = FlutterMethodChannel(
+      name: "envBridgeChannel",
+      binaryMessenger: controller.binaryMessenger
+    )

+    channel.setMethodCallHandler({
+      (methodCall: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
+        if (methodCall.method == "setEnvironmentVariable") {
+            let value = methodCall.arguments as! String
+            // 環境変数を受け取って何かする。
+            print(value)
+        }
+    })

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

main関数からEnvBridgeで定義した関数を呼ぶことで、AppDelegateの処理を実行する。結果としてFlutterから値を渡してSwiftで環境変数を使った処理を実行することができる。

Androidの時に不測の処理をすると困るので一応iosの時だけ実行するようにしておく。

lib/main.dart
+ import 'package:flutter/services.dart';
+ import 'env_bridge.dart';

- void main() {
+ Future<void> main() async {

+    if (Platform.isIOS) {
+        await EnvBridge.sendEnvironmentVariableToAppDelegate();
+    }

    runApp(const MyApp())
}
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?