I have downloaded the new trained model from python
backend, with this code:
import Foundation
import Alamofire
import AlamofireObjectMapper
import ObjectMapper
import CoreML
class func downloadModel(modelUrl: String) {
let destenation = Support.getDestenationForModel(modelUrl: modelUrl)
AF.download(modelUrl, to: destenation).downloadProgress { progress in
print("Download Progress: \(progress.fractionCompleted)")
}
.response { response in
switch response.result {
case .success(let success):
if let url = success?.absoluteURL {
FTApi.compileNewModel(url: url)
}
break
case .failure(let err):
print(err)
break
}
}
}
where in Support
class the getDestenationForModel
is the following:
class func getDestenationForModel(modelUrl: String) -> DownloadRequest.Destination {
let destenation: DownloadRequest.Destination = { url, options in
guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first ,
let modelUrl = URL(string: modelUrl) else {
preconditionFailure("unable to use documents directory")
}
let fileURL = documentsURL.appendingPathComponent(modelUrl.lastPathComponent)
AppPrefrences.pathOfModel = modelUrl.lastPathComponent
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
return destenation
}
when the download is finished I try to save the model to CoreData
(I didn't find any other way, maybe you could recommend something else) using the following code:
private class func compileNewModel(url: URL) {
do {
let compiledUrl = try MLModel.compileModel(at: url)
guard let model = try? MLModel(contentsOf: compiledUrl)
else {
print("cannot get content of model")
return
}
let coreMlModel = CML(context: PersistanceService.context)
print(type(of: model)) // => MLNeuralNetworkEngine
coreMlModel.model = (model as NSObject)
PersistanceService.saveContext() // here I have an error
} catch {
print("cannot download the model!")
}
}
the error is: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MLNeuralNetworkEngine encodeWithCoder:]: unrecognized selector sent to instance 0x104d38280'
where this is my CoreData
entity class:
import Foundation
import CoreData
extension CML {
@nonobjc public class func fetchRequest() -> NSFetchRequest<CML> {
return NSFetchRequest<CML>(entityName: "CML")
}
@NSManaged public var model: NSObject?
}
I tried to change the type from NSObject
to MLModel
, but the result is the same.
Why would you even try this? It's not the sort of thing CoreData is designed for.
The correct solution is to copy the folder from compiledURL to a location in your app's Application Support folder. Then when you create the MLModel object, use the URL from the Application Support folder.
Read "Downloading and Compiling a Model on the User's Device" in the Core ML documentation to see how to do this.