Оригинальная статья: https://medium.com/dartlang/dart-2-18-f4b3101f146c
С версии Dart 2.18 начинается поддержка возможности взаимодействия с Objective-C и Swift, а также поддержка новых пакетов для iOS/macOS на этой основе.
Dart 2.18 также включает улучшения типизации общих функций, повышение производительности асинхронного кода, поддержку новых функций pub.dev и упорядочивание инструментов и основных библиотек.
Наконец, введены последние изменения состояния миграции null-safety, а также важные обновления дорожной карты по достижению полной null-safety.
В 2020 году мы представили Dart Foreign Function Interface (FFI) для вызова внешних C API, который был выпущен в Dart 2.12 в марте 2021 года.
С момента выхода этого выпуска множество пакетов использовали эту возможность для интеграции с существующими внешними C API, такими как: file_picker
, printing
, win32
, objectbox
, realm
, isar
, tflite_flutter
и dbus
.
Команда Dart стремится обеспечивать возможность взаимодействия со всеми основными языками, используемыми на платформах, где работает Dart, и Dart 2.18 является следующей вехой на пути к этому цели.В версии 2.18 код Dart может вызывать код на Objective-C и Swift, что обычно используется для вызова API на платформах macOS и iOS. Dart поддерживает это взаимодействие в любом приложении, от командной строки до серверного кода и пользовательского интерфейса Flutter.Эта новая механика использует тот факт, что Objective-C и Swift могут предоставлять API через привязку C кода, а Dart API использует генератор ffigen
, чтобы создавать эти привязки из заголовочных файлов API.
macOS имеет API для запроса информации о часовых поясах, открытых через NSTimeZone
. Разработчики могут использовать этот API для получения часового пояса, настроенного пользователем для устройства, и UTC часового смещения.
В этом примере Objective-C использует API часового пояса для получения текущего часового пояса и смещения GMT:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSTimeZone *timezone = [NSTimeZone systemTimeZone]; // Получаем текущий часовой пояс.
NSLog(@"Имя часового пояса: %@", timezone.name);
NSLog(@"Смещение GMT: %ld часов", timezone.secondsFromGMT / 60 / 60);
}
return 0;
}
Здесь импортирован Foundation.h
, который включает заголовочные файлы API библиотеки Apple Foundation.
Далее, в методе main
, он вызывает метод systemTimeZone
класса NSTimeZone
, который возвращает экземпляр NSTimeZone
выбранной временной зоны устройства.
Наконец, приложение выводит два результата в консоль, содержащие имя временной зоны и смещение UTC (в часах).
Если запустить эту программу, она должна вернуть что-то похожее на следующее, в зависимости от местоположения разработчика:``` Имя временной зоны: Europe/Copenhagen Смещение от Гринвича: 2 часа
---
## Пример использования временных зон с Dart
Давайте воспроизведём вышеупомянутый результат с использованием нового Dart и Objective-C.
Сначала создайте новый Dart CLI:
$ dart create timezones
Затем отредактируйте файл `pubspec` для включения конфигурации `ffigen`, которая указывает на заголовочный файл и перечисляет те Objective-C интерфейсы, которые должны генерировать обёртки:
```yaml
ffigen:
name: TimeZoneLibrary
language: objc
output: "foundation_bindings.dart"
exclude-all-by-default: true
objc-interfaces:
include:
- "NSTimeZone"
headers:
entry-points:
- "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSTimeZone.h"
Это выбирает Objective-C bindings для заголовочных файлов NSTimeZone.h
и включает только API интерфейса NSTimeZone
. Чтобы сгенерировать обёртки, можно выполнить команду ffigen
:
$ dart run ffigen
Эта команда создаёт новый файл foundation_bindings.dart
, содержащий множество сгенерированных API bindings. Используя этот файл с привязками, можно написать Dart main
метод, который повторяет Objective-C код:
void main(List<String> args) async {
const dylibPath =
'/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation';
final lib = TimeZoneLibrary(DynamicLibrary.open(dylibPath));
final timeZone = NSTimeZone.getLocalTimeZone(lib);
if (timeZone != null) {
print('Имя временной зоны: ${timeZone.name}');
print('Смещение от Гринвича: ${timeZone.secondsFromGMT ~/ 3600} часов');
}
}
```Таким образом, начиная с Dart 2.18, эта новая поддержка находится в режиме экспериментальной работы, что усиливает возможности Dart для непосредственного вызова API macOS и iOS.И это также дополняет плагины Flutter, предоставляя возможность разработчикам непосредственно вызывать API macOS и iOS из Dart-кода.> Чтобы узнать больше о такой взаимодействии, обратитесь к [руководству по взаимодействию Objective-C и Swift](https://dart.dev/guides/libraries/objective-c-interop).
# Платформенно-зависимые библиотеки HTTP
В Dart входит универсальный многоплатформенный HTTP-библиотека `http`, которая позволяет писать код независимо от платформы, но иногда разработчики хотят использовать специфичные для конкретной native платформы сетевые API, такие как Apple's `NSURLSession`, который позволяет указывать доступ только через Wi-Fi или VPN.
Для поддержки этих сценариев мы создали новый сетевой пакет `cupertino_http` для macOS и iOS, используя возможности прямого взаимодействия с Objective-C, о которых говорилось выше.
## Пример использования библиотеки Cupertino HTTP
Ниже представлен пример того, как конфигурировать HTTP-клиент Flutter для использования `cupertino_http` на iOS и macOS, а также стандартного HTTP-клиента из `dart:io`:
```dart
late Client client;
if (Platform.isIOS || Platform.isMacOS) {
final config = URLSessionConfiguration.ephemeralSessionConfiguration()
..allowsCellularAccess = false
..allowsExpensiveNetworkAccess = false;
client = CupertinoClient.fromSessionConfiguration(config);
} else {
client = Client(); // Использует HTTP-клиент на основе dart:io
}
После начальной конфигурации приложение может выполнять последующие сетевые запросы для данного клиента, например, HTTP GET-запрос теперь выглядит следующим образом:```dart final response = await get( Uri.https( 'www.googleapis.com', '/books/v1/volumes', {'q': 'HTTP', 'maxResults': '40', 'printType': 'books'}, ), );
Когда разработчики не могут использовать универсальные клиентские интерфейсы, они могут напрямую использовать библиотеку `cupertino_http` для вызова сетевых API Apple:
```dart
final session = URLSession.sessionWithConfiguration(URLSessionConfiguration.backgroundSession('com.example.bgdownload'), onFinishedDownloading: (s, t, fileUri) { actualContent = File.fromUri(fileUri).readAsStringSync(); });
final task = session.downloadTaskWithRequest(URLRequest.fromUrl(Uri.https(...))..resume());
Целью при проектировании этой функциональности было сделать приложение доступным для большего количества платформ. Для достижения этой цели мы сохранили универсальные многоплатформенные API для базовых HTTP-операций и позволили настраивать используемые сетевые библиотеки для каждой платформы. package:http
снижает необходимость использования платформенно-зависимого кода до минимума; этот API можно конфигурировать в зависимости от платформы, но использовать его можно независимо от платформы.
Dart 2.18 предоставляет экспериментальную поддержку двух платформенно-зависимых библиотек HTTP для package:http
:
cupertino_http
, основанной на NSURLSession
для macOS/iOS;cronet_http
, основанной на Cronet — популярной сетевой библиотеке для Android.Объединение универсального клиентского API с несколькими реализациями HTTP позволяет получить поведение, специфичное для платформы, при этом все ещё поддерживая приложение из одного набора общих источников со всех платформ.Dart использует множество универсальных функций, таких как метод fold
, который сводит коллекцию элементов к одному значению, например, вычисление суммы списка целых чисел:
List<int> numbers = [1, 2, 3];
final sum = numbers.fold(0, (x, y) => x + y);
print('Сумма $numbers равна $sum');
Для Dart 2.17 или более ранних версий этот метод вызывает ошибку типа:
строка 2 • Оператор '+' не может быть применён условно, так как получатель может быть 'null'.
Dart 2.18 улучшил типизацию, и теперь пример выше проходит статическую проверку, позволяя заключить, что x и y являются непустыми целыми числами. Это изменение позволяет разработчикам писать более компактный код на Dart, сохранив при этом полную надёжность строгой типизации.
Эта версия Dart улучшает способ работы Dart VM с методами async
и функциями генераторов async*/sync*
.
Это уменьшает размер кода; в двух крупных внутренних приложениях Google мы заметили уменьшение размера AOT-снимков примерно на 10%, а также улучшение производительности микробенчмарков.> Эти изменения включают небольшие поведенческие изменения; для получения дополнительной информации обратитеся к логу изменений.
В рамках версии 2.18 мы внедрили две важные доработки в хранилище пакетов pub.dev
.
Поддержка хобби или личных проектов через pub.dev
может потребовать временного вклада, чтобы продвигать это. Чтобы помочь спонсированию, мы добавили новый funding
тег, который публикаторы могут использовать для указания ссылок на способы спонсирования пакета. Эти ссылки затем отображаются в боковой панели на pub.dev
. Для получения более подробной информации обратитесь к документации по pubspec
.
Кроме того, мы стремимся поощрять богатую экосистему открытого программного обеспечения, и чтобы подчеркнуть это, автоматическая система оценки пакетов в pub.dev
дополнительно присваивает 10 баллов за использование лицензий, одобренных OSI.
Dart придает большое значение простоте и легкости обучения, поэтому при добавлении новых возможностей мы всегда стараемся поддерживать осторожный баланс.
Один способ поддержания простоты — удаление исторических функций и API. Dart 2.18 провёл очистку в этой категории, включая некоторые значительные изменения:- Мы добавили унифицированный dart
CLI-инструмент для разработчиков еще в октябре 2020 года; в версии 2.18 завершена миграция. В этом выпуске были удалены последние два отмеченных как устаревшие инструмента: dart2js
(используйте dart compile js
) и dartanalyzer
(используйте dart analyze
).
pub
сгенерировал новый файл конфигурации: .dart_tool/package_config.json
. Предыдущий файл .packages
использовал формат, который не мог содержать версию, а теперь мы прекратили его использование. Если у вас есть файл .packages
, вы можете удалить его.Object
в миксинах (значительное изменение #48167).uri
в классе RedirectException
из модуля dart:io
стал nullable (значительное изменение #49045).dart:io
, были удалены (значительное изменение #34218; ранее они были помечены как устаревшие). Теперь рекомендовано использовать соответствующие константы в нижнем регистре camelCase.echoMode
) и режима строки (lineMode
) в классе Stdin
теперь отвечает за восстановление этих настроек при выходе программы (значительное изменение #45630).---С момента выпуска тестовой версии в ноябре 2020 года и официальной версии Dart 2.12 в марте 2021 года мы рады видеть широкое применение null safety.
Большинство популярных пакетов уже перешли на null safety на pub.dev
; анализ показывает, что все первые 250 самых используемых пакетов поддерживают null safety, а также 98% из первых 1000 пакетов. Во-первых, большинство разработчиков приложений работают с кодовой базой, которая имеет полностью пустую безопасность миграции, что является критически важным условием; до того как все код и зависимости (включая транзитивные) будут перемещены, полная безопасность отсутствия значений в Dart не будет действовать.
Нижеприведённая диаграмма показывает сравнение flutter run
перед внедрением безопасной работы с отсутствием значений и после него, когда приложение начинает переход к полной безопасности отсутствия значений, разработчики выполняют частичную миграцию, но некоторые части остаются неперемещёнными относительно полной безопасности отсутствия значений.С течением времени можно заметить, что использование полной безопасности отсутствия значений увеличивается здоровым образом. К концу прошлого месяца количество приложений, использующих полную безопасность отсутствия значений, превышало количество приложений, не использующих её, в четыре раза; поэтому мы надеемся, что в течение следующих нескольких кварталов мы будем видеть 100% использования надёжной полной безопасности отсутствия значений.
Поддержка одновременно полной безопасности отсутствия значений и её отсутствия увеличивает затраты и сложность.
Во-первых, разработчики Dart должны обучиться и понять эти два подхода, проверяя каждый раз, читающий Dart-код, версию языка, чтобы узнать, являются ли типы по умолчанию непустыми (Dart 2.12 и выше) или пустыми (Dart 2.11 и ниже).
Во-вторых, поддержка этих двух подходов нашим компилятором и временем выполнения замедляет развитие Dart SDK для поддержки новых возможностей.
Основываясь на затратах, связанных с отсутствием полной безопасности отсутствия значений, и очень активном использовании, которое было упомянуто в предыдущем разделе, наша цель — перейти к поддержке только надёжной полной безопасности отсутствия значений и прекратить поддержку отсутствия полной безопасности отсутствия значений и несовершенной полной безопасности отсутствия значений. Мы временно планируем это сделать к середине 2023 года.
Это означает прекращение поддержки Dart 2.11 и более ранних версий, файлы pubspec с ограничением SDK меньше 2.12 больше не будут распознаваться в Dart 3 и выше.
В исходном коде, содержащем метки языка, если они установлены меньше 2.12 (например,
// @dart=2.9
), также будут считаться ошибочными.Если вы уже перешли на надёжную полную безопасность отсутствия значений, ваш код будет работать со всей безопасностью отсутствия значений в Dart 3; если нет, немедленно начните миграцию!
Для получения более подробной информации об этих изменениях обратитесь к этому вопросу на GitHub.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )