本文介绍: Dart 2.18 版本开始提供与 Objective-C 和 Swift 交互的能力预览,以及在这基础上构建的新 iOS / macOS 包支持

原文链接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 的重要路线更新

[外链图片转存失败,源站可能有防盗链机制,建议图片保存下来直接上传(img-zZ4FmMz5-1661916139420)(http://img.cdn.guoshuyu.cn/20220831_# Dart/image1.png)]

Dart 支持与 Objective-C 和 Swift 交互的能力

在 2020 年的时候我们预览用于调用原生 C API 的 Dart函数接口(FFI),并于 2021 年 3 月在 Dart 2.12 中发布了它。

自该版本发布以来,大量软件包利用功能与现有的原生C API集成例如file_pickerprintingwin32objectboxrealmisartflite_flutter dbus 等。

Dart 团队希望支持运行平台上所有主要语言交互能力,而 Dart 2.18达到了实现这一目标的下一个里程碑

在 2.18, Dart 代码可以调用 Objective-C 和 Swift 代码,这通常用于调用 macOS 和 iOS 平台上的API,Dart在任何应用中都支持这种互操作机制,从CLI 应用到后端代码和 Flutter UI。

这种新机制其实是利用了 Objective-C 和 Swift 代码可以基于 API 绑定 C 代码公开,Dart API 包装生成工具 ffigen可以从 API 标头创建这些绑定

使用Objective-C的时区示例

macOS 有一个 API 可用于查询 NSTimeZone 上公开的时区信息开发者可以查询该 API 以了解用户为其设备配置时区和 UTC [时区偏移量](https://www.w3.org/International/core/2005/09/timezone.html#:~:text=What is a “zone offset,or “-” from UTC.)。

以下示例中 Objective-C 使用时区 API 获取系统时区和GMT偏移量

#import <Foundation/Foundation.h&gt;

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSTimeZone *timezone = [NSTimeZone systemTimeZone]; // Get current time zone.
        NSLog(@"Timezone name: %@", timezone.name);
        NSLog(@"Timezone offset GMT: %ld hours", timezone.secondsFromGMT/60/60);
    }
    return 0;
}

这里导入Foundation.h,其中包含 Apple Foundation 库的 API headers

接下来,在 main 方法中,它从 NSTimeZone调用systemTimeZone 方法,此方法返回设备上选定时区的 NSTimeZone 实例

最后应用控制台输出两行结果,其中包含时区名称和UTC偏移量(以小时为单位)。

如果运行程序,它应该返回类似于以下内容的东西,具体取决于开发者位置

Timezone name: Europe/Copenhagen
Timezone offset GMT: 2 hours

使用 Dart 的时区示例

我们使用新的 Dart 与 Objective-C 一起重新实现上面的结果

首先创建一个新的 Dart CLI :

$ dart create timezones

然后编辑 pubspec 文件包含 ffigen 配置配置指向头文件并列出了哪些 Objective-C 接口应该生成包装器:

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"

这就为 NSTimeZone.h 中的 headers 选择 Objective-C 绑定,并仅包括NSTimeZone 接口中的API,要生成 wrappers, 可以允行 ffigen

$ dart run ffigen

命令创建一个新文件 foundation_bindings.dart,其中包含一堆生成的API绑定,使用该绑定文件,就可以编写 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: ${timeZone.name}');
    print('Offset from GMT: ${timeZone.secondsFromGMT / 60 / 60} hours');
  }
}

就这样,从 Dart 2.18 开始,这种新的支持在实验状态下可用,该能力增强了Dart 的交互支持,以直接调用 macOS 和 iOS API 支持。

并且这也反向补充了 Flutter 的插件,提供了允许开发者直接从 Dart 代码调用macOS 和 iOS API 的能力。

要了解有关这种互操作性的更多信息,请参阅 Objective-C 和 Swift 交互指南

特定于平台http

Dart 里包括一个通用的多平台http库,该库允许开着编写代码而无需考虑平台细节,但是有时候开发者可能希望编写特定于特定 native 平台的 网络 API的代码,例如苹果网络NSURLSession 允许指定仅限 WiFi 或 VPN的网络

为了支持这些用例我们为 macOS 和 iOS 平台创建了一个新的网络包 cupertino_http,该能力建立在上一节中提到的 Objective-C 直接交互的基础上。

Cupertino http library 示例

以下示例将 Flutter 的 http 客户端设置为在其他平台上使用 cupertino_http库,以及 dart:io 下的 http 库:

late Client client;
if (Platform.isIOS || Platform.isMacOS) {
  final config = URLSessionConfiguration.ephemeralSessionConfiguration()
    ..allowsCellularAccess = false
    ..allowsExpensiveNetworkAccess = false;
  client = CupertinoClient.fromSessionConfiguration(config);
} else {
  client = Client(); // Uses an HTTP client based on dart:io
}

初始配置后,应用会对特定客户端进行后续网络调用例如 http get() 请求现在类似于以下内容

