有没有办法让 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。
- (可选)切换到 Xcode 测试版
sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer
。
- 编译您的模型:
xcrun coremlcompiler compile /path/to/MyModel.mlmodel /path/to/output/folder
。
- 将已编译的模型文件夹
MyModel.mlmodelc
放入您的应用程序包中。
- 将自动生成的 swift 模型 class (
MyModel.swift
) 手动添加到您的项目中,并使用 @available(iOS 11.0, *)
对其进行注释。
加载并初始化您的模型:
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。这给您留下了两个选择:
直接使用 Core Ml API 来评估您的模型。 (也就是说,MLModel(contentsOf: url)
而不是 MyModelClass()
,等等)方便的是,生成的 Swift class 您已经看到但没有使用,向您显示了所有 API 个您需要的电话。
生成一次Swift class(仅编译iOS 11),然后从那里复制代码并将其粘贴到常规源文件中.粘贴后,您可以添加所需的 @available
声明,以便将您的最低部署目标更改为 iOS 10 或更早。
在这两种情况下,如果您更改模型,则可能需要重做一些工作。
我的应用程序中有一个 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。
- (可选)切换到 Xcode 测试版
sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer
。 - 编译您的模型:
xcrun coremlcompiler compile /path/to/MyModel.mlmodel /path/to/output/folder
。 - 将已编译的模型文件夹
MyModel.mlmodelc
放入您的应用程序包中。 - 将自动生成的 swift 模型 class (
MyModel.swift
) 手动添加到您的项目中,并使用@available(iOS 11.0, *)
对其进行注释。 加载并初始化您的模型:
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。这给您留下了两个选择:
直接使用 Core Ml API 来评估您的模型。 (也就是说,
MLModel(contentsOf: url)
而不是MyModelClass()
,等等)方便的是,生成的 Swift class 您已经看到但没有使用,向您显示了所有 API 个您需要的电话。生成一次Swift class(仅编译iOS 11),然后从那里复制代码并将其粘贴到常规源文件中.粘贴后,您可以添加所需的
@available
声明,以便将您的最低部署目标更改为 iOS 10 或更早。
在这两种情况下,如果您更改模型,则可能需要重做一些工作。