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

I have a CoreML model in my application.

At runtime, the prediction feature must be disabled on iOS8-10 and active on iOS11.

To compile, on all classes that use CoreML, I added:

@available (iOS 11.0, *)

But .mlmodel generates Swift code on every rebuild, discarding all annotations. And so create compilation errors like:

'MLModel' is only available on iOS 11.0 or newer

Is there a way in Xcode9 to make only mlmodel iOS11?

EDIT : This bug was fixed in XCode 9 beta 4. The workaround is no longer needed.

+3


source to share


2 answers


Upd. 7/27/17: Apple has just implemented a new API to compile models on a device. This means that you can now avoid steps 1-4.

  • (optional) Switch to Xcode beta sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer

    .
  • Compile your model: xcrun coremlcompiler compile /path/to/MyModel.mlmodel /path/to/output/folder

    .
  • Place the compiled model folder MyModel.mlmodelc

    in your app package.
  • Add the auto-generated swift model class ( MyModel.swift

    ) to your project manually and annotate it with @available(iOS 11.0, *)

    . How to find the model class
  • Load and initialize your model:

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

    let url = URL (fileURLWithPath: path!)

    let model = try it! MyModel (contentOf: url)



Warning: I have not tried to download such an application in the AppStore. I tried this on my test device and it works, I'm just not sure if it will continue to work after exiting the Appstore.

+5


source


This sounds like a mistake. The generated Swift code must include annotations @available

just like yours, so your app compiles, can call it while running on iOS 11, and not require it to be called when running on older iOS.

Id highly recommend filing this bug with Apple so they can hopefully fix it before Xcode 9 GM.

In the meantime, you can turn off code generation for your model. In your code project settings under "Build Options for Your Purpose" find "Kernel Code Generation Language" and change it to "None".



This will of course prevent you from using the generated Swift class in your project. This gives you two options:

  • Use the Core Ml API directly to evaluate your model. (That is, MLModel(contentsOf: url)

    instead of MyModelClass()

    , etc.). Conveniently, the generated Swift class you have seen but not used shows you all the API calls you need.

  • Create the Swift class once (compile for iOS 11 only), then copy the code and paste it into your regular source file. Once pasted, you can add the required declarations @available

    to change the minimum deployment target to iOS 10 or earlier.

In both cases, theres work, which you may need to redo if you ever change the model.

+1


source







All Articles