有没有办法在源代码级别为iOS11 +提供CoreML模型

时间:2017-07-20 13:11:34

标签: ios coreml

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

在运行时,应在iOS8-10上禁用预测功能,在iOS11上激活预测功能。

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

  

@available(iOS 11.0,*)

但是.mlmodel会在每次重建时生成Swift代码,丢弃所有注释。因此创建编译错误,如:

  

' MLModel'仅适用于iOS 11.0或更高版本

Xcode9中是否有办法只制作mlmodel iOS11?

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

2 个答案:

答案 0 :(得分:5)

<强> UPD。 07/25/17: Apple刚刚推出new API用于在设备上编译模型。这意味着,您现在可以避免步骤1-4。

  1. (可选)切换到Xcode beta 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模型类(MyModel.swift)添加到项目中,并使用@available(iOS 11.0, *)对其进行注释。 How to find model class
  5. 加载并初始化您的模型:

    let path = Bundle.main.path(forResource:&#34; MyModel&#34;,ofType:&#34; mlmodelc&#34;)

    让url = URL(fileURLWithPath:path!)

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

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

答案 1 :(得分:1)

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

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

与此同时,您可以禁用模型的代码生成。在您的代码项目设置中,在目标的Build Settings下,查找“CoreML Code Generation Language”并将其更改为“None”。

但是,这当然会阻止您在项目中使用生成的Swift类。这为您提供了两个选项:

  1. 直接使用Core Ml API评估您的模型。 (也就是说,MLModel(contentsOf: url)而不是MyModelClass()等。)方便的是,您看到但未使用的生成的Swift类会向您展示您需要的所有API调用。

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

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