TGViewer
Flutter Friendly Flutter Friendly @flutterfriendly · 995 subscribers
Post #230 736
➡️Всем привет! Это Роза, Flutter Dev в Friflex

Если вы хоть раз делали приложение и для Web, и для мобильных платформ, то точно сталкивались с конфликтами библиотек dart:io и dart:html (а точнее, уже dart:web) или других платформенно-специфичных пакетов. Вы могли увидеть примерно такое сообщение в консоли:

Failed to build iOS app

Error (Xcode): lib/main.dart:7:8: Error: Dart library 'dart:html' is not available on this platform.


или, например:

Running Gradle task 'assembleDebug'...  
../lib/web_widgets/url_functions_web.dart:19:31: Error: Type 'ui.HashUrlStrategy' not found.  
class UrlPathStrategy extends ui.HashUrlStrategy {  
^^^^^^^^^^^^^^^^^^  
........


И это объяснимо, ведь мы используем пакет, который не поддерживается в мобильном устройстве, все просто и понятно.

Давайте по порядку! 

◾️ dart:io — библиотека для работы с файлами, сокетами и прочим «системным» API. Он поддерживается только на мобильных и desktop устройствах.
◾️ dart:html(dart:web) — библиотека для работы с DOM и Web API. Поддерживается только в браузере.
    
Соответственно, если мы подключаем dart:io в вебе или dart:web на мобильных устройствах, компилятор выдаст ошибку.

Чтобы решить эту проблему, можно:
1. Использовать сторонние кроссплатформенные библиотеки:
Например, cross_file.
Этот пакет предоставляет абстракцию XFile, которая позволяет работать с файлами на всех платформах (Web, Desktop, Mobile).

При помощи cross_file, например, вы можете сделать файловый пикер:

Future<XFile?> showFilePicker({List<String>? extensions}) {
  return FilePicker.platform.pickFiles(
    allowedExtensions: extensions,
    type: extensions?.isNotEmpty ?? false ? FileType.custom : FileType.any,
  ).then((result) {
    return result?.xFiles.firstOrNull;
  });
}


2. Делать условные импорты

Если подходящей библиотеки нет, можно подключать разные реализации под разные платформы. Например, для настройки ClientChannelBase для grpc. Подробнее о grpc можете прочитать здесь.

export 'grpc_stub.dart'
  if (dart.library.io) 'grpc_io.dart'
  if (dart.library.js_interop) 'grpc_web.dart';


При использовании этого файла (импорте его в ваш виджет) Dart сам подставит нужную реализацию в зависимости от платформы:
✔️ если это мобильные или desktop → grpc_io.dart
✔️ если это Web → grpc_web.dart
✔️ а если ни одна из библиотек не доступна →  grpc_stub.dart

grpc_stub.dart (заглушка):

import 'package:grpc/grpc_connection_interface.dart';

ClientChannelBase setupChannel(String url) =>
    throw UnimplementedError();


grpc_io.dart (Mobile/Desktop):

import 'package:grpc/grpc.dart';
import 'package:grpc/grpc_connection_interface.dart';

ClientChannelBase setupChannel(String url) {
  return ClientChannel(
    uri.host,
    port: uri.port,
    options: ChannelOptions(credentials: credentials),
  );
}


grpc_web.dart (Web):

import 'package:grpc/grpc_connection_interface.dart';
import 'package:grpc/grpc_web.dart';

ClientChannelBase setupChannel(String url) {
  return GrpcWebClientChannel.xhr(uri);
}


А в коде используем :

late final ClientChannelBase channel = setupChannel(baseUrl);


Вот и все! Делитесь в комментах вашими лайфхаками при работе с кроссплатформой!
  • 👍 10
  • 🔥 4
  • ❤ 1
More from @flutterfriendly
  1. May 14, 2026👀Какой сложный вопрос или тема по Flutter вас сейчас беспокоят? Может, задача не идет, ба…
  2. Apr 17, 2026💭Привет! Это Роза, Flutter-разработчица Friflex! Уверена, многие из вас знакомы с Dart De…
  3. Apr 8, 2026Привет, друзья! Делимся нашей страничкой на Хабре, чтобы всегда оставаться на связи. Там е…
  4. Apr 3, 2026🌸Апрель в календаре и на экране Весна зовет обновлять визуальное: убирать темные темы и в…
  5. Apr 1, 2026Всегда с нетерпением ждем этого дня, чтобы сделать подборку ИТ-мемов Пусть поводов для улы…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →