Сравнение простых старых переменных Dart, JSON, YAML и окружения
К настоящему времени вы привыкли настраивать параметры конфигурации в pubspec.yaml, но что, если вы хотите определить свои собственные значения конфигурации и прочитать их в своем приложении? Как ты это делаешь? В этой статье я дам вам обзор некоторых вариантов.
Обычный старый дротик
Одно из простых решений - использовать простой старый класс Dart. Создайте файл с именем my_config.dart и добавьте следующий код:
class MyConfig { static const String country = 'Mongolia'; static const String animal = 'horse'; }
Затем вы можете использовать его в любом месте своего кода, импортировав этот файл:
import 'my_config.dart'; void main() { print(MyConfig.country); print(MyConfig.animal); }
Использование библиотеки, а не класса
На самом деле нет необходимости использовать имя класса, например MyConfig
, когда все, что он содержит, - это статические члены. Замените my_config.dart следующим упрощенным кодом:
const String country = 'Mongolia'; const String animal = 'horse';
Вы по-прежнему можете использовать эти значения в любом месте вашего приложения, но теперь вы также можете дать им любое пространство имен и показать или скрыть их по своему усмотрению:
import 'my_config.dart' as config show country; void main() { print(config.country); }
Пространство имен - config
, и вы показываете только переменную country
, поэтому animal
не будет доступен. Это полезно для предотвращения конфликтов имен, когда в вашем проекте есть другие переменные или библиотеки.
Не рассказывай свои секреты
Прежде чем перейти к другим параметрам, я хочу напомнить вам, что нужно быть осторожным с любыми личными данными, которые могут быть в вашем файле конфигурации. Вы не хотите случайно поделиться этим со всем миром, отправив файл в репозиторий Git. Чтобы этого не произошло, вам следует добавить файл конфигурации в .gitignore.
Откройте .gitignore и добавьте имя файла конфигурации в новую строку:
# Configuration my_config.dart
Конечно, теперь, когда кто-то клонирует ваш проект из репозитория Git, он не будет компилироваться, пока они не добавят отсутствующий файл конфигурации.
JSON
Если вы предпочитаете текстовый файл для конфигурации, использование JSON - простой вариант.
Чтение файла JSON в Dart
Создайте файл с именем my_config.json в корне вашего проекта Dart и добавьте следующее содержимое:
{ "country": "Mongolia", "animal": "horse" }
Теперь вы можете прочитать это в своем приложении так:
import 'dart:convert'; import 'dart:io'; Future<void> main() async { final configFile = File('my_config.json'); final jsonString = await configFile.readAsString(); final dynamic jsonMap = jsonDecode(jsonString); print(jsonMap['country']); print(jsonMap['animal']); }
Здесь вам нужно сделать три вещи:
- Получите файл, указав путь. Для этого требуется библиотека
dart:io
. - Извлеките текстовое содержимое файла с помощью
readAsString
. - Преобразуйте строку JSON в карту Dart с
jsonDecode
, которая поступает из библиотекиdart:convert
.
Не забудьте добавить my_config.json
в .gitignore, если в вашем файле конфигурации есть конфиденциальная информация.
Примечание. Если вам сложно скопировать файл конфигурации при развертывании приложения в новое место, а не добавлять его в .gitignore, вы можете просто использовать безопасные значения по умолчанию, а затем отредактировать файл после перемещения проекта на рабочий сервер. Спасибо этой статье за идею.
Чтение файла JSON во Flutter
Если у вас есть текстовый файл конфигурации, к которому вы хотите получить доступ во время выполнения во Flutter, вам необходимо поместить его в пакет ресурсов вашего приложения.
Создайте папку с именем assets в корне вашего проекта Flutter и добавьте в нее my_config.json (все еще с тем же содержимым JSON, которое вы использовали в примере с Dart).
Затем объявите этот файл в pubspec.yaml следующим образом:
flutter: assets: - assets/my_config.json
Теперь вы можете получить к нему доступ и прочитать его во Flutter, используя rootBundle
или DefaultAssetBundle.of(context)
. (Последний вариант рекомендуется, поскольку его можно настроить на уровне виджета).
import 'dart:convert'; import 'package:flutter/material.dart'; Future<void> loadAsset(BuildContext context) async { final jsonString = await DefaultAssetBundle.of(context) .loadString('assets/my_config.json'); final dynamic jsonMap = jsonDecode(jsonString); print(jsonMap['country']); print(jsonMap['animal']); }
Метод loadString
получает текст из файла. После этого он такой же, как Дарт.
YAML
Формат YAML - еще один распространенный формат файлов конфигурации. Его немного проще редактировать вручную, чем JSON. Это также формат, который Dart использует для своих собственных файлов конфигурации.
Чтение файла YAML в Dart
Создайте файл с именем my_config.yaml в корне вашего проекта Dart и добавьте следующее содержимое:
country: Mongolia animal: horse
Для чтения файлов YAML у команды Dart есть пакет под названием yaml, который вы можете использовать. Добавьте его в свои зависимости pubspec.yaml:
dependencies: yaml: ^3.1.0
Затем вы можете использовать его для анализа файла YAML следующим образом:
import 'dart:io'; import 'package:yaml/yaml.dart'; Future<void> main() async { final configFile = File('my_config.yaml'); final yamlString = await configFile.readAsString(); final dynamic yamlMap = loadYaml(yamlString); print(yamlMap['country']); print(yamlMap['animal']); }
Вам все еще нужно было получить строку из текстового файла, как вы это делали раньше с JSON, но как только вы ее получите, вы можете преобразовать ее в карту с помощью loadYaml
. Следует отметить, что эта карта относится к типу YamlMap
, который включает некоторые отличия от Dart Map
. Вы можете просмотреть документацию по исходному коду для получения дополнительной информации об этом.
Не забудьте добавить my_config.yaml
в .gitignore, если в вашем файле конфигурации есть конфиденциальная информация.
Чтение файла YAML во Flutter
Если вы читали статью до этого момента, то здесь нет ничего нового. Добавьте my_config.yaml к своим ресурсам и объявите его в pubspec.yaml:
dependencies: yaml: ^3.1.0 flutter: assets: - assets/my_config.yaml
Затем прочтите это во Flutter вот так:
import 'package:flutter/material.dart'; import 'package:yaml/yaml.dart'; Future<void> loadAsset(BuildContext context) async { final yamlString = await DefaultAssetBundle.of(context) .loadString('assets/my_config.yaml'); final dynamic yamlMap = loadYaml(yamlString); print(yamlMap['country']); print(yamlMap['animal']); }
Но я хочу прочитать сам pubspec.yaml!
Если вы работаете в простом проекте Dart, это довольно просто. Опять же, используя пакет yaml, вы можете сделать это так:
import 'dart:io'; import 'package:yaml/yaml.dart'; Future<void> main() async { final configFile = File('pubspec.yaml'); final yamlString = await configFile.readAsString(); final dynamic yamlMap = loadYaml(yamlString); print(yamlMap['name']); print(yamlMap['description']); print(yamlMap['version']); }
Однако в проекте Flutter pubspec.yaml не входит в набор ресурсов (насколько мне известно), поэтому вы не можете получить к нему прямой доступ. Вопрос в том, зачем вам к нему доступ? Если вы хотите знать такие вещи, как название версии или номер сборки, вам следует использовать package_info_plus, который является фаворитом Flutter. Вот информация об использовании из документации:
import 'package:package_info_plus/package_info_plus.dart'; PackageInfo packageInfo = await PackageInfo.fromPlatform(); String appName = packageInfo.appName; String packageName = packageInfo.packageName; String version = packageInfo.version; String buildNumber = packageInfo.buildNumber;
Переменные среды
Вместо того, чтобы возиться с чтением и анализом файлов конфигурации, другой вариант - использовать переменные среды. Это переменные, которые вы передаете в качестве параметров командной строки при запуске приложения.
Использование переменных окружения в Dart
Замените main.dart следующим кодом:
void main() { const country = String.fromEnvironment('country'); const animal = String.fromEnvironment('animal'); print(country); print(animal); }
Метод fromEnvironment
получает свое значение из аргумента командной строки, который вы передадите при запуске приложения.
Теперь запустите приложение из командной строки следующим образом:
dart run --define=country=Mongolia --define=animal=horse
Параметр --define
позволяет вам установить пару "ключ-значение" для переменной среды. Ключ является первым, а значение вторым, причем все элементы разделяются символом =
равно. Для двух пар ключ-значение просто дважды используйте --define
.
Консоль отладки должна показать ожидаемые результаты:
Mongolia horse
Вы даже можете следовать тому же шаблону, который мы использовали в разделе «Обычный старый дротик» выше, и создать файл my_config.dart со следующим содержанием:
const country = String.fromEnvironment('country'); const animal = String.fromEnvironment('animal');
fromEnvironment
также принимает значение по умолчанию (которое вы можете использовать, например, во время разработки):
String.fromEnvironment('country', defaultValue: 'unknown')
Использование переменных окружения во Flutter
Во Flutter все то же, что и в Dart, за исключением того, как вы устанавливаете переменные в командной строке:
flutter run --dart-define=country=Mongolia --dart-define=animal=horse
На этот раз вы используете --dart-define
вместо --define
.
Преимущество использования переменных среды заключается в том, что у вас нет файла конфигурации, который нужно добавить в .gitignore, а затем скопировать для нового проекта.
Обновлять
Flutter Intellij Plugin, по-видимому, теперь поддерживает добавление переменных среды в IDE. Вероятно, это касается пользователей Android Studio. Я еще не использовал эту функцию. Оставьте комментарий, если есть.
Вывод
В этой статье рассказывалось только о том, как получить доступ к значениям конфигурации из кода Dart самого приложения. Если вам нужно что-то вроде сборки разновидностей для приложения Flutter, вам также придется выполнить дополнительную настройку для конкретной платформы. Вы можете узнать больше о том, как это сделать, в списке статей, включенных в документацию Flutter:
Оставьте комментарий ниже о том, какой метод вы предпочитаете для установки значений конфигурации или о вещах, на которые следует обратить внимание.