有没有办法让 CoreML 模型在源代码级别可用于 iOS11+

Is there a way to make CoreML model available for iOS11+ at source level

我的应用程序中有一个 CoreML 模型。

在 运行 时,预测功能应在 iOS8-10 禁用并在 iOS11 启用。

为了能够编译,在所有使用 CoreML 的 类 上,我添加了:

@available(iOS 11.0, *)

但是 .mlmodel 会在每次重建时生成 Swift 代码并丢弃所有注释。因此会产生像 :

这样的编译错误

'MLModel' is only available on iOS 11.0 or newer

在 Xcode9 中是否有办法使 mlmodel 仅 iOS11?

编辑:此错误已在 XCode 9 beta 4 中修复。不再需要解决方法。

更新。 2017 年 7 月 25 日: Apple 刚刚引入 new API 用于在设备上编译模型。这意味着,您现在可以避免步骤 1-4。

  1. (可选)切换到 Xcode 测试版 sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer
  2. 编译您的模型:xcrun coremlcompiler compile /path/to/MyModel.mlmodel /path/to/output/folder
  3. 将已编译的模型文件夹 MyModel.mlmodelc 放入您的应用程序包中。
  4. 将自动生成的 swift 模型 class (MyModel.swift) 手动添加到您的项目中,并使用 @available(iOS 11.0, *) 对其进行注释。
  5. 加载并初始化您的模型:

    let path = Bundle.main.path(forResource: "MyModel", ofType: "mlmodelc")

    let url = URL(fileURLWithPath: 路径!)

    让模型=试试! MyModel(contentsOf: url)

警告:我还没有尝试将此类应用程序上传到 AppStore。 我已经在我的测试设备上试过了,它可以工作,我只是不确定它在发布到 Appstore 后是否继续工作。

这听起来像是一个错误 — 生成的 Swift 代码应该像您的代码一样包含 @available 注释,以便您的应用程序编译,可以在 运行 中调用它 iOS 11,并且要求在旧 iOS 版本中 运行 时不要调用它。

我强烈推荐 filing that bug with Apple 这样他们就可以在 Xcode 9 GM 之前修复它。

同时,您可以为您的模型禁用代码生成。在您的代码项目设置中,在目标的构建设置下,查找“CoreML 代码生成语言”并将其更改为“None”。

当然,这会阻止您在项目中使用生成的 Swift class。这给您留下了两个选择:

  1. 直接使用 Core Ml API 来评估您的模型。 (也就是说,MLModel(contentsOf: url) 而不是 MyModelClass(),等等)方便的是,生成的 Swift class 您已经看到但没有使用,向您显示了所有 API 个您需要的电话。

  2. 生成一次Swift class(仅编译iOS 11),然后从那里复制代码并将其粘贴到常规源文件中.粘贴后,您可以添加所需的 @available 声明,以便将您的最低部署目标更改为 iOS 10 或更早。

在这两种情况下,如果您更改模型,则可能需要重做一些工作。