final response = await get(
  Uri.https(
    'www.googleapis.com',
    '/books/v1/volumes',
    {'q': 'HTTP', 'maxResults': '40', 'printType': 'books'},
  ),
);

开发者无法使用通用客户端接口时,就可以直接使用 cupertino_http调用苹果的网络API:

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();

多平台应用程序中特定于平台的网络

设计功能时,目标仍然是使应用尽支持更多的平台,为了实现这个目标,我们基本http 操作保留了通用的多平台 http API 集,并允许为每个平台配置要使用的网络库。

package:http需要编写的特定于平台的代码量降至最低,此 API 可以按平台配置,但以独立于平台的方式使用。

Dart 2.18 提供了对两个对于 package:http 特定于平台的 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(The sum of $numbers is $sum);

对于 Dart 2.17 或更早版本,这个方法返回类型错误

line 2 • The operator ‘+’ can’t be unconditionally invoked because the receiver can be ‘null’.

Dart 2.18 改进了类型推断,前面示例通过静态分析可以推断出 x 和 y 都是不可为空整数,此更改允许开发编写简洁的 Dart 代码,同时保留强推断类型的完整可靠性属性

异步性能改进

此版本的 Dart 改进了 Dart VM 应用 async 方法和 async*/sync* 生成器功能的方式

这减少了代码大小,在两个大型内部 Google 应用程序中,我们看到 AOT 快照大小减少了约 10%,还可以看到基准测试性能有所提高

这些变化包括额外的小行为变化;要了解更多信息,请参阅更改日志

pub.dev 改进

结合 2.18 版本,我们对 pub.dev存储库进行了两项更改。

个人业余时间通过 pub.dev 维护和发布的可能会产生一些时间上的投入,为了促进赞助,我们现在在 中支持一个新 funding 标签pubspec发布者可以使用该标签列出指向一种或多种赞助包的方式链接。然后这些链接显示pub.dev在侧边栏中:

[外链图片转存失败,源站可能有防盗链机制,建议图片保存下来直接上传(img-cycmfXri-1661916139421)(http://img.cdn.guoshuyu.cn/20220831_# Dart/image2.png)]

要了解更多信息,请参阅pubspec文档

此外,我们希望鼓励丰富的开源软件包生态系统,为了突出这一点,自动评分对使用 OSI 批准的许可证pub.dev额外奖励 10 分。

一些重大变化

Dart 非常注重简单和易学的能力,在添加新功能时,我们一直在努力保持谨慎的平衡。

保持简单的一种方法是删除历史功能和 API,Dart 2.18 清理了此类别中的项目,包括一些较小的重大更改:

安全更新

自 2020 年 11 月发布测试版和 2021 年 3 月发布 Dart 2.12 以来,我们很高兴看到 null 安全性的广泛使用。

首先,大多数流行包的开发人员都在 pub.dev 迁移到了零安全性分析表明,100% 的前 250 个和 98% 的前 1000 个最常用的包支持零安全

其次,大多数应用开发人员具有完全空安全迁移的代码库中工作,这是至关重要条件,在迁移所有代码和所有依赖项(包括传递性)之前, Dart 健全的 null safety 不会发挥作用。

下图显示flutter run 在引入零安全没有引起之间的对比,随着应用开始迁移到零安全开发人员进行了部分迁移,但仍存在部分内容迁移到 null safety

随着时间的推移可以看到, null safety 使用在健康地增长。到上月底,与不使用 null safety 相比, null safety 多出四倍,所以我们希望,在接下来的几个季度中,我们将看到 100% 的可靠安全方法。

[外链图片转存失败,源站可能有防盗链机制,建议图片保存下来直接上传(img-0aqUjPTj-1661916139421)(http://img.cdn.guoshuyu.cn/20220831_# Dart/image3.png)]

重要的零安全路线更新

同时支持空安全和非空安全会增加开销和复杂性。

首先,Dart 开发需要学习理解这两种模式,每当阅读一段 Dart 代码时,检查语言版本查看类型是否默认为非空(Dart 2.12 及更高版本)或默认可空(Dart 2.11 及更早版本)。

其次,在我们的编译器运行时同时支持这两种模式会减慢 Dart SDK 的发展以支持新功能。

基于非空安全的开销和上一节中提到的非常积极的采用数字,我们的目标是过渡到仅支持可靠空值安全,并停止非空值安全和不健全的空值安全模式,我们暂时将其定于 2023 年年中发布

这将意味着停止对 Dart 2.11 及更早版本的支持具有低于 2.12 的 SDK 约束的 Pubspec 文件将不再在 Dart 3 及更高版本中解析

在包含语言标记源代码中,如果设置为小于 2.12(例如// @dart=2.9)也会失败

如果已迁移到可靠的 null 安全性,那么你的代码将在 Dart 3 中以完全的 null 安全性工作,如果还没有,请立即迁移!

要了解有关这些更改的更多信息,请参阅此 GitHub 问题

原文地址:https://blog.csdn.net/ZuoYueLiang/article/details/126620444

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24168.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